利用SSR在国内服务器转发Telegram的MTProxy代理

糟糕的背景说明

最近这段时间,Telegram的MTProxy可以说几乎是被判了死刑,原因无外乎是MTProxy的数据包大小特征太明显,极其容易被分析出来。虽然官方加入了Random Padding这个功能试图解决这个问题,但效果其实非常可怜,我换完端口后开启了Random Padding,哪怕只有我一个人在用这个代理,依然在12小时内被封掉。

现在普遍的建议是在国内搭需要鉴权的socks5服务器,这个技术上没有问题,但如果你要分享出去的话,一个socks5代理可以做的,可不仅仅是MTProxy这么简单,需要承担的风险会大得多。

这种情况,要么上专线搭MTProxy,要么就用更不容易被封的手段转发这个代理服务,不管是v2还是ssr,这个你根据自己的爱好选择,我习惯性的还是用ssr。

在国外VPS建立一个跳板代理

对我来说,这就是一台装了SSR的国外VPS而已。

在国内VPS建立一个透明代理

我们以ssr为例,这里需要用到的是ss(r)-redir,而不是ss(r)-local,后者是用于建立socks5代理的,而前者才是我们所需要的透明代理。具体的建立过程就不多说了,无非就是ss-redir -c config.json了,这里我设定的本地代理端口是127.0.0.1:1080。注意,不要开放到0.0.0.0上,否则你的透明代理可能会被滥用的。

建立转发规则

根据hostloc论坛网友的建议,只需要找出Telegram的3个ASN所对应的IP,把国内VPS到这些IP的流量全部转发到ss-redir产生的透明代理上就行了。

写了个脚本把这些IP拔下来然后转成bash脚本:

import requests
import json

ip_range_urls = ['https://api.bgpview.io/asn/59930/prefixes', 'https://api.bgpview.io/asn/62014/prefixes',
                 'https://api.bgpview.io/asn/62041/prefixes']

with open('tg_ipset_redirect.sh', 'w') as dst:
    dst.write('#! /bin/bash\n')
    dst.write('ipset create telegram hash:net -!\n')

    for url in ip_range_urls:
        ip_data = json.loads(requests.get(url).content)
        for ip_range in ip_data['data']['ipv4_prefixes']:
            dst.write('ipset add telegram {} -!\n'.format(ip_range['prefix']))

    dst.write(
        'iptables -t nat -A PREROUTING -p tcp -m set --match-set telegram dst -j REDIRECT --to-ports 1080\n')
    dst.write(
        'iptables -t nat -A OUTPUT -p tcp -m set --match-set telegram dst -j REDIRECT --to-ports 1080\n')

产生的bash脚本如下:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
#! /bin/bash
ipset create telegram hash:net -!
ipset add telegram 91.108.12.0/22 -!
ipset add telegram 149.154.172.0/22 -!
ipset add telegram 91.108.16.0/22 -!
ipset add telegram 91.108.56.0/23 -!
ipset add telegram 149.154.168.0/22 -!
ipset add telegram 91.108.4.0/22 -!
ipset add telegram 91.108.8.0/22 -!
ipset add telegram 91.108.56.0/22 -!
ipset add telegram 149.154.160.0/20 -!
ipset add telegram 149.154.164.0/22 -!
iptables -t nat -A PREROUTING -p tcp -m set --match-set telegram dst -j REDIRECT --to-ports 1080
iptables -t nat -A OUTPUT -p tcp -m set --match-set telegram dst -j REDIRECT --to-ports 1080

这么一看,当初还写什么脚本,IP段也没几个啊,害得我一度以为脚本写错了,是不是漏了什么IP,结果上网站一查还真就这几个IP段。 Bash脚本应该都看得懂吧,就是把telegram的IP加入一个ipset中(当然,你得先安装ipset,一般默认都没有),然后把符合tcp协议的、同时目的IP属于这个ipset内的流量,全部转发到ss-redir产生的1080透明代理端口上。

在国内VPS安装MTProxy

不知道为啥,写这篇文章的时候,用官方的MTProxy在本地搭的测试环境一直连不上,之前在国外VPS上搭都是OK的。这次干脆直接换成了纯python3版本的mtprotoproxy,还省去了build过程。

git clone下来后,改下端口设置就行了。config.py里的Users,其实就是个16位的随机secret,可以用以下命令产生:

head -c 16 /dev/urandom | xxd -ps

你还可以配置多个secret,这样就可以把secret当Users来管理了,虽然我目前还没发现这玩意有什么管理功能。

对于python脚本的启动管理,我向来喜欢转个supervisor搞定,只需要写个配置文件就行了:

command=/usr/bin/python3 /root/.services/mtprotoproxy/mtprotoproxy.py
startsecs=1
startretries=100
autorstart=true
autorestart=true

当然,我建议你可以先手工执行以下这个服务器命令,这样会自动echo出产生的MTProxy的地址,省的你自己再去一点点拼起来。

固化ipset和iptables规则

ipset和iptables默认重启后就会掉了,我们可以先把他们保存到文件:

ipset save > /etc/ipset.conf
iptables-save  > /etc/iptables.conf

然后在/etc/rc.local里(对应的是ubuntu/debian系统,centos自己想办法),写入从文件还原ipset和iptables的命令就可以了:

1
2
3
4
5
6
#!/bin/sh

ipset restore < /etc/ipset.conf
iptables-restore < /etc/iptables.conf

exit 0

ubuntu18默认没有/etc/rc.local文件了,自己创建一个就行,记得chomod +x /etc/rc.local给它添加可执行属性。