基于Erlang的个人MTProto代理:策略系统与专属密钥
MTProto代理可在网络审查环境下提供Telegram访问。传统模型使用单一密钥服务所有用户,导致诸多问题:缺乏访问控制、无法分析用户活动、盈利模式受限。解决方案是为每位客户分配专属密钥及唯一SNI域名,通过Erlang mtproto_proxy的策略系统实现。
该实现通过O(1)复杂度的连接验证和运行时可配置规则实现扩展。支持连接限制、访问撤销和活动追踪,无需重启服务器。
Erlang在高负载代理中的优势
Erlang/OTP因其专为处理数百万长连接设计的架构,成为MTProto代理的理想选择:
- 进程隔离:每个连接都是独立的轻量级进程(约2KB)。单个进程崩溃不影响其他连接。
- 自动扩展:BEAM自动将进程分配到所有CPU核心,无需手动管理。
- 抢占式多任务:单个客户端无法独占CPU核心。
- 位语法解析:单行代码安全解析TLS ClientHello:
parse_client_hello(
<<?TLS_REC_HANDSHAKE, ?TLS_10_VERSION, TlsFrameLen:16,
?TLS_TAG_CLIENT_HELLO, HelloLen:24, ?TLS_12_VERSION,
Random:32/binary,
SessIdLen, SessId:SessIdLen/binary,
CipherSuitesLen:16, CipherSuites:CipherSuitesLen/binary,
CompMethodsLen, CompMethods:CompMethodsLen/binary,
ExtensionsLen:16, Extensions:ExtensionsLen/binary>>
) when TlsFrameLen >= 512, HelloLen >= 508 -> ...
- 实时监控:通过远程控制台检查表和状态。
- 热更新:无需中断连接即可修改代码和配置。
总代码量仅3500行,少于大多数替代方案。
SNI与伪装TLS密钥格式
服务器名称指示(SNI)允许客户端在完成TLS握手前,于ClientHello中指定域名。伪装TLS模仿TLS 1.3 ClientHello,使用合法的SNI,将MTProto协议隐藏在加密字段中。
个人密钥格式:
0xEE | <16随机字节> | <UTF-8编码的SNI域名>
t.me/proxy使用的十六进制字符串:
ee<32位十六进制令牌><十六进制编码的SNI>
验证方式:使用端口基础密钥对ClientHello进行HMAC。唯一性基于扩展中的SNI域名。
策略系统:访问规则
策略是为每个连接制定的有序规则列表。第一条未满足的规则将拒绝连接。
规则类型
| 规则 | 描述 |
|------|-------------|
| {in_table, Key, Table} | 键值存在于表中 |
| {not_in_table, Key, Table} | 键值不存在于表中 |
| {max_connections, [Key,...], N} | 键值连接数 ≤ N |
连接中的键值
tls_domain— 伪装TLS中的SNIport_name— 端口名称client_ipv4/client_ipv6— 客户端IP{client_ipv4_subnet, Mask}— 子网
表为内存哈希表,配置重载时保存,重启时丢失。
个人代理策略配置
基础策略:
{policy, [
{in_table, tls_domain, personal_domains},
{max_connections, [tls_domain], 30}
]}
- 白名单:
tls_domain必须在personal_domains表中。 - 限制:每个域名同时连接数≤30(防止链接共享)。
扩展配置:
{max_connections, [client_ipv4], 30},
{not_in_table, client_ipv4, ip4_blacklist}
启动标准个人代理
sys.config配置
{mtproto_proxy, [
{ports, [
#{name => mtp_handler,
listen_ip => "0.0.0.0",
port => 443,
secret => <<"d0d6e111bada5511fcce9584deadbeef">>,
tag => <<"dcbe8f1493fa4cd9ab300891c0b5b326">>}
]},
{allowed_protocols, [mtp_fake_tls]},
{policy, [
{in_table, tls_domain, personal_domains},
{max_connections, [tls_domain], 100}
]}
]}
域名注册
mtp_proxy eval '
mtp_policy_table:add(personal_domains, tls_domain, "alice42.example.com").'
域名立即生效。
核心要点
- 个人SNI域名实现访问控制和数据分析,无需更改基础密钥。
- 策略检查复杂度为O(1),可扩展至数千用户。
- Erlang确保连接隔离和零停机时间。
- 策略表通过Erlang RPC运行时管理。
- 每个域名30连接限制防止滥用。
— Editorial Team
暂无评论。