我有一個在 VPS (Debian 10) 上運行的 Minecraft 伺服器,但 VPS 太弱了,無法處理它,所以我想使用更強大的本地伺服器來運行它 (Ubuntu 22.04)。 VPS 託管 OpenVPN 伺服器,本地伺服器作為唯一客戶端進行連線。 VPS位於10.8.0.1,本地伺服器位於10.8.0.6(本地網路上的192.168.1.185)。
我使用 iptables 規則將 10.8.0.6:25565 的 tun0 VPN 封包轉送到本機伺服器的 IP。這工作正常:我可以從 VPS 查詢 Minecraft 伺服器。然後,我在 VPS 上設定相同的一組規則(當然交換了相關 IP),將連線從 vps_external_ip:25565 轉送到 10.8.0.6:25565。該規則將封包一路轉送到本機伺服器,但連線總是逾時。奇怪的是,來自 VPS -> 本機伺服器的工作連線和外部 -> VPS -> 本機伺服器的工作連線都不會增加任何 POSTROUTING MASQUERADE 規則的資料包計數器,但它們會增加 PREROUTING 規則。當存取 eth0:25565 上的 VPS 時,TCP/UDP 連線只是逾時,沒有連線被拒絕錯誤。
兩台機器上都啟用了 IPV4 轉發,並且我嘗試停用 UFW,但沒有成功。
我在兩台伺服器的 NAT POSTROUTE 上設定了日誌規則,但我不太確定如何解決該問題,因為我找不到任何問題。
POSTROUTE 日誌輸出 (iptables -t nat -I POSTROUTING -j LOG --log-prefix "NAT:" --log-level 7)
##### VPS
Apr 23 20:52:02 vpskernel: [1552376.122382] NAT1:IN= OUT=tun0 SRC=<my ip> DST=10.8.0.6 LEN=48 TOS=0x08 PREC=0x20 TTL=114 ID=21284 DF PROTO=TCP SPT=1806 DPT=25565 WINDOW=64240 RES=0x00 SYN URGP=0
#### Local server
<could not find any relevant logs grepping /var/log/kern.log for NAT1 and there were no logs at all for tun0>
我為每個伺服器使用 /etc/ufw/before.rules 來設定 iptables 規則。
VPS /etc/ufw/before.rules:
# START OPENVPN RULES
# NAT table rules
*nat
:PREROUTING ACCEPT [0:0]
:POSTROUTING ACCEPT [0:0]
# Allow traffic from OpenVPN client to eth0
-A POSTROUTING -s 10.8.0.0/8 -o eth0 -j MASQUERADE
# END OPENVPN RULES
-A PREROUTING -i eth0 -d <vps external IP> -p tcp --dport 25565 -j DNAT --to-destination 10.8.0.6:25565
-A PREROUTING -i eth0 -d <vps external IP> -p udp --dport 25565 -j DNAT --to-destination 10.8.0.6:25565
-A POSTROUTING -s 10.0.0.0/8 ! -d 10.0.0.0/8 -j MASQUERADE
COMMIT
本機伺服器/etc/ufw/before.rules:
*nat
:PREROUTING ACCEPT [0:0]
:POSTROUTING ACCEPT [0:0]
-A PREROUTING -i tun0 -d 10.8.0.6 -p tcp --dport 25565 -j DNAT --to-destination 192.168.1.185:25565
-A PREROUTING -i tun0 -d 10.8.0.6 -p udp --dport 25565 -j DNAT --to-destination 192.168.1.185:25565
# setup routing
-A POSTROUTING -s 192.168.1.0/24 ! -d 192.168.1.0/24 -j MASQUERADE
COMMIT
PREROUTING 規則正在運行,但 POSTROUTING 規則計數器沒有遞增。
我在 25565 上運行 tcpdump 進行調試。我看到資料包傳入,但在外部連接時在任何介面上都沒有看到任何返回。當直接從 VPS 查詢時,我看到本機伺服器在 tun0 上回應。看起來問題是本地伺服器試圖直接回應 en01 上的 IP,而不是 tun0 上的 VPS,但我不知道如何解決這個問題。
VPS tcpdump:
# eth 0
21:43:39.972647 IP my_ip.2729 > vps_ip.25565: Flags [S], seq 1483515507, win 64240, options [mss 1460,nop,nop,sackOK], length 0
# tun0
21:43:39.972739 IP my_ip.2729 > 10.8.0.6.25565: Flags [S], seq 1483515507, win 64240, options [mss 1460,nop,nop,sackOK], length 0
本機伺服器 tcpdump:
#tun0
21:43:39.972566 IP my_ip.2729 > 10.8.0.6.25565: Flags [S], seq 1483515507, win 64240, options [mss 1356,nop,nop,sackOK], length 0
#en01
21:43:39.972618 IP 10.8.0.6.25565 > my_ip.2729: Flags [S.], seq 2141764446, ack 1483515508, win 64240, options [mss 1460,nop,nop,sackOK], length 0
答案1
終於想通了。大多數線上連接埠轉送指南都有 POSTROUTING 規則,該規則不適用於 OpenVPN(或我的情況)。我必須為除本地 IP 以外的任何內容制定後路由規則,以將其重寫為 tun0 VPS IP,而不是允許本地 IP 作為來源且目標不是本地 IP。
VPS /etc/ufw/before.rules(交換 s 和 d):
-A POSTROUTING -d 10.0.0.0/8 ! -s 10.0.0.0/8 -j MASQUERADE -t nat
此外,僅在 VPS 上需要 POSTROUTING 規則。