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 規則,排查時很難看清哪條在生效。