V2Ray 免翻接收谷歌 FCM 推送

作者 Known Rabbit 日期 2017-12-07
V2Ray 免翻接收谷歌 FCM 推送

从维修点回来的一加,脸上布满着岁月的痕迹,身体也一天不如一天了。打开电池使用情况,耗电大家除了手机屏幕谷歌服务就是想删又不能删的超级费电宇宙无敌旋转爆炸垃圾手机QQ。

绿色守护过来!给我拖出去!

好了。现在问题来了。怎么收消息呢?

我们都知道第三方 QQ 推送有两种方案,一个是据说支持Nougat通知特性、利用谷歌 Firebase 推送消息的 FCM-For-Mojo ,还有一个就是用老版 GCM 但是同时支持华为、小米等国产推送 SDK 的 GcmForMojo (这项目连个README都没有?!)

纠结了一秒作为颜控当然选界面好看的啦

那么问题又来了。我总不能上个Q还要成天到晚挂梯子吧?——我要把这个解决了的话,还有一个好处,其他使用 FCM Push 的软件可以一同受益,Qng内生活就会很轻松了。

网上教程传统的思路都会告诉你,装个haproxy呀,装个nginx呀,你得有个国外VPS呀,巴拉巴拉巴……不过为了个QQ没必要搞这么多幺蛾子,而且好线路的VPS是真的贵。鉴于我的机器都是国内的且有备案,使用成本反而更低。所以在国内架一个 MojoQQ 服务,并让他同时作为 FCM 服务端与安卓 FCM 客户端的反向代理,大概是最好的选择了。

方案概述

不久前无意听说了一个小众爱国软件V2Ray,因为自己有梯子就一直没有用,配置太复杂。细细看了一眼文档,对inbound和outbound配置的解耦给予了它很大的灵活性,而且可以接入ss作为出站端,简直不能更合适。

为什么呢?SS的服务端程序据传已经被各大主机商识别并禁止了。而且最重要的是,我只想在服务器上运行一个binary来完成——反代、路由、走SS出国。mojo自己就要一大票依赖,不想更麻烦了,运维的东西我要搞吐了。

因此采用V2Ray以后的方案简化为:

  • 一键安装V2Ray
  • 配置文件粘上去
  • 写一行hosts
  • 一键安装FCM-For-Mojo服务端
  • 手机上装好客户端
  • 手机上写一行hosts

这就很简单了嘛。

一顿抓包中间人查文档以后,大概确定了打通FCM需要连接的主机。

通讯端点

我又不会写demo,所以我在Play商店找了一个测试App。我们可以看到它的套路大概是:

  • 通过 android.clients.google.com 向FCM服务注册本客户端
  • 测试向 pushnotificationtester.appspot.com (即应用后端)的连接,请求服务通过FCM推送消息
    • 这个服务器地址当然随应用不同而变化啦
    • 这里被坑了很久我才意识到……appspot也被墙了……
  • 在此过程中,Play Services 通过向 mtalk.google.com 或者 alt[1-8]-mtalk.google.com 发起长连接以 XMPP 协议持续接受推送消息。
  • 应用后端将请求发送到 fcm.googleapis.com 通过 FCM[1] 推送消息。

服务器配置

V2Ray

首先下载v2ray。可以在release下载也可以用官方的linux一键安装脚本。

bash <(curl -L -s https://install.direct/go.sh)

然后修改配置文件 /etc/v2ray/config.json 如下。Mac系统强烈推荐 Jayson !JSON 编辑神器!

{
"log":
{
"access": "/var/log/v2ray/access.log",
"error": "/var/log/v2ray/error.log",
"loglevel": "debug"
},
"inbound":
{
"port": 443,
"protocol": "dokodemo-door",
"settings":
{
"address": "android.l.google.com",
"network": "tcp",
"port": 443
}
},
"inboundDetour":
[
{
"protocol": "dokodemo-door",
"tag": "xmpp",
"port": "5228",
"settings":
{
"address": "mobile-gtalk.l.google.com",
"network": "tcp",
"port": 5228
}
}
],
"outbound":
{
"protocol": "shadowsocks",
"settings":
{
"servers":
[
{
"address": "SS_ADDR",
"port": SS_PORT_INT,
"method": "SS_ENC_METHOD",
"password": "SS_PWD"
}
]
}
}
}

配置文件本身已经把自己解释的很明白了。至于完整的参数和高级功能,包括访问控制、转发规则、透明代理等等,参考官方文档[2]自行发掘咯。

入站协议 dokodemo-door “任意门”协议既可以做端口转发(也就是反向代理)也可以改改参数做成类似 ss-redir 的透明代理。在这里转发的地址只要是个谷歌的IP就可以,毕竟谷歌自带负载均衡的,只要 Host 是对的就会连到正确的服务器上。但这也是 v2ray 的局限性。在443端口上做更复杂的转发就需要SNIProxy了。

inboundDetour 里的 5228 端口就是客户端推送用的端口了。这里的 443 端口和 5228 端口都保持不变,这样我们直接在手机上设一下 hosts ,v2就会自动把对应端口通过 ss 转发到对应主机上啦。重复一遍,如果你要使用443端口部署其他服务,请使用 nginx、SNIProxy 等其他服务自行分流

FCM-For-mojo

根据官方教程[3]和mojo教程[4]整理了一下,复制粘贴就好,没报错的话就会成功启动一个服务端,并开始打印日志。

SERVER_ZIP=https://github.com/RikkaApps/FCM-for-Mojo/releases/download/v0.5.1/server.zip
curl http://share-10066126.cos.myqcloud.com/cpanm.pl|perl - Mojo::Webqq
mkdir ffm && cd ffm
wget $SERVER_ZIP
mv config.example.js config.js
unzip server.zip && cd node
npm install && cd ..
npm install -g pm2
sudo echo "127.0.0.1 fcm.googleapis.com" >> /etc/hosts
pm2 start node/index.js --name 'mojo'
pm2 logs mojo

pm2 类似 python 的 supervisor。直接 Ctrl - C 退出它就在后台运行啦。

扫码登陆

按服务端日志里的提示打开链接扫码登陆。这个框架基于 SmartQQ 只能这么搞。

如果图床挂了,在自己机器上打开它提示的文件就好。

scp vps.yours.com:/tmp/mojo_webqq_qrcode_ffm.png /tmp
open /tmp/mojo_webqq_qrcode_ffm.png # for mac

客户端配置

仅针对安卓。废话别的手机哪儿来的 FCM

从官方 releases 下载 ffm 的客户端。按提示配置。

然后用 AdAway 等软件设置hosts,将 android.clients.google.commtalk.google.com 指向服务器IP即可。这里不推荐用 Go Hosts 。开发者人品极差。


  1. Firebase 云消息传递 HTTP 协议  |  Firebase

  2. 文件格式 · Project V 官方网站

  3. RikkaApps/FCM-for-Mojo: Firebase Cloud Messaging for Mojo-Webqq.

  4. sjdy521/Mojo-Webqq: #安装方法