Ubuntu 16.04にlibvirtをそのままインストールすると、その範囲にサービスを提供するdnsmasqインスタンスであるvirbr0仮想ブリッジが192.168.122.0/24に作成され、基本的なNATマスカレードが設定されます。
その下に、仮想化ソフトウェアが使用するタップインターフェイスを作成しました。ソフトウェア自体はインターネットとネットワークの残りの部分に完全にアクセスできるため、マスカレードは適切に機能しています。また、ホストから仮想化ソフトウェアのsshポートにアクセスするには、そのソフトウェアが要求するIPアドレスを使用します。したがって、「箱から出して」ルーティングテーブルは一般的に正しいと思います。
私がやりたいのは、外部からこのソフトウェア、そして一般的にはホストシステムへのインバウンドssh接続をポートフォワードすることです。これで、ホストシステムにはもちろんsshがあり、それが機能する必要があります。そのため、ポート2022などの別のポートを使用しようとしています。
IptablesでDNATルールを作成して、ポート2022のインバウンドトラフィックをポート22のソフトウェアのIPアドレスに転送しました。外部からsshインしようとすると、宛先に到達できなくなります(例:以下のコンピューターA)。アドレス変換が適切に行われているように見えますが、iptablesの「FORWARD」ステップに移動した直後に、アウトバウンドの到達不能ICMPパケットを取得し始めます。
どうすればいいのか困っています。いくつかのSNATルールを試しましたが、失敗したか、それは問題ではありません。誰かがこれについてアイデアを持っていますか?
更新:tap0のWiresharkは、転送されたパケットを受信したことを示していません。パケットを返すものはすべて、仮想化ソフトウェアとは関係ありません。
これが私のネットワークの写真です:
----------
| Internet |
----------
|
|
--------
| Router | 10.211.255.1
--------
|
|
____________|_______________
| |
---------- ---------
| | | enp0s5 | 10.211.255.4
| Computer | 10.211.255.2 | Host | 192.168.122.1
| A | | virbr0 |
---------- ---------
|
| LAN NAT 192.168.122.0/24
|
----------
| tap0 |
| Guest OS | 192.168.122.118
| |
----------
これが私のIPテーブルのルールです:
Chain INPUT (policy ACCEPT)
target prot opt source destination
LOG all -- anywhere anywhere LOG level debug prefix "INTRACE: "
ACCEPT udp -- anywhere anywhere udp dpt:domain
ACCEPT tcp -- anywhere anywhere tcp dpt:domain
ACCEPT udp -- anywhere anywhere udp dpt:bootps
ACCEPT tcp -- anywhere anywhere tcp dpt:bootps
Chain FORWARD (policy ACCEPT)
target prot opt source destination
LOG all -- anywhere anywhere LOG level debug prefix "FORTRACE: "
ACCEPT all -- anywhere 192.168.122.0/24 ctstate RELATED,ESTABLISHED
ACCEPT all -- 192.168.122.0/24 anywhere
ACCEPT all -- anywhere anywhere
REJECT all -- anywhere anywhere reject-with icmp-port-unreachable
REJECT all -- anywhere anywhere reject-with icmp-port-unreachable
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
LOG all -- anywhere anywhere LOG level debug prefix "OUTTRACE: "
ACCEPT udp -- anywhere anywhere udp dpt:bootpc
NAT tables:
Chain PREROUTING (policy ACCEPT)
target prot opt source destination
LOG tcp -- anywhere anywhere tcp dpt:2022 LOG level debug prefix "NATPTRACE: "
DNAT tcp -- anywhere anywhere tcp dpt:2022 to:192.168.122.118:22
Chain INPUT (policy ACCEPT)
target prot opt source destination
LOG all -- anywhere anywhere LOG level debug prefix "NATITRACE: "
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
LOG all -- anywhere anywhere LOG level debug prefix "NATOTRACE: "
Chain POSTROUTING (policy ACCEPT)
target prot opt source destination
LOG all -- anywhere anywhere LOG level debug prefix "NATQTRACE: "
SNAT tcp -- anywhere anywhere tcp spt:ssh to::2022
RETURN all -- 192.168.122.0/24 base-address.mcast.net/24
RETURN all -- 192.168.122.0/24 broadcasthost.localdomain
MASQUERADE tcp -- 192.168.122.0/24 !192.168.122.0/24 masq ports: 1024-65535
MASQUERADE udp -- 192.168.122.0/24 !192.168.122.0/24 masq ports: 1024-65535
MASQUERADE all -- 192.168.122.0/24 !192.168.122.0/24
最後に、これは上記のルールでsyslogに表示される例です。
Oct 20 09:49:15 ubuntu kernel: [85149.812291] RAWPTRACE: IN=enp0s5 OUT= MAC=00:1c:42:3a:00:df:00:1c:42:00:00:08:08:00 SRC=10.211.55.2 DST=10.211.55.4 LEN=64 TOS=0x00 PREC=0x00 TTL=64 ID=40132 DF PROTO=TCP SPT=53245 DPT=2022 WINDOW=65535 RES=0x00 SYN URGP=0
Oct 20 09:49:15 ubuntu kernel: [85149.812318] MGPTRACE: IN=enp0s5 OUT= MAC=00:1c:42:3a:00:df:00:1c:42:00:00:08:08:00 SRC=10.211.55.2 DST=10.211.55.4 LEN=64 TOS=0x00 PREC=0x00 TTL=64 ID=40132 DF PROTO=TCP SPT=53245 DPT=2022 WINDOW=65535 RES=0x00 SYN URGP=0
Oct 20 09:49:15 ubuntu kernel: [85149.812326] NATPTRACE: IN=enp0s5 OUT= MAC=00:1c:42:3a:00:df:00:1c:42:00:00:08:08:00 SRC=10.211.55.2 DST=10.211.55.4 LEN=64 TOS=0x00 PREC=0x00 TTL=64 ID=40132 DF PROTO=TCP SPT=53245 DPT=2022 WINDOW=65535 RES=0x00 SYN URGP=0
Oct 20 09:49:15 ubuntu kernel: [85149.812336] MGFTRACE: IN=enp0s5 OUT=virbr0 MAC=00:1c:42:3a:00:df:00:1c:42:00:00:08:08:00 SRC=10.211.55.2 DST=192.168.122.118 LEN=64 TOS=0x00 PREC=0x00 TTL=63 ID=40132 DF PROTO=TCP SPT=53245 DPT=22 WINDOW=65535 RES=0x00 SYN URGP=0
Oct 20 09:49:15 ubuntu kernel: [85149.812340] FORTRACE: IN=enp0s5 OUT=virbr0 MAC=00:1c:42:3a:00:df:00:1c:42:00:00:08:08:00 SRC=10.211.55.2 DST=192.168.122.118 LEN=64 TOS=0x00 PREC=0x00 TTL=63 ID=40132 DF PROTO=TCP SPT=53245 DPT=22 WINDOW=65535 RES=0x00 SYN URGP=0
Oct 20 09:49:15 ubuntu kernel: [85149.812354] RAWOTRACE: IN= OUT=enp0s5 SRC=10.211.55.4 DST=10.211.55.2 LEN=92 TOS=0x00 PREC=0xC0 TTL=64 ID=50608 PROTO=ICMP TYPE=3 CODE=3 [SRC=10.211.55.2 DST=192.168.122.118 LEN=64 TOS=0x00 PREC=0x00 TTL=63 ID=40132 DF PROTO=TCP SPT=53245 DPT=22 WINDOW=65535 RES=0x00 SYN URGP=0 ]
Oct 20 09:49:15 ubuntu kernel: [85149.812357] MGOTRACE: IN= OUT=enp0s5 SRC=10.211.55.4 DST=10.211.55.2 LEN=92 TOS=0x00 PREC=0xC0 TTL=64 ID=50608 PROTO=ICMP TYPE=3 CODE=3 [SRC=10.211.55.2 DST=192.168.122.118 LEN=64 TOS=0x00 PREC=0x00 TTL=63 ID=40132 DF PROTO=TCP SPT=53245 DPT=22 WINDOW=65535 RES=0x00 SYN URGP=0 ]
Oct 20 09:49:15 ubuntu kernel: [85149.812361] OUTTRACE: IN= OUT=enp0s5 SRC=10.211.55.4 DST=10.211.55.2 LEN=92 TOS=0x00 PREC=0xC0 TTL=64 ID=50608 PROTO=ICMP TYPE=3 CODE=3 [SRC=10.211.55.2 DST=192.168.122.118 LEN=64 TOS=0x00 PREC=0x00 TTL=63 ID=40132 DF PROTO=TCP SPT=53245 DPT=22 WINDOW=65535 RES=0x00 SYN URGP=0 ]
Oct 20 09:49:15 ubuntu kernel: [85149.812364] MGQTRACE: IN= OUT=enp0s5 SRC=10.211.55.4 DST=10.211.55.2 LEN=92 TOS=0x00 PREC=0xC0 TTL=64 ID=50608 PROTO=ICMP TYPE=3 CODE=3 [SRC=10.211.55.2 DST=192.168.122.118 LEN=64 TOS=0x00 PREC=0x00 TTL=63 ID=40132 DF PROTO=TCP SPT=53245 DPT=22 WINDOW=65535 RES=0x00 SYN URGP=0 ]
問題はFORWARDルールにありました。それらを設定しなかったので、iptables --list
からの出力を誤って解釈していました。
そのリストでは、ルール4は次のようになっています。
ACCEPT all -- anywhere anywhere
これは、どこからでもどこにでもバインドされたすべての着信パケットを受け入れるように見えます。
ただし、iptables -S
を見ると、ルール4は実際には次のようになっています。
-A FORWARD -i virbr0 -o virbr0 -j ACCEPT
これは、vibr0宛てのenp0s5から着信するパケットとは一致しません。したがって、それはREJECTルール5にヒットしていました。これは、実際にはvibr0宛てのすべてのパケットの拒否でした。
私が学んだ教訓は、iptables --list
の出力を信頼するのではなく、何かがおかしいと思われるときにiptables -S
の出力をチェックすることです。