官方源码编译 + 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 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,避免实例停止或重新启动后公网地址发生变化。
由于免费层级 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
官方项目: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
进入源码目录:
cd /opt/MTProxy
考虑到 VM 只有约 1GB 内存,使用单线程编译:
sudo make -j1
检查编译结果:
ls -lh /opt/MTProxy/objs/bin/mtproto-proxy
实际生成文件 /opt/MTProxy/objs/bin/mtproto-proxy,文件大小约 508KB。
进入源码目录:
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 单独存放在 /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,不要公开分享。
创建服务文件:
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 控制台: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 PowerShell 执行:
Test-NetConnection 203.0.113.10 -Port 8443
实际测试结果:
ComputerName : 203.0.113.10
RemotePort : 8443
TcpTestSucceeded : True
说明公网 TCP 8443 已经可达。
但是 TCP 测试成功不代表 Telegram 协议认证一定成功,还需要客户端实际连接验证。
第一次测试时,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 客户端成功连接。
这是本次部署最关键的故障排查和修复步骤。
客户端使用 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。
验证:
实际部署已经完成 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
更新脚本特点:
default 和 proxy_for 配置项。注意:这是基础完整性检查,不等于完整的配置语义校验;自动恢复也需要通过后续日志和服务状态监控确认。
创建 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
本次部署使用已有 VM,没有新增实例,也没有新增 GCP 持久磁盘。
Docker 已安装,但 MTProxy 直接运行官方源码编译后的程序,不需要 Docker 容器常驻。
需要关注:
| 项目 | 状态 |
|---|---|
| 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 出站流量以及服务器内存使用情况。
--nat-info 是实际解决「TCP 通但客户端连不上」的关键修复,应作为独立章节,而不是简单的一条启动参数。systemctl status mtproxy 可能显示启动参数中的 Secret,发布截图或日志时必须脱敏。