最近发现手机部分 APP 加载时一直转圈打不开,还有一部分收不到推送通知,排查后定位到 Google FCM 连接失败,在此记录一下整个排查过程。
获取连接状态信息
拨号 *#*#426#*#* 可以查看 FCM 的连接域名、端口以及连接状态等信息。
通过 ADB 排查
为方便操作,通过 ADB 连接手机来敲命令(直接在手机上输入实在太费劲)。注意需要给 adbd 或 com.android.shell 授予 root 权限。
# 首先排查 DNS 解析
nslookup mtalk.google.com
# 排查网络连通性
ping mtalk.google.com
# 排查端口连通性
telnet mtalk.google.com 5228
DNS、网络、端口三项检测均无异常,这就很奇怪了,于是决定抓包看看。
tcpdump -i any host mtalk.google.com and port 5228
抓包后发现没有任何出站流量,进一步检查防火墙规则:
iptables -vnL
ip6tables -vnL
输出中注意到一条名为 zte_fw_gms 的链,内容如下:
Chain zte_fw_gms (1 references)
pkts bytes target prot opt in out source destination
0 0 ACCEPT all -- * * 0.0.0.0/0 0.0.0.0/0 STRING match "services.googleapis.cn" ALGO name bm
0 0 DROP all -- * * 0.0.0.0/0 0.0.0.0/0 owner UID match 10343
0 0 DROP all -- * * 0.0.0.0/0 0.0.0.0/0 owner UID match 10249
0 0 DROP all -- * * 0.0.0.0/0 0.0.0.0/0 owner UID match 99910343
这条链看起来很可疑。
iptables -Z # 清空计数器,重新观察
iptables -L zte_fw_gms -n --line-numbers -v # 再次查看,发现 UID 10343 的计数在上涨
iptables -R zte_fw_gms 2 -m owner --uid-owner 10343 -j ACCEPT # 将 DROP 改为 ACCEPT,FCM 状态随即变为 connected
netstat -antulp | grep 5228 # TCP 连接已建立 ESTABLISHED
dumpsys package | grep 10343 # 查看对应包名,确认无误
至此问题定位完成:FCM 服务被防火墙规则阻断,导致依赖 GMS 的应用无法正常接收推送。
其实直接执行 iptables -F 也能临时解决,但这种方式并不安全。需要注意的是,手机重启后防火墙规则会恢复,需要重新修改或清理。理论上可以通过 KernelSU 的模块机制实现开机自动清理。
写了一个小模块
其实可以通过 Web UI 对规则进行持久化管理,做成一个 iptables 管理模块,支持增删改查以及备份还原。不过考虑到网卡名、IP 变化等因素可能导致规则还原失败,目前还没有太好的思路,只能采用简单粗暴的方式做规则清理。
原创
Google FCM 连接失败排查
本文采用 CC BY-NC-SA 4.0 许可协议,转载请注明出处。
赞赏支持
如果觉得文章对你有帮助,可以请作者喝杯咖啡 ☕
评论交流
欢迎留下你的想法