✈️ GCP 部署 Telegram MTProxy 完整指南

官方源码编译 + systemd 部署实录:与 sing-box、HY2、Caddy 共存,TCP 8443 独立端口,GCP NAT 参数修复,客户端 Secret 独立存储,每日官方配置自动更新(已脱敏,可公开)

在已有 GCP Debian VPS 上部署 Telegram MTProxy,作为独立的 Telegram 专用代理服务。本方案采用 Telegram 官方 MTProxy 源码编译,使用 systemd 管理,不依赖 Docker 容器运行。本文 IP 均为示例值,请替换为你自己的。

一、部署目标

在已有 GCP Debian VPS 上部署 Telegram MTProxy,作为独立的 Telegram 专用代理服务。

本方案采用 Telegram 官方 MTProxy 源码编译,使用 systemd 管理,不依赖 Docker 容器运行。

主要目标:

说明:本站早期版本是 Docker 镜像方案。官方镜像版本较旧,实际部署最终改用官方源码编译 + systemd,本文即为实际成功部署的记录。

二、服务器环境

实际部署环境:

项目 配置
云平台 Google Cloud Platform
操作系统 Debian GNU/Linux 12 Bookworm
架构 x86_64
CPU 2 vCPU(共享型)
内存 约 1GB
系统磁盘 30GB
Swap 512MB
Docker 29.9.3,已安装但不用于运行 MTProxy
MTProxy Telegram 官方源码编译
编译提交 69f2f08

当前服务器原有服务:

服务 协议 端口
Caddy TCP 80、443
sing-box / HY2 UDP 443
SSH TCP 22
Telegram MTProxy TCP 8443

特别注意:Caddy 使用 TCP 443,sing-box 使用 UDP 443,两者可以同时使用,不需要修改原有配置。

三、GCP NAT 网络说明

GCP VM 使用公网 NAT,实例内部地址和公网地址不同。

本次部署地址(示例值):

项目 地址
VM 内网 IP 10.128.0.2
GCP 公网 IP 203.0.113.10
MTProxy 端口 TCP 8443

这是本次部署中最重要的技术调整。

MTProxy 需要通过 --nat-info 告知自身内部地址和公网映射地址,否则可能出现 TCP 端口测试成功,但 Telegram 客户端无法正常完成连接的问题。

正确参数:

--nat-info 10.128.0.2:203.0.113.10

检查内网地址:

ip -4 route get 149.154.175.50

检查公网地址:

curl -4fsS https://api.ipify.org
echo

如果更换公网 IP,需要同步修改 NAT 参数和客户端连接地址。

建议在 GCP 中保留静态外部 IP,避免实例停止或重新启动后公网地址发生变化。

四、增加 Swap

由于免费层级 VM 只有约 1GB 内存,为减少内存不足时进程被 OOM Killer 终止的风险,增加 512MB Swap。

创建 Swap:

sudo fallocate -l 512M /swapfile
sudo chmod 600 /swapfile
sudo mkswap /swapfile
sudo swapon /swapfile

设置开机自动挂载:

echo '/swapfile none swap sw 0 0' | sudo tee -a /etc/fstab

设置 Swap 使用倾向:

echo 'vm.swappiness=10' | sudo tee /etc/sysctl.d/99-swap.conf
sudo sysctl --system

检查:

free -h
sudo /sbin/swapon --show

注意:Swap 文件使用现有系统磁盘空间,不需要另外创建 GCP 持久磁盘,不会因为创建 Swap 本身增加云磁盘容量。

Swap 是内存不足时的缓冲,不是物理内存的替代品。如果持续大量使用 Swap,需要进一步检查内存压力。

五、安装编译依赖

更新软件源:

sudo apt-get update

安装依赖:

sudo apt-get install -y \
  git curl build-essential \
  libssl-dev zlib1g-dev

六、下载 Telegram 官方源码

官方项目:https://github.com/TelegramMessenger/MTProxy

克隆源码:

sudo git clone --depth 1 \
  https://github.com/TelegramMessenger/MTProxy.git \
  /opt/MTProxy

由于使用 sudo 下载,源码目录归 root 所有。

检查版本:

sudo git -C /opt/MTProxy rev-parse --short HEAD

实际部署提交:

69f2f08

七、编译 MTProxy

进入源码目录:

cd /opt/MTProxy

考虑到 VM 只有约 1GB 内存,使用单线程编译:

sudo make -j1

检查编译结果:

ls -lh /opt/MTProxy/objs/bin/mtproto-proxy

实际生成文件 /opt/MTProxy/objs/bin/mtproto-proxy,文件大小约 508KB。

