VPS 中转是什么意思:端口转发的原理、用途与配置
VPS 中转就是在用户和目标服务器之间加一台线路更好的 VPS:用户连中转机的端口,中转机把流量原样转给目标服务器,回包也经它返回。它不会让服务器本身变快,只是用两段质量好的线路替换一段绕路、丢包的直连,所以先测三段线路,再决定值不值得中转。
VPS 中转是什么意思?就是在用户和真正提供服务的目标服务器之间,加一台线路更好的 VPS 做中间站:用户连接中转机的某个端口,中转机把收到的流量原样转发到目标服务器,目标服务器的回包也经中转机送回用户。技术上它就是“服务器端口转发”,常用 iptables、realm、socat 或 Nginx 的 stream 模块实现。中转不会让目标服务器本身变快,它的作用是换路:如果用户直连目标服务器要绕路或在晚高峰大量丢包,而“用户到中转机”和“中转机到目标服务器”两段都很干净,那么走中转的体验就会更好。反过来,直连本来就好,中转只会多一跳延迟、多一份流量费。
中转的原理:数据包怎么走
以下示例地址取自文档专用范围:中转机 203.0.113.10,目标服务器 198.51.100.20。
| 步骤 | 直连 | 经过中转 |
|---|---|---|
| 用户发起连接 | 用户 → 198.51.100.20:22 | 用户 → 203.0.113.10:10022 |
| 中转机处理 | — | 把目标改成 198.51.100.20:22,把源地址改成自己的 IP,再发出 |
| 目标服务器看到的来源 | 用户的 IP | 中转机的 IP 203.0.113.10 |
| 回包路径 | 目标 → 用户 | 目标 → 中转机 → 用户 |
两点要记住:
- 回包必须经过中转机。中转机如果只改目标地址、不改源地址,目标服务器会把回包直接发给用户,用户收到一个“陌生地址”发来的包会丢弃,连接建立不起来。所以端口转发一定是“改目标 + 改源”两步,这是配置中最常漏掉的一步。
- 四层转发不解密内容。中转机只搬运 TCP、UDP 数据包,HTTPS、SSH 的加密内容它看不到也不需要看,证书仍然装在目标服务器上。
跨境中转最明显的收益往往是丢包下降;直连绕路严重时,延迟也能跟着降下来。下面是一个假设的晚高峰对比,直连没有绕路、只是出口拥塞:
| 路径 | 延迟 | 丢包 |
|---|---|---|
| 上海电信直连美国西海岸服务器 | 约 190 ms | 约 8%(国际出口拥塞) |
| 上海电信 → 香港中转机(回程优化线路) | 约 35 ms | 低于 1% |
| 香港中转机 → 美国服务器 | 约 150 ms | 低于 1% |
| 经中转合计 | 约 185 ms | 低于 2% |
延迟几乎没变,但丢包从 8% 降到 2% 以下,游戏的卡顿、远程桌面的掉线会明显减少。如果直连晚高峰也只有 1% 丢包,中转就没有意义。
哪些场景适合用中转
| 场景 | 中转解决什么 | 注意事项 |
|---|---|---|
| 游戏服务器在海外,玩家在内地 | 玩家到中转机走优化线路,减少跨境段丢包 | 不少游戏用 UDP,转发规则要包含 UDP |
| 海外分支机构访问总部的业务系统 | 员工连就近、线路好的中转机,再转到总部系统 | 跨境访问要使用合规的网络渠道,正式业务优先考虑运营商的跨境专线 |
| 服务器迁移、换 IP 的过渡期 | 旧服务器把端口转发到新服务器,解析生效前访问旧地址的用户也不会中断 | 过渡结束后及时下线,旧机器的流量也要计费 |
| 不想暴露源站 IP | 对外只公布中转机地址 | 源站 IP 不能在历史解析记录、邮件头等地方泄露过,否则藏不住 |
| 多台后端只开放一个入口 | 一台中转机按端口把流量分给不同服务器 | 所有业务共享中转机的带宽 |
不适合中转的情况也要说清:大文件下载、视频分发这类以流量为主的业务,中转会让流量成本翻倍,用 CDN 更划算;目标服务器需要知道用户真实 IP(例如按 IP 限流、记录登录地)而转发方式又不支持传递时,中转会让所有用户看起来都来自同一个地址。
先测三段线路,再决定要不要中转
在你常用的时段(通常是晚上 8 点到 11 点)分别测三段:
# 1. 在用户这一侧:直连目标服务器、连中转机,各发 100 个包
mtr -rwzc 100 198.51.100.20
mtr -rwzc 100 203.0.113.10
# 2. 在中转机上:测中转机到目标服务器这一段
mtr -rwzc 100 198.51.100.20
Windows 电脑没有 mtr,可以用 ping -n 100 地址 看丢包,或者安装 WinMTR。mtr 报告要看最后一跳(目标地址那一行)的丢包;中间某一跳显示丢包、后面各跳却正常,多半只是那台路由器限制了 ICMP 回应。判断标准:第 1 组的第二条加上第 2 组的丢包,明显低于直连的丢包,而两段延迟相加不比直连多太多(例如多 20 ms 以内),中转才值得做。只看白天的测试结果没有参考价值,跨境线路的问题多数只在晚高峰出现。
方法一:用 iptables 做端口转发
iptables 转发在内核里完成,几乎不占 CPU,适合目标是固定 IP 的情况。下面把中转机的 10022 端口转到目标的 22 端口,把 27015 端口的 TCP 和 UDP 原样转给目标的游戏服务:
# 开启内核转发,并写入配置文件使重启后仍然生效
echo 'net.ipv4.ip_forward = 1' > /etc/sysctl.d/99-forward.conf
sysctl --system
# 改目标:发到本机 10022 的 TCP 转给 198.51.100.20:22
iptables -t nat -A PREROUTING -p tcp --dport 10022 -j DNAT --to-destination 198.51.100.20:22
# 游戏端口 TCP 和 UDP 各一条
iptables -t nat -A PREROUTING -p tcp --dport 27015 -j DNAT --to-destination 198.51.100.20:27015
iptables -t nat -A PREROUTING -p udp --dport 27015 -j DNAT --to-destination 198.51.100.20:27015
# 改源:发往目标服务器的包,源地址换成中转机自己的 IP,保证回包经过中转机
iptables -t nat -A POSTROUTING -d 198.51.100.20 -j SNAT --to-source 203.0.113.10
# 允许这些包被转发(FORWARD 链默认策略为 DROP 时必须加)
iptables -A FORWARD -d 198.51.100.20 -j ACCEPT
iptables -A FORWARD -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
203.0.113.10 要换成中转机网卡上实际配置的地址:云服务器的网卡上通常是内网 IP,公网 IP 由平台做一对一映射,这时 --to-source 写网卡上的内网 IP,或者干脆改用 -j MASQUERADE 让系统自动选择。
没有使用 ufw 的机器,用 iptables-persistent 保存规则,否则重启后全部丢失(Debian、Ubuntu):
apt install -y iptables-persistent
netfilter-persistent save
检查规则有没有命中:iptables -t nat -L -n -v 里每条规则前面的包计数在增长,说明流量进来了。几个常见的坑:
- 装了 Docker 的机器,Docker 在自己开启 IP 转发时会把 FORWARD 链的默认策略设为 DROP(
iptables -S FORWARD第一行能看到),上面两条 FORWARD 规则不能省。 - 开着 ufw 的,
/etc/default/ufw里的DEFAULT_FORWARD_POLICY默认是 DROP,要改成 ACCEPT 或用ufw route allow放行转发。另外,在 Debian、Ubuntu 上 ufw 和 iptables-persistent 不能共存,安装后者会把 ufw 卸掉;用 ufw 的,NAT 规则按 ufw 文档写进/etc/ufw/before.rules的*nat段。 - 云服务器的安全组要放行中转机上的 10022、27015 等端口;目标服务器则只需对中转机的 IP 放行 22 和 27015。
方法二:用 realm 等用户态工具转发
iptables 只认 IP,目标是域名或者 IP 会变时不方便;用户态转发工具直接写“监听端口 → 目标地址”,配置更直观。realm 是一个开源的轻量转发程序,支持 TCP 和 UDP,目标可以写域名。从项目的 GitHub Releases 页面下载对应架构的压缩包,解压后把 realm 放进 /usr/local/bin,然后写配置文件 /etc/realm/config.toml:
[log]
level = "warn"
[network]
no_tcp = false
use_udp = true
[[endpoints]]
listen = "0.0.0.0:10022"
remote = "198.51.100.20:22"
[[endpoints]]
listen = "0.0.0.0:27015"
remote = "game.example.com:27015"
再写一个 systemd 服务 /etc/systemd/system/realm.service,让它开机自启、异常退出后自动拉起:
[Unit]
Description=realm port forwarding
After=network-online.target
Wants=network-online.target
[Service]
ExecStart=/usr/local/bin/realm -c /etc/realm/config.toml
Restart=on-failure
LimitNOFILE=1048576
[Install]
WantedBy=multi-user.target
systemctl daemon-reload
systemctl enable --now realm
ss -tulnp | grep realm # 确认 10022、27015 的 TCP 和 UDP 都在监听
用户态转发由程序自己与目标服务器建立新连接,不需要开内核转发,也不用写 SNAT。几种工具对比:
| 工具 | 工作位置 | 目标可写域名 | UDP | 传递用户真实 IP | 适合 |
|---|---|---|---|---|---|
| iptables / nftables | 内核 | 否 | 支持 | 否 | 固定 IP、追求低开销 |
| realm | 用户态 | 是 | 支持 | 可发送 PROXY protocol | 多端口、目标会变 |
| socat | 用户态 | 是 | 支持 | 否 | 临时测试,一条命令起一个转发 |
| Nginx stream | 用户态 | 是 | 支持 | 支持 PROXY protocol | 已经在用 Nginx,需要传真实 IP |
需要让目标服务器看到用户真实 IP 时,可以让转发端在每个 TCP 连接的开头附上 PROXY protocol 头:Nginx stream 在 server 段加 proxy_protocol on;,realm 在 [network] 里加 send_proxy = true。目标服务器上的程序也要能解析,以 Nginx 为例,监听写成 listen 443 ssl proxy_protocol;,再用 set_real_ip_from 中转机IP; 和 real_ip_header proxy_protocol; 把日志和程序看到的来源地址换成用户真实 IP。两端必须同时开启,只开一端会导致连接失败。
中转机的流量怎么算:每个字节过两次
每个字节都要经过中转机两次:从一侧收进来,再向另一侧发出去。假设一个游戏服务器每月给玩家下发 300 GB、玩家上传 100 GB(假设数字):
| 机器 | 入方向 | 出方向 | 只计出方向 | 进出合计 |
|---|---|---|---|---|
| 目标服务器 | 100 GB | 300 GB | 300 GB | 400 GB |
| 中转机 | 300 + 100 = 400 GB | 300 + 100 = 400 GB | 400 GB | 800 GB |
所以买中转机前先问清流量的计法:只计出方向的套餐,中转机的用量等于业务的上下行之和;进出都计的,是业务流量的两倍。线路优化的 VPS 往往带宽不大、流量单价高,适合承载游戏、远程桌面、SSH 这类流量小但怕丢包的业务;网页里的图片、安装包这类大流量内容,交给 CDN 或直连更合适。
带宽同理:中转机的端口速率就是业务的上限,目标服务器有 1 Gbps,中转机只有 30 Mbps,用户最多也只能跑到 30 Mbps。CPU 一般不是瓶颈,几十 Mbps 的转发,单核 VPS 上 iptables 几乎没有负担;用户态工具在包量很大时会多占一些 CPU,满载时用 top 看一眼即可。
转发不通时按这张表查
| 现象 | 常见原因 | 处理 |
|---|---|---|
连接超时,但 iptables -t nat -L -n -v 里 DNAT 规则的计数在涨 |
包已进到中转机:没做 SNAT,回包没经过中转机;或者 FORWARD 链、ufw 的转发策略把包丢了 | 补上 POSTROUTING 的 SNAT 或 MASQUERADE 规则,检查 FORWARD 默认策略和放行规则 |
nc -zv 203.0.113.10 10022 超时,DNAT 计数也不涨 |
包根本没到中转机,多是安全组没放行该端口 | 在云平台安全组里放行,并确认访问的是中转机的公网地址 |
| TCP 正常,游戏进不去 | 只写了 TCP 规则,或 realm 没开 use_udp,或服务商限制 UDP |
补 UDP 规则,问清服务商对 UDP 的策略 |
| 重启后转发失效 | 规则没有保存,ip_forward 只用 sysctl -w 临时开启 |
用 netfilter-persistent 保存(用 ufw 的写进 before.rules),参数写进 /etc/sysctl.d/ |
| 目标服务器日志里全是同一个 IP | 转发后看到的就是中转机地址,属正常现象 | 需要真实 IP 时改用支持 PROXY protocol 的方式 |
| 速度远低于预期 | 中转机端口带宽小,或中转机到目标这一段丢包 | 在中转机上单独测这一段,必要时换中转机位置 |
最后提醒两点。中转端口对全网开放,示例里的 10022 转发的是 SSH,任何人都能经它尝试登录目标服务器,所以要么只允许你自己的 IP 访问这个端口(在 DNAT 规则里加上 -s 你的IP),要么目标服务器只允许密钥登录;目标服务器上则只对中转机的 IP 放行业务端口。另外,中转只能用于合法用途,服务商发现滥用同样会停机处理。
常见问题
VPS 中转和 CDN 有什么区别?
CDN 在边缘节点缓存网页、图片等内容,用户多数请求不必回源;中转不缓存任何东西,每个数据包都要经中转机到达目标服务器。游戏、远程桌面、SSH 这类实时的 TCP、UDP 连接没法缓存,只能用中转;静态网站和大文件下载用 CDN 更合适。
中转能防 DDoS 吗?
不能。中转只是把源站 IP 藏在后面,攻击流量会打到中转机上,中转机被黑洞后业务同样中断。需要抗攻击时,中转机本身要用带防护的线路,或者把入口换成高防 IP。
系统默认用 nftables,文中的 iptables 命令还能用吗?
能。较新的 Debian、Ubuntu 里,iptables 命令默认是基于 nftables 的兼容版本(iptables-nft),规则实际写进 nftables,用法不变,执行 iptables -V 看到 nf_tables 字样即是。只是要固定用一套工具管理规则,一部分用 iptables 写、一部分直接写 nft 规则,排查时很难看清哪条在生效。