VPS 中轉架設:nftables DNAT 與 GOST 端口轉發

VPS 中轉架設:nftables DNAT 與 GOST 端口轉發

Jason Chen
2026年10月14日· 8 分鐘讀完

VPS 中轉是在現有代理伺服器前面多加一跳:客戶端先連接中轉 VPS,中轉再把 TCP 及 UDP 資料原封不動交給落地伺服器,過程中不作任何解密。你可以在核心以 nftables DNAT 加來源地址轉換實現,亦可以在用戶空間以 GOST 轉發;兩種做法都只可用於你擁有或已獲授權的伺服器之間。

關鍵要點

  • 中轉只改變入口地址,不改變出口:網站看到的仍是落地伺服器。
  • nftables DNAT 需要啟用 IP 轉發,並配合相應的 SNAT 或 masquerade 規則,否則回應封包會走錯路徑。
  • GOST 在應用層轉發,毋須核心轉發,但長時間的 UDP 工作階段需要 keepAlive。
  • 兩種方式都會令落地伺服器看到中轉的地址,而不是每個客戶端的地址。
  • 客戶端的 TLS、REALITY 或密鑰設定保持不變,只改伺服器地址及端口。

本文按文末官方來源整理,未完成完整端到端實測。指令假設兩部伺服器均為 Ubuntu 24.04 LTS,使用發行版內置的 nftables 及 GOST v3.3.0;內容描述的是文件所載行為,而非實測結果。先參考自建擁有權及復原清單,確認每部伺服器由誰管理。

VPS 中轉何時有用,何時沒有用?

當客戶端連往某個數據中心比另一個穩定,或你想更換公開入口地址而不重建代理本身時,中轉便派上用場。它不是第二層加密,亦不會對落地伺服器隱藏流量;這類需求較接近多跳鏈路,每一跳各自運行協議。

轉發端口亦等於公開該端口。開放任何端口前,先了解入站端口轉發如何暴露服務,並決定允許哪些來源地址。如果落地伺服器本身已經緩慢或負載過高,中轉也無補於事:先按自建伺服器變慢的排查方法量度清楚。如果維護兩部伺服器、兩套防火牆及兩套升級時間表超出你的實際需要,加這一跳之前請先把這份工作量與託管 VPN 比較一下。

只使用你自行管理的伺服器,確保控制台存取不依賴被轉發的端口,SSH 主機密鑰亦經帶外核實。不要使用來歷不明的一鍵中轉腳本:它們往往整體替換防火牆規則,事後亦無從查證改動了甚麼。

nftables DNAT 還是 GOST:應選哪種中轉方式?

問題nftables DNAT 端口轉發GOST 端口轉發
運行位置Linux 核心 netfilter,附連接追蹤中轉上的一個用戶空間程序
是否需要 ip_forward需要不需要
落地看到的來源經 SNAT 或 masquerade 後的中轉地址中轉地址,因為 GOST 自行建立新連接
UDP 處理每個流一條 conntrack 記錄UDP 監聽器,附 keepAlive 及 ttl 選項
額外功能計數器、比對條件,毋須額外常駐程式多個目標、揀選策略、可選的轉發鏈
主要故障點缺少 SNAT,或被 forward 政策丟棄程序停止,或 UDP 通道過早關閉

nftables 的有狀態 NAT 在一個流的首個封包上建立綁定,其後的封包沿用這個綁定。[1] GOST 的 TCP 及 UDP 轉發服務在中轉接受連接,再向每個目標節點建立新連接;它亦可用 -F 讓流量經過轉發鏈中的一跳,但下一部伺服器需要相應的服務。[2] 本文兩種方式都只作直接轉發,每個端口只選一種。

步驟 1:記錄落地伺服器資料並規劃端口

示例中,中轉的公網網絡介面是 eth0,地址 198.51.100.10;落地伺服器是 203.0.113.30,上面已有代理在 TCP 及 UDP 443 監聽。請把這些值全部換成你的實際資料,並在加入中轉前確認直連落地服務正常。

在中轉上揀選沒被佔用的端口:這裏 nftables 用 8443,GOST 用 8444,方便比較兩種方式。以 sudo ss -lntup 檢查。以 sudo nft list ruleset > ~/relay-ruleset-before.nft 保存中轉現有規則,並記下正在使用的防火牆管理工具,例如 UFW 或 Docker。

如果落地伺服器的防火牆只放行已知客戶端地址,請為中轉地址放行 TCP 及 UDP 443。中轉啟用後,落地伺服器會把 198.51.100.10 視為所有經中轉客戶端的對端,按客戶端地址設定的限制及日誌將無法區分用戶。

步驟 2:啟用轉發並加入 nftables DNAT 與 SNAT

核心轉發預設關閉(net.ipv4.ip_forward 為 0)。[3] 建立 /etc/sysctl.d/90-relay-forward.conf,內容為 net.ipv4.ip_forward = 1,然後執行 sudo sysctl --system,再以 sysctl net.ipv4.ip_forward 確認。核心文件提到,更改這個值會把各網絡介面的設定參數重設為預設,因此之後要覆核你自訂過的介面設定。[3]

把以下規則儲存為 /etc/nftables-relay/relay-nat.nft:

table ip relay_nat
delete table ip relay_nat

table ip relay_nat {
    chain prerouting {
        type nat hook prerouting priority -100; policy accept;
        iifname "eth0" tcp dport 8443 counter dnat to 203.0.113.30:443
        iifname "eth0" udp dport 8443 counter dnat to 203.0.113.30:443
    }
    chain postrouting {
        type nat hook postrouting priority 100; policy accept;
        ip daddr 203.0.113.30 tcp dport 443 counter masquerade
        ip daddr 203.0.113.30 udp dport 443 counter masquerade
    }
}

頭兩行先建立再刪除這張表,所以重複載入檔案時只會替換 relay_nat,不會影響其他表。不要加入 flush ruleset:它會連同 UFW、Docker 或服務商代理程式的規則一併清除。prerouting 鏈改寫目的地址,postrouting 鏈把來源地址改為中轉地址,落地伺服器便會回應中轉,再由 conntrack 把回應轉換回客戶端。[1] 缺少這一步 SNAT,落地伺服器會直接把回應送往客戶端,與客戶端原本的連接對不上。

先以 sudo nft -c -f /etc/nftables-relay/relay-nat.nft 檢查語法,再以 sudo nft -f 加同一路徑載入。

在過濾規則中放行轉發流量

NAT 規則不能代替過濾規則。在 nftables 中,一條基礎鏈的 accept 並非最終裁決,同一掛載點上另一條基礎鏈的 drop 仍然生效。[4] 執行 sudo nft list ruleset | grep -B2 -A4 'hook forward'。如果某條 forward 鏈是 policy drop,便在管理該鏈的工具中加入放行。以 UFW 為例,使用 sudo ufw route allow proto tcp to 203.0.113.30 port 443,再加一條 proto udp 的同類規則,而不是另建一張互相衝突的表。

步驟 3:或者以 GOST 轉發同一服務

從 GOST 官方 v3.3.0 發佈頁下載 Linux 版本,查閱發佈說明及官方校驗碼,安裝為 /opt/gost/v3.3.0/gost,擁有者 root,權限 0755。[5] GOST 讀取以 -C 傳入的 YAML 或 JSON 檔案。[6] 把以下內容儲存為 /etc/gost-relay/gost.yml:

services:
- name: relay-tcp
  addr: :8444
  handler:
    type: tcp
  listener:
    type: tcp
  forwarder:
    nodes:
    - name: landing-tcp
      addr: 203.0.113.30:443
- name: relay-udp
  addr: :8444
  handler:
    type: udp
  listener:
    type: udp
    metadata:
      keepAlive: true
      ttl: 30s
  forwarder:
    nodes:
    - name: landing-udp
      addr: 203.0.113.30:443

keepAlive 為 false 時,GOST 的 UDP 監聽器在傳回回應後即關閉通道,這適合單次 DNS 查詢,卻會令需要大量往返封包的 QUIC 類代理中斷。設為 keepAlive: true 後,閒置通道每隔 ttl 檢查一次,最多經過兩個閒置週期便關閉。[2] readBufferSize 預設為 4096 位元組,較大的 UDP 封包會被截斷,除非你的協議會傳送更大的資料包,否則保持預設。

建立不可登入的帳戶 gost-relay,再編寫一個 systemd 單元,以該帳戶執行 /opt/gost/v3.3.0/gost -C /etc/gost-relay/gost.yml,並設定 Restart=on-failure 及 NoNewPrivileges=true。8444 端口高於 1024,程序毋須額外權限。在中轉的入站防火牆放行 TCP 及 UDP 8444;GOST 流量對中轉而言屬本機流量,毋須 forward 規則。

步驟 4:讓客戶端連接中轉

複製客戶端可用的設定,只把伺服器地址改為 198.51.100.10,端口改為 8443(nftables)或 8444(GOST)。TLS 伺服器名稱、REALITY 參數、UUID 及密鑰全部保持原樣。兩種方式都不會終結 TLS,所以客戶端仍然端到端驗證落地伺服器的證書或 REALITY 參數。

如果原設定以落地伺服器的 IP 地址作為 TLS 名稱,經中轉後依然可用,因為名稱驗證針對證書,而非 socket 地址。以下檢查全部通過前,請保留直連設定作後備。

如何驗證中轉路徑及回程流量?

檢查方法預期現象不符時的處理
經中轉設定向你控制的端點發出請求取得預期回應先測直連設定,再查中轉的監聽及規則
在中轉執行 sudo nft list table ip relay_natDNAT 及 masquerade 規則的計數上升DNAT 無計數:介面或端口錯誤;有 DNAT 無 masquerade:檢查 ip daddr
在落地伺服器執行 sudo ss -tn state established '( sport = :443 )'對端顯示為中轉地址顯示客戶端地址:缺少 SNAT,或流量繞過了中轉
經中轉設定執行一項 UDP 工作UDP 計數上升,工作階段保持GOST 確認 keepAlive: true,nftables 檢查 UDP 規則
只停止 gost-relay,再連接 8444新連接失敗,8443 不受影響8444 被其他程序佔用,或客戶端用錯設定
以直連設定連接落地伺服器可用,或在你限制只許中轉存取時被拒絕按你的規劃調整落地防火牆

經中轉設定開啟 IP 地址查詢工具。它應顯示落地伺服器的出口地址,而不是中轉地址,因為中轉只承載入站一段。日後如建立每一跳各自運行代理協議的鏈路,請按 Xray 代理鏈逐跳驗證方法檢查,而不是用這張表。

如何持久化、回退及清理?

要在開機時載入 nftables 檔案,可編寫一個擁有者為 root 的小型一次性單元 relay-nat.service:在 network-online.target 之後執行 /usr/sbin/nft -f /etc/nftables-relay/relay-nat.nft,設定 RemainAfterExit=yes,並以 ExecStop=/usr/sbin/nft delete table ip relay_nat 停止。啟用後在維護時段重新啟動,再重複計數器及對端檢查。sysctl 檔案已令轉發持久生效。只有保留 GOST 方式時才啟用 gost-relay。

回退由客戶端開始:切回直連設定,以一次新請求確認。在中轉執行 sudo systemctl disable --now relay-nat gost-relay,刪除你加入的 UFW route 或入站規則;如再無其他用途需要轉發,刪除 /etc/sysctl.d/90-relay-forward.conf 後執行 sudo sysctl --system。把 sudo nft list ruleset 與保存的副本比對。落地伺服器上為中轉而設的放行規則最後才刪。

總結

  • 中轉只移動入口,落地伺服器仍是出口,也不會多出新的解密環節。
  • nftables 需要轉發、DNAT、SNAT,以及與你的防火牆工具一致的 forward 放行。
  • GOST 毋須核心轉發,但必須讓 UDP 通道在長工作階段中保持開啟。
  • 棄用直連設定前,核對計數器、落地端對端地址、UDP 及出口地址。

常見問題

VPS 中轉會為代理流量額外加密嗎?

不會。兩種方式都只轉發封包或資料流,不作解密,也不加新的加密層。加密仍然來自客戶端與落地伺服器之間運行的代理協議本身。

為何只設定 DNAT 時連接會卡住?

因為落地伺服器會把回應送往客戶端的原始地址,而不是送回中轉。加入 SNAT 或 masquerade 後,回應才會經中轉的連接追蹤返回客戶端。

同一部中轉可以同時使用 GOST 及 nftables 嗎?

可以,像本文般使用不同端口即可。不要讓兩種方式指向同一個中轉端口,否則 DNAT 規則會先截走封包,GOST 根本收不到這些連接。

落地伺服器還能看到我真實的客戶端地址嗎?

在這兩種設定下看不到。落地伺服器看到的都是中轉地址,所以它上面按客戶端地址設定的限制及日誌都會失去這部分資料。

GOST 的 UDP 轉發適合 QUIC 類代理嗎?

可以,前提是 UDP 監聽器能讓通道保持開啟。把 keepAlive 設為 true,並設定合適的 ttl,然後確認長時間工作階段經中轉後不會中斷。

中轉能令緩慢的落地伺服器變快嗎?

單靠中轉不行。它可以改變客戶端到達入口的線路,但吞吐量仍受落地伺服器的頻寬、處理器負載及網絡擠塞限制,需要分別排查。

怎樣移除中轉而不破壞其他防火牆規則?

只刪除 relay_nat 表、GOST 服務及你自己加入的那幾條放行規則。不要清空整個規則集,否則其他工具管理的規則也會一併消失。

免責聲明: 本文僅供一般資訊參考,不構成法律、技術或其他專業建議。我們不保證內容的準確性、完整性或時效性。

來源:

  1. nftables wiki: Performing Network Address Translation (NAT) — https://wiki.nftables.org/wiki-nftables/index.php/Performing_Network_Address_Translation_(NAT)
  2. GOST: Port forwarding — https://gost.run/en/tutorials/port-forwarding/
  3. Linux kernel documentation: IP sysctl — https://docs.kernel.org/networking/ip-sysctl.html
  4. nftables wiki: Configuring chains — https://wiki.nftables.org/wiki-nftables/index.php/Configuring_chains
  5. GOST release v3.3.0 — https://github.com/go-gost/gost/releases/tag/v3.3.0
  6. GOST: Command line reference — https://gost.run/en/reference/configuration/cmd/

Sources checked 2026 年 10 月 14 日。

延伸閱讀:

開啟 3 天免費試用

註冊即可免費體驗全部高級功能。

*只限新用戶;每位用戶只可獲得一次試用。

VPS 中轉架設:nftables DNAT 與 GOST 端口轉發 | AethoVPN