返回首页

Nginx 上 443 端口的 MTProxy:Telegram 隐藏设置

使用 stream 模块和 TLS 伪装在 443 端口设置 Telegram MTProxy 的详细指南,以 Nginx 绕过封锁。适用于 IT 专家。

Nginx + 443 上的 MTProxy:Telegram 隐藏设置指南
Advertisement 728x90

在Nginx 443端口隐匿部署Telegram MTProxy

本文旨在解决系统管理员和开发者面临的一个关键挑战:如何在不干扰现有Nginx管理的Web服务的前提下,在标准的HTTPS 443端口上部署Telegram MTProxy。这种配置通过将代理流量伪装成常规Web流量,显著增强了代理抵御检测和封锁的能力。主要难点在于Nginx如何正确路由请求,在同一端口上区分目标HTTP/HTTPS站点和MTProxy。本指南将详细阐述Nginx stream 模块的运行机制及其与 mtprotoproxy 的集成,以创建一个强大而隐蔽的解决方案。

Nginx Stream 模块如何实现多路复用

为了让MTProxy和Nginx能在443端口上成功共存,一个智能的路由机制至关重要。Nginx的stream模块在TCP/UDP层运行,能够在完整的应用层处理之前分析初始连接数据。一个关键点是,TLS ClientHello消息中的服务器名称指示(SNI)字段即使在加密连接中也是以明文传输的。这使得Nginx无需解密整个SSL流即可读取请求的主机名。

所提出的解决方案采用以下逻辑:

Google AdInline article slot
  • HTTPS主机的端口重分配: 所有先前监听443端口的现有Nginx HTTPS虚拟主机都将迁移到一个内部端口,例如4443。这为集中式处理器腾出了443端口。
  • Nginx Stream 作为中央路由器: 在现在可用的443端口上配置一个Nginx stream 服务器。该服务器使用 ssl_preread on 指令从传入的SSL连接中提取SNI。
  • 动态路由: 根据提取到的SNI,Nginx stream 做出决策:

* 如果SNI与为MTProxy选择的域名(例如 myprovider.ru)匹配,则连接将被转发到MTProxy(MTProxy将监听一个本地端口,例如7788)。

* 如果SNI与任何其他域名匹配,则连接将被重定向回Nginx,但会重定向到内部端口4443,在那里由标准的HTTPS虚拟主机进行处理。

  • 保留真实IP: 为了准确的日志记录、流量分析以及Nginx后端应用程序的正常运行,使用了 proxy_protocol。这允许真实的客户端IP地址沿着代理链传递。

这种方法使得MTProxy能够伪装成常规的HTTPS流量,与Web服务器使用相同的端口。这显著提高了其抵御检测和封锁的能力,使其流量与标准Web连接无法区分。

Google AdInline article slot

配置Nginx以实现共存

第一步是修改所有现有Nginx HTTPS虚拟主机的配置。您需要将其监听端口从443更改为内部端口,例如 127.0.0.1:4443。这确保了Nginx在 stream 模块重定向请求后能够处理这些请求。

示例 server 块修改:

server {
  server_name mywebsite.ru;
  listen 127.0.0.1:4443 ssl http2 proxy_protocol;
  set_real_ip_from 127.0.0.1;    # 信任localhost作为PROXY协议源
  real_ip_header proxy_protocol; # 从PROXY协议头中提取IP
  real_ip_recursive on;          # 递归应用以正确确定IP
  # ... 您的服务器块的其他指令 ...
  ssl_certificate /etc/letsencrypt/live/mywebsite.ru/fullchain.pem;
  ssl_certificate_key /etc/letsencrypt/live/mywebsite.ru/privkey.pem;
  # ... 其他SSL/TLS设置 ...
}

listen 中的 proxy_protocol 指令指示Nginx期望接收PROXY协议头。set_real_ip_fromreal_ip_header 对于Nginx正确识别并传递客户端的真实IP地址至关重要,而不是Nginx Stream将使用的本地主机IP(127.0.0.1)。如果没有这些设置,所有对您站点的请求都将显示为源自 127.0.0.1,这可能会扰乱应用程序功能、日志记录和安全系统。

Google AdInline article slot

下一步是为Nginx stream 模块创建一个新的配置文件。建议将其放置在 /etc/nginx/conf.d/stream.conf 或其他能确保Nginx加载它的合适位置。

