2層のポート転送用にiptablesを適切に構成する: 外部サーバーをVPN経由でローカルサーバーに接続する

2層のポート転送用にiptablesを適切に構成する: 外部サーバーをVPN経由でローカルサーバーに接続する

私は VPS (Debian 10) で Minecraft サーバーを実行していましたが、VPS は処理するには小さすぎたため、より強力なローカル サーバー (Ubuntu 22.04) を使用して実行したいと考えました。VPS は OpenVPN サーバーをホストしており、ローカル サーバーは唯一のクライアントとして接続します。VPS は 10.8.0.1 にあり、ローカル サーバーは 10.8.0.6 (ローカル ネットワーク上の 192.168.1.185) にあります。

10.8.0.6:25565 の tun0 VPN パケットをローカル サーバーの IP に転送するために、iptables ルールを使用しました。これは問題なく動作しており、VPS から Minecraft サーバーにクエリを実行できます。次に、VPS で同じルール セット (関連する IP は当然入れ替えます) を設定して、vps_external_ip:25565 から 10.8.0.6:25565 への接続を転送します。このルールはパケットをローカル サーバーまで転送しますが、接続は常にタイムアウトします。奇妙なことに、VPS -> ローカル サーバーからの接続も、外部 -> VPS -> ローカル サーバーからの接続も、POSTROUTING MASQUERADE ルールのパケット カウンターを増加させませんが、PREROUTING ルールでは増加します。VPS の eth0:25565 に到達すると、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 で応答しているのがわかります。問題は、ローカル サーバーが tun0 の VPS ではなく en01 の IP に直接応答しようとしていることのようですが、これを修正する方法がわかりません。

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

ついに解決しました。オンラインのポート転送ガイドのほとんどには、OpenVPN (または私の状況) では機能しない POSTROUTING ルールがありました。ローカル IP を、ローカル IP ではない宛先のソースとして許可する代わりに、ローカル IP 以外のすべての postrouting ルールを tun0 VPS 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

さらに、POSTROUTING ルールは VPS 上でのみ必要でした。

関連情報