八、下载 Telegram 官方配置

进入源码目录:

cd /opt/MTProxy

下载官方 Secret 文件:

sudo curl -fsSL \
  https://core.telegram.org/getProxySecret \
  -o proxy-secret

下载官方服务器配置:

sudo curl -fsSL \
  https://core.telegram.org/getProxyConfig \
  -o proxy-multi.conf

检查文件:

wc -c proxy-secret proxy-multi.conf

实际部署结果:

128 proxy-secret
821 proxy-multi.conf

检查配置结构:

grep -q '^default ' proxy-multi.conf \
  && echo "default 配置存在"

grep -q '^proxy_for ' proxy-multi.conf \
  && echo "proxy_for 配置存在"

两个配置项均通过检查。

注意:proxy-secret 是 MTProxy 用于连接 Telegram 后端的官方密钥文件,不是提供给用户的客户端 Secret。

九、生成独立客户端 Secret

客户端 Secret 单独存放在 /etc/mtproxy/,不放在 Git 源码目录中。

创建目录:

sudo install -d -m 700 /etc/mtproxy

生成 128 位随机 Secret:

sudo bash -c '
umask 077
printf "CLIENT_SECRET=%s\n" "$(openssl rand -hex 16)" \
  > /etc/mtproxy/mtproxy.env
'

检查权限:

sudo stat -c '%a %U:%G %n' \
  /etc/mtproxy \
  /etc/mtproxy/mtproxy.env

预期:

700 root:root /etc/mtproxy
600 root:root /etc/mtproxy/mtproxy.env

Secret 不要提交到 Git,不要公开分享。

十、配置 systemd 服务

创建服务文件:

sudo tee /etc/systemd/system/mtproxy.service > /dev/null <<'EOF'
[Unit]
Description=Telegram MTProxy
After=network-online.target
Wants=network-online.target

[Service]
Type=simple
WorkingDirectory=/opt/MTProxy
EnvironmentFile=/etc/mtproxy/mtproxy.env

ExecStart=/opt/MTProxy/objs/bin/mtproto-proxy \
  -u nobody \
  -p 8888 \
  -H 8443 \
  -S ${CLIENT_SECRET} \
  --aes-pwd /opt/MTProxy/proxy-secret \
  /opt/MTProxy/proxy-multi.conf \
  --nat-info 10.128.0.2:203.0.113.10 \
  -M 1

Restart=on-failure
RestartSec=5
LimitNOFILE=65536

[Install]
WantedBy=multi-user.target
EOF

说明:

参数 作用
-u nobody 以低权限用户运行
-p 8888 MTProxy 统计端口参数
-H 8443 客户端监听端口
-S 客户端连接 Secret
--aes-pwd Telegram 官方后端密钥文件
--nat-info GCP 内外网 NAT 映射
-M 1 一个 Worker

检查 systemd 配置:

sudo systemd-analyze verify \
  /etc/systemd/system/mtproxy.service

重新加载并启动:

sudo systemctl daemon-reload
sudo systemctl enable --now mtproxy

检查状态:

sudo systemctl status mtproxy --no-pager

检查端口:

sudo ss -lntup | grep -E ':(8443|8888)\b'

查看日志:

sudo journalctl -u mtproxy -n 50 --no-pager

实际运行检查结果:

注意:systemctl status 和 ps 的完整输出可能包含启动参数中的客户端 Secret。不要将未经脱敏的完整输出公开。

十一、GCP 防火墙配置

在 GCP 控制台:VPC Network → Firewall → Create Firewall Rule。

建议参数:

配置项 设置
名称 allow-mtproxy-8443
方向 Ingress
操作 Allow
目标 指定 MTProxy VM
来源 IPv4 0.0.0.0/0
协议 TCP
端口 8443

只开放 TCP 8443。

不要开放 TCP 8888,也不要修改原有 TCP 443、UDP 443 和 SSH 22 规则。

十二、Windows 端口连通性测试

在 Windows PowerShell 执行:

Test-NetConnection 203.0.113.10 -Port 8443

实际测试结果:

ComputerName     : 203.0.113.10
RemotePort       : 8443
TcpTestSucceeded : True

说明公网 TCP 8443 已经可达。

但是 TCP 测试成功不代表 Telegram 协议认证一定成功,还需要客户端实际连接验证。

十三、GCP NAT 参数修复

第一次测试时,TCP 8443 可以连接,但 Telegram 客户端无法正常使用。

检查发现内网地址与公网地址不一致(见第三节的地址表)。通过检查 MTProxy 帮助信息,确认当前版本支持:

--nat-info <local-addr>:<global-addr>

在 systemd 服务中增加:

--nat-info 10.128.0.2:203.0.113.10

重新加载并重启:

sudo systemctl daemon-reload
sudo systemctl restart mtproxy

修改后 Telegram 客户端成功连接。

这是本次部署最关键的故障排查和修复步骤。

十四、Telegram 客户端连接

客户端使用 MTProto 类型。

连接参数:

项目 内容
Server GCP 公网 IP
Port 8443
Secret 客户端随机 Secret

建议使用 Telegram 官方支持的随机填充模式。

客户端 Secret 格式:

dd + 32位十六进制随机 Secret

生成连接链接:

sudo bash -c '
source /etc/mtproxy/mtproxy.env
printf "tg://proxy?server=203.0.113.10&port=8443&secret=dd%s\n" "$CLIENT_SECRET"
'

这里的 Secret 必须使用当前 /etc/mtproxy/mtproxy.env 中的值。

在 Windows 上打开生成的 Telegram 链接,导入 Telegram Desktop。

验证:

  1. Telegram 显示代理已连接。
  2. 能够正常收发文字消息。
  3. 能够传输图片和文件。
  4. 关闭并重新打开客户端后仍能连接。
  5. 切换网络后重新测试。

实际部署已经完成 Telegram 客户端连接验证。

十五、每日自动更新 Telegram 官方配置

Telegram 官方建议定期更新 proxy-multi.conf。

采用 systemd timer,每天检查一次。

更新脚本:

sudo tee /usr/local/sbin/mtproxy-refresh-config > /dev/null <<'EOF'
#!/bin/bash
set -Eeuo pipefail

CONFIG="/opt/MTProxy/proxy-multi.conf"
BACKUP="/opt/MTProxy/proxy-multi.conf.bak"
URL="https://core.telegram.org/getProxyConfig"

TMP=$(mktemp /opt/MTProxy/.proxy-config.XXXXXX)
trap 'rm -f "$TMP"' EXIT

logger -t mtproxy-update "开始检查 Telegram 官方配置"

if ! curl -fLsS \
    --connect-timeout 10 \
    --max-time 60 \
    --retry 2 \
    "$URL" -o "$TMP"; then
    logger -t mtproxy-update "下载失败,保留旧配置"
    exit 1
fi

if [ "$(wc -c < "$TMP")" -lt 64 ] ||
   ! grep -q '^default ' "$TMP" ||
   ! grep -q '^proxy_for ' "$TMP"; then
    logger -t mtproxy-update "配置验证失败,保留旧配置"
    exit 1
fi

if cmp -s "$TMP" "$CONFIG"; then
    logger -t mtproxy-update "配置没有变化,无需重启"
    exit 0
fi

cp -a "$CONFIG" "$BACKUP"

install -o root -g root -m 0644 "$TMP" "${CONFIG}.new"
mv -f "${CONFIG}.new" "$CONFIG"

if systemctl restart mtproxy &&
   systemctl is-active --quiet mtproxy; then
    logger -t mtproxy-update "配置更新成功,MTProxy 已重启"
else
    cp -a "$BACKUP" "$CONFIG"
    systemctl restart mtproxy || true
    logger -t mtproxy-update "更新后服务异常,已尝试恢复旧配置"
    exit 1
fi
EOF

sudo chmod 700 /usr/local/sbin/mtproxy-refresh-config

更新脚本特点:

注意:这是基础完整性检查,不等于完整的配置语义校验;自动恢复也需要通过后续日志和服务状态监控确认。

创建 systemd service:

sudo tee /etc/systemd/system/mtproxy-refresh-config.service > /dev/null <<'EOF'
[Unit]
Description=Refresh Telegram MTProxy configuration

[Service]
Type=oneshot
ExecStart=/usr/local/sbin/mtproxy-refresh-config
EOF

创建每日 timer:

sudo tee /etc/systemd/system/mtproxy-refresh-config.timer > /dev/null <<'EOF'
[Unit]
Description=Daily Telegram MTProxy configuration refresh

[Timer]
OnCalendar=*-*-* 04:17:00
Persistent=true
RandomizedDelaySec=5m
Unit=mtproxy-refresh-config.service

[Install]
WantedBy=timers.target
EOF

检查配置:

sudo systemd-analyze verify \
  /etc/systemd/system/mtproxy-refresh-config.service \
  /etc/systemd/system/mtproxy-refresh-config.timer

手动测试:

sudo /usr/local/sbin/mtproxy-refresh-config

查看更新日志:

sudo journalctl -t mtproxy-update -n 20 --no-pager

启用定时器:

sudo systemctl daemon-reload
sudo systemctl enable --now mtproxy-refresh-config.timer

检查:

systemctl list-timers mtproxy-refresh-config.timer

实际手动更新成功,定时器也已成功启用。

本次设置的计划执行时间为每天 UTC 04:17,另有最多 5 分钟随机延迟。

十六、日常维护命令

查看 MTProxy 状态:

sudo systemctl is-active mtproxy

查看开机启动状态:

sudo systemctl is-enabled mtproxy

查看日志:

sudo journalctl -u mtproxy -n 50 --no-pager

实时日志:

sudo journalctl -u mtproxy -f

检查监听端口:

sudo ss -lntup | grep -E ':(8443|8888)\b'

检查每日更新任务:

sudo systemctl is-active mtproxy-refresh-config.timer

查看下次更新:

systemctl list-timers mtproxy-refresh-config.timer

查看更新日志:

sudo journalctl -t mtproxy-update -n 30 --no-pager

查看内存:

free -h

查看 Swap:

sudo /sbin/swapon --show

十七、GCP 免费层级与资源注意事项

本次部署使用已有 VM,没有新增实例,也没有新增 GCP 持久磁盘。

Docker 已安装,但 MTProxy 直接运行官方源码编译后的程序,不需要 Docker 容器常驻。

需要关注:

  1. MTProxy 流量直接经过 GCP VM,不经过 Cloudflare CDN。
  2. GCP 免费额度有区域、流量和资源使用条件,不能认为所有 MTProxy 流量都免费。
  3. 512MB Swap 占用现有系统磁盘空间。
  4. MTProxy 当前使用一个 Worker。
  5. 约 1GB RAM 的 VM 应持续监控内存和 Swap。
  6. 不建议在该 VM 上安装额外的容器管理面板。
  7. 不建议为了 MTProxy 修改现有 sing-box、HY2 和 Caddy 配置。

十八、最终部署状态

项目 状态
Telegram 官方源码 已下载
官方源码编译 成功
官方配置下载 成功
客户端 Secret 已生成并轮换
systemd 服务 正常运行
运行权限 nobody
NAT 参数 已配置
TCP 8443 公网可达
GCP 防火墙 已放行
Telegram 客户端 已成功连接
开机自动启动 已启用
异常自动重启 已配置
每日配置更新 已启用
配置备份 已配置
Swap 512MB,已启用

十九、最终架构

GCP Debian 12 VPS
│
├── Caddy
│   ├── TCP 80
│   └── TCP 443
│
├── sing-box
│   └── UDP 443
│
├── Telegram MTProxy
│   ├── 官方源码编译
│   ├── systemd 管理
│   ├── TCP 8443
│   ├── NAT 映射配置
│   └── 单 Worker
│
├── MTProxy 配置维护
│   ├── 每日下载官方配置
│   ├── 配置完整性检查
│   ├── 变化检测
│   ├── 自动备份
│   └── 更新后重启
│
└── 系统资源
    ├── 约 1GB RAM
    ├── 512MB Swap
    └── 30GB 系统磁盘

总结:

本方案最终采用 Telegram 官方源码 + systemd,而不是 Docker 镜像运行。

通过独立 TCP 8443、GCP NAT 参数、客户端独立 Secret 和每日自动更新机制,实现了与现有 Caddy、sing-box、HY2 服务共存的 Telegram MTProxy 部署。

后续主要维护源码版本、Telegram 官方配置、Secret 安全、GCP 出站流量以及服务器内存使用情况。

二十、关键经验

  1. GCP NAT 是关键:--nat-info 是实际解决「TCP 通但客户端连不上」的关键修复,应作为独立章节,而不是简单的一条启动参数。
  2. Docker 不一定是最佳选择:官方镜像较旧,最终采用官方源码编译更合适;Docker 保留安装,但不参与 MTProxy 的实际运行。
  3. 端口共存:TCP 443 与 UDP 443 可以同时使用(Caddy 与 sing-box 互不干扰),MTProxy 使用独立的 TCP 8443,零改动现有服务。
  4. 自动更新要有保护:不应直接覆盖配置文件,必须先下载、检查、备份,再替换,异常时回滚。
  5. 两个保留事项:目前自动更新脚本是基础检查和重启回滚,并不是真正的端到端健康检查,后续可以增强为检查进程、监听端口和 Telegram 后端连接状态;另外 systemctl status mtproxy 可能显示启动参数中的 Secret,发布截图或日志时必须脱敏。