stream {
    log_format stream '$remote_addr [$time_local] host=$ssl_preread_server_name '
                      'prot=$protocol status=$status out=$bytes_sent in=$bytes_received';

    # 可选:启用日志以进行调试
    #access_log /var/log/nginx/stream_access.log stream;
    #error_log /var/log/nginx/stream_error.log;

    map $ssl_preread_server_name $backend_name {
        myprovider.ru      tg_proxy;    # 选定MTProxy域名的流量
        default            nginx_https; # 所有其他HTTPS流量
    }

    upstream nginx_https {
        server 127.0.0.1:4443; # 重定向到Nginx的内部端口
    }

    upstream tg_proxy {
        server 127.0.0.1:7788; # 重定向到MTProxy的本地端口
    }

    server {
        listen 443 reuseport; # 监听主443端口
        proxy_pass $backend_name;
        ssl_preread on;       # 启用SNI读取以确定主机名
        proxy_protocol on;    # 启用PROXY协议以传递真实IP
    }
}

在此块中,map 用于将SNI($ssl_preread_server_name)与后端名称关联起来。$backend_name 将根据请求的域名是 tg_proxy 还是 nginx_httpsupstream 指令定义了每个后端流量的转发位置。listen 443 reuseport 允许多个Nginx进程监听同一端口,从而提高性能和容错能力。ssl_preread on 是一个关键指令,它使Nginx无需解密整个SSL流量即可获取SNI。

如果您的当前Nginx安装不支持 stream 模块(例如,它是最小化构建),则需要安装它。在Debian/Ubuntu上,可以使用以下命令完成:

sudo apt install nginx-full

完成所有更改后,您必须验证Nginx配置并重新启动它:

nginx -t && sudo systemctl restart nginx

在基于systemd的系统上,使用 systemctl restart 而不是 service nginx restart 是更现代和推荐的方法。

MTProxy安装与配置

在此设置中实现MTProxy,我们将使用alexbers开发的高效Python实现 mtprotoproxy,它与Nginx proxy_protocol 良好集成,并支持所需的TLS伪装模式。

安装过程包括克隆仓库并切换到适当的分支:

(cd /opt || sudo mkdir /opt && sudo chown $(whoami):$(whoami) /opt) && cd /opt
git clone https://github.com/alexbers/mtprotoproxy.git
cd mtprotoproxy
# 重要提示:在撰写本文时,此配置在master分支上可实现稳定运行
git checkout master

接下来,为MTProxy生成一个密钥(secret)。此密钥将用于Telegram客户端的身份验证,并且必须是唯一的:

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

生成的32位十六进制值应该保存下来。现在,您需要在 mtprotoproxy 目录中创建或编辑 config.py 文件:

# /opt/mtprotoproxy/config.py
PORT = 7788 # Nginx Stream将重定向流量到的本地端口
LISTEN_ADDR_IPV4 = "127.0.0.1" # 为安全起见绑定到localhost
LISTEN_ADDR_IPV6 = None # 如果不需要或未配置,则禁用IPv6

# 用户及其密钥的字典。可以为不同的组创建多个。
USERS = {
    "tg_user_1":  "YOUR_GENERATED_SECRET_HERE",
    # "tg_user_2": "0123456789abcdef0123456789abcdef", # 额外密钥示例
}

# MTProxy运行模式
MODES = {
    "classic": False, # 经典模式,易于检测
    "secure": False,  # 改进模式,但伪装效果不佳
    "tls": True       # TLS伪装模式,最能抵抗检测
}

# TLS模式的域名。MTProxy将在启动时检查其可用性。
# 使用您在Nginx Stream配置中选择的域名。
TLS_DOMAIN = "myprovider.ru" # 将用于MTProxy的域名
PROXY_PROTOCOL = True # 与Nginx Stream配合工作的强制设置
# AD_TAG = "GET_YOUR_AD_TAG_FROM_@MTProxybot" # 可选:用于广告标签

这里的关键设置包括:LISTEN_ADDR_IPV4 = "127.0.0.1" 确保MTProxy只能通过同一服务器上的Nginx访问,从而增强安全性。MODES = {"tls": True} 激活TLS伪装模式,使MTProxy流量与常规HTTPS无法区分。TLS_DOMAIN 必须与Nginx Stream map 指令中指定的域名匹配,以便Nginx正确识别和转发流量。最后,PROXY_PROTOCOL = True 允许MTProxy从Nginx接收客户端的真实IP地址,这对于正常运行和日志记录至关重要。

验证与自动化启动

在配置Nginx和MTProxy之后,彻底验证整个系统的功能至关重要。

验证MTProxy和Nginx功能

  • 手动启动MTProxy: 导航到 /opt/mtprotoproxy 目录,手动启动MTProxy进行初步检查:

```bash

python3 mtprotoproxy.py

```

控制台应显示一行代理连接参数,例如:

```

tg_user_1: tg://proxy?server=YOUR_VM_IP&port=7788&secret=LONG_SECRET

```

重要提示: 这里显示的密钥将带有 ee 前缀,并包含 config.py 中指定的编码 TLS_DOMAIN。这是TLS伪装机制的一部分。复制此链接。

  • 使用Telegram客户端测试:

* 在复制的链接中,将端口从 7788 更改为 443

* 将生成的链接发送到Telegram的“收藏夹”或“保存的消息”中。

* 点击链接并选择“连接”。

* 如果一切配置正确,Telegram应该能通过代理成功连接。为了进行额外检查,您可以向任何机器人(例如 @MTProxybot)发送 /ping 命令——应返回一条包含当前代理延迟的消息。

  • 验证HTTPS伪装: 为确认MTProxy正确伪装成常规网站,请执行以下检查:

* 将以下行添加到您的本地 hosts 文件中(对于Linux/macOS,是 /etc/hosts;对于Windows,是 %SystemRoot%\System32\drivers\etc\hosts):

```

YOUR_VM_IP myprovider.ru

```

* 将 YOUR_VM_IP 替换为您的服务器实际IP地址。

* 在浏览器中打开 https://myprovider.ru

* 如果一切正常,您应该能看到 myprovider.ru 的内容(您的提供商网站或您在 TLS_DOMAIN 中指定的任何其他域名)。这证实了Nginx Stream将请求重定向到MTProxy,并且MTProxy识别为非Telegram流量后,透明地将其代理到原始Web资源,从而展示了成功的TLS伪装。

* 验证后请务必删除 hosts 文件中添加的行。

将MTProxy设置为Systemd服务

为确保MTProxy在系统启动时自动启动并持续运行,建议将其配置为 systemd 服务。

  • 停止 手动运行的MTProxy(Ctrl+C)。
  • 创建 一个 systemd 单元文件,路径为 /etc/systemd/system/mtprotoproxy.service

```ini

[Unit]

Description=MTProto Proxy

After=network.target

[Service]

Type=simple

User=nobody

Group=nogroup

WorkingDirectory=/opt/mtprotoproxy

ExecStart=/usr/bin/python3 /opt/mtprotoproxy/mtprotoproxy.py

Restart=always

RestartSec=3

[Install]

WantedBy=multi-user.target

```

在这里,User=nobodyGroup=nogroup 通过以最小权限运行服务来增强安全性。WorkingDirectory 指向 mtprotoproxy.py 脚本所在的目录。

  • 重新加载 systemd 配置,启用服务并启动它:

```bash

sudo systemctl daemon-reload

sudo systemctl enable mtprotoproxy.service

sudo systemctl start mtprotoproxy.service

```

  • 检查 服务状态:

```bash

systemctl status mtprotoproxy.service

```

输出应显示服务处于 active (running) 状态。

  • 查看日志: 用于调试或监控,请使用:

```bash

journalctl -u mtprotoproxy.service -e

```

这种全面的设置允许您在443端口上使用Telegram MTProxy,有效地将其伪装成常规HTTPS流量,同时保留同一服务器上现有网站的全部功能。

重要提示:

  • 在Nginx Stream中使用 ssl_preread 可以在不解密的情况下基于SNI进行流量路由,这对于在单个端口上分离MTProxy和HTTPS流量至关重要。
  • 在Nginx和MTProxy中配置 proxy_protocol 确保了客户端真实IP地址的传输,这对于日志记录和安全性至关重要。
  • MTProxy配置为 tls: True 模式并指定了 TLS_DOMAIN,使得代理流量与到该域名的常规HTTPS连接无法区分。
  • 将MTProxy绑定到 127.0.0.1 通过限制直接外部访问来增强安全性。
  • systemd 服务确保MTProxy的自动启动和监控,保证其持续运行。

— Editorial Team

Advertisement 728x90

继续阅读