iptables: Wireguard VPN 接続の背後にあるサーバーに UDP および TCP ポートを転送する方法

iptables: Wireguard VPN 接続の背後にあるサーバーに UDP および TCP ポートを転送する方法

パブリック IP を持つ Debian bullseye を実行する VPS (KVM) サーバーがあります。そのサーバーでは Wireguard サーバーも実行しています。自宅には、Wireguard クライアントを備えた別のサーバー (NAT の背後) があり、これが私の VPS に接続されています。トンネルは稼働しており、Wireguard VPN 経由で適切に通信できることを意味します。

+----------------------------------+             +-------------------------------
| Homeserver (behind NAT)          |             | VPS (KVM) with public IP     |
| 192.168.1.10                     |             | 1.2.3.4                      |
|         +------------------------|             |--------------------+         |
|         | wg-homeserver          | - - - - - - | wg-vps             |         |
|         | 192.168.200.2          |             | 192.168.200.1      |         |
|         +------------------------|             |--------------------+         |
|                                  |             |                              |
+----------------------------------+             +------------------------------+

私のホームサーバーは、ポート(すべての IP アドレス)をリッスンする多数の Docker コンテナーを実行しているため、これらのポートは 192.168.1.0/24 からアクセスできます。ここで、VPS のパブリック IP アドレスで 1 つの TCP ポートと 1 つの UDP ポートを転送し、トラフィックを Wireguard リンク経由でホームサーバーの同じポートに転送する必要があります。

1.2.3.4:10000/tcp -> 192.168.200.2:10000/tcp
1.2.3.4:10001/udp -> 192.168.200.2:10001/udp

IP 転送は両方のマシンで有効になっています。つまり、cat /proc/sys/net/ipv4/ip_forwardが表示されます1

TCP ポートを転送するには、次のルールがあります。

iptables -A FORWARD -d 192.168.200.2/32 -i wg-vps -p tcp --dport 10000 -j ACCEPT
iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 10000 -j DNAT --to-destination 192.168.200.2:10000

しようとすると、ssh -p 10000 1.2.3.4によって記録されているパケットが表示されませんwireguard -i wg-vps。 他にもさまざまなことを試しましたが、何が間違っているのか、何が足りないのかがわかりません。

とにかく、UDP ポートに関しては、私はこのルールを作成しましたが、少し成功しました。

iptables -t nat -A PREROUTING -d 1.2.3.4/32 -i eth0 -p udp --dport 10001 -j DNAT --to-destination 192.168.200.2:10001

UDP テスト パケットを送信する方法は次のとおりです。

echo -n test | nc -4 -u 1.2.3.4 10001

これを実行すると、tcpdump -i wg-vpsVPS ログに次の内容が表示されます (4.5.6.7パブリック IP アドレス)。

11:35:47.497622 IP 4.5.6.7.43357 > 192.168.200.2.10001: UDP, length 4

これは、正しいことを実行しようとしているように見えます。パケットを取得し、宛先を に更新し192.168.200.2、それを Wireguard インターフェイス に配置しますwg-vps。しかしtcpdump -i wg-homeserver、私のホームサーバーでは、このパケットの到着は表示されません。

実際、watch ip -s link show wg-homeserverホームサーバーでそのポートにUDPパケットを送信するたびに、RXエラーが1ずつ増加することに気づきました。何かそこへはずっと到達しますが、それが何であれ、表示されずtcpdump、下のどこかでドロップされているように見えます。Wireguard リンク上の UDP と TCP はどちらも両方向で正常に動作するため、これは奇妙です。

私の理解では、tcpdumpiptables より前のパケットが表示されるので、パケットは Wireguard インターフェイスに書き込まれているように見えても、どこかでドロップされるのではないかと思います。

アップデート: さて、Wireguard ログを有効にする方法を見つけました:

echo module wireguard +p > /sys/kernel/debug/dynamic_debug/control

ログを追ってみると、dmesg --followWireguard が次の理由でパケットをドロップしているようです:

wireguard: wg-homeserver: Packet has unallowed src IP (4.5.6.7) from peer 20 (xxxxxx)

つまり、これは、送信元アドレスがリクエストの送信元からのオリジナルであるという事実を好まないことを意味していると思います。SNAT を実行したくないので、何らかの方法で、任意の送信元アドレスを許可するように教える必要があると思います。

AllowedIPsこれは私の Wireguard 構成のセクションの設定であることが判明しました[Peer]。これで問題は解決しました:

AllowedIPs = 0.0.0.0/0, ::0/0

これまで、セクションにあるものと同様のインターフェース マスクを設定していましたが[Interface]、これによってパケットの送信元アドレスが制限されることに気づいていませんでした。

ただし、これはすべてのトラフィックをハイジャックし、Wireguard リンク経由でルーティングしようとします。これは、ルートを追加してすべてのトラフィックを VPN 経由でリダイレクトする必要があると判断するためです。これは明らかに望ましいことでwg-quickAllowedIPsありませんが、幸いなことに解決策があります。セクションTable = offに追加すること[Interface]で、これを防ぐことができます。

答え1

送信パケットがホーム サーバーでどのようにルーティングされるかを理解するには、ルール テーブルを参照してください。wg-quick はいくつかのルールを追加します。

ip rule show

私の場合、wg-quick によって生成されたいくつかのルール (すべてのパケットを wg に転送する) を削除し、必要なポートを転送するルールを追加する必要がありました。上記のコマンドから wg テーブル番号を確認できます。

ip -4 rule add sport 80 table XXXXX
ip -4 rule add sport 443 table XXXXX

上記はしばらくは機能していました。しかし、DHCP リースの有効期限が切れたり、LAN ケーブルが切断されて再接続されたりすると、systemd-networkd はカスタム ルールを削除します。そのため、wg-quick を完全に削除し、systemd-networkd を使用して wg インターフェイスとルーティング ルールを構成しました。

関連情報