返回首页

MTProto proxy:个人密钥和策略

本文描述了在 Erlang 上实现个人 MTProto proxy,使用唯一 SNI 域名。它涵盖了用于访问控制、连接限制和用户分析的策略系统。提供了配置和代码示例。

个人 MTProto Proxy:Erlang 和访问策略
Advertisement 728x90

基于Erlang的个人MTProto代理:策略系统与专属密钥

MTProto代理可在网络审查环境下提供Telegram访问。传统模型使用单一密钥服务所有用户,导致诸多问题:缺乏访问控制、无法分析用户活动、盈利模式受限。解决方案是为每位客户分配专属密钥及唯一SNI域名,通过Erlang mtproto_proxy的策略系统实现。

该实现通过O(1)复杂度的连接验证和运行时可配置规则实现扩展。支持连接限制、访问撤销和活动追踪,无需重启服务器。

Erlang在高负载代理中的优势

Erlang/OTP因其专为处理数百万长连接设计的架构,成为MTProto代理的理想选择:

Google AdInline article slot
  • 进程隔离:每个连接都是独立的轻量级进程(约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协议隐藏在加密字段中。

个人密钥格式:

Google AdInline article slot
0xEE | <16随机字节> | <UTF-8编码的SNI域名>

t.me/proxy使用的十六进制字符串:

ee<32位十六进制令牌><十六进制编码的SNI>

验证方式:使用端口基础密钥对ClientHello进行HMAC。唯一性基于扩展中的SNI域名。

策略系统:访问规则

策略是为每个连接制定的有序规则列表。第一条未满足的规则将拒绝连接。

Google AdInline article slot

规则类型

| 规则 | 描述 |

|------|-------------|

| {in_table, Key, Table} | 键值存在于表中 |

| {not_in_table, Key, Table} | 键值不存在于表中 |

| {max_connections, [Key,...], N} | 键值连接数 ≤ N |

连接中的键值

  • tls_domain — 伪装TLS中的SNI
  • port_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

Advertisement 728x90

继续阅读