伺服器租用與託管

VPS 中轉是什麼意思:連接埠轉發的原理、用途與配置

VPS 中轉就是在使用者和目標伺服器之間加一台線路更好的 VPS:使用者連中轉機的連接埠,中轉機把流量原樣轉給目標伺服器,回包也經它返回。它不會讓伺服器本身變快,只是用兩段品質好的線路替換一段繞路、丟包的直連,所以先測三段線路,再決定值不值得中轉。

作者 頂聯產品團隊發布於 7 分鐘閱讀

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

想看看在你的機房裡怎麼用?

從一次產品示範開始,梳理你的業務鏈路。

查看價格
服務熱線 400-112-2951

讓我們聊聊你的 IDC 業務

掃碼新增企業微信,預約產品示範或申請試用。

Toplink 企業微信二維碼

長按儲存或使用企業微信 / 微信掃描

也可致電
400-112-2951
Telegram
@TopLink88