
私がやりたいこと
Debian Stretch GNU/Linux マシンを設定して、ネットワーク インターフェイス間で IP パケットをルーティングしたいと思います。
コンテクスト
これらは私の Debian ボックスと、近々ルーターになる予定のネットワーク インターフェイスです。
索引 | インターフェース名 | ip |
---|---|---|
1 | エンプ2s0 | 192.168.23.91/24 |
2 | エンクス00e04c360e75 | 192.168.1.1/24 |
3 | エンクス000ec667a74a | 192.168.2.2/24 |
sysctl net.ipv4.ip_forward
を返す1
ため、ルーティングが有効になります。cat /proc/sys/net/ipv4/conf/*/rp_filter
s以外は何も返しません0
。したがって、逆パス フィルタリングは無効になります。(これは、私が見つけた他のいくつかの質問の懸念の原因でした。)
ルーティング テーブルは次のようになります。
$ sudo route -nn
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
0.0.0.0 192.168.23.254 0.0.0.0 UG 100 0 0 enp2s0
169.254.0.0 0.0.0.0 255.255.0.0 U 1000 0 0 enp2s0
172.17.0.0 0.0.0.0 255.255.0.0 U 0 0 0 docker0
192.168.1.0 0.0.0.0 255.255.255.0 U 101 0 0 enx00e04c360e75
192.168.2.0 0.0.0.0 255.255.255.0 U 102 0 0 enx000ec667a74a
192.168.23.0 0.0.0.0 255.255.255.0 U 100 0 0 enp2s0
以下の作品
NIC 2 に接続されたデバイス ( 192.168.1.111
) から、NIC 2 ( 192.168.1.1
) と NIC 3 ( 192.168.2.2
) の両方に ping を実行できます。
tcpdump
私の Debian ルーターの出力は予想どおりです:
$ sudo tcpdump -i enx00e04c360e75 icmp -n
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on enx00e04c360e75, link-type EN10MB (Ethernet), capture size 262144 bytes
18:10:51.919808 IP 192.168.1.111 > 192.168.1.1: ICMP echo request, id 25404, seq 17, length 64
18:10:51.919863 IP 192.168.1.1 > 192.168.1.111: ICMP echo reply, id 25404, seq 17, length 64
18:10:52.920019 IP 192.168.1.111 > 192.168.1.1: ICMP echo request, id 25404, seq 18, length 64
18:10:52.920130 IP 192.168.1.1 > 192.168.1.111: ICMP echo reply, id 25404, seq 18, length 64
18:10:53.920808 IP 192.168.1.111 > 192.168.1.1: ICMP echo request, id 25404, seq 19, length 64
18:10:53.920895 IP 192.168.1.1 > 192.168.1.111: ICMP echo reply, id 25404, seq 19, length 64
[...]
18:11:03.408546 IP 192.168.1.111 > 192.168.2.2: ICMP echo request, id 25916, seq 0, length 64
18:11:03.408622 IP 192.168.2.2 > 192.168.1.111: ICMP echo reply, id 25916, seq 0, length 64
18:11:04.405006 IP 192.168.1.111 > 192.168.2.2: ICMP echo request, id 25916, seq 1, length 64
18:11:04.405061 IP 192.168.2.2 > 192.168.1.111: ICMP echo reply, id 25916, seq 1, length 64
18:11:05.405147 IP 192.168.1.111 > 192.168.2.2: ICMP echo request, id 25916, seq 2, length 64
18:11:05.405201 IP 192.168.2.2 > 192.168.1.111: ICMP echo reply, id 25916, seq 2, length 64
以下は機能しません
NIC 2 経由で接続されたデバイスから、NIC 1 経由でアクセス可能なホストに ping できません。
tcpdump
私の Debian ボックスで実行すると、NIC 2 に着信パケットが表示されます。
$ sudo tcpdump -i enx00e04c360e75 icmp -n
listening on enx00e04c360e75, link-type EN10MB (Ethernet), capture size 262144 bytes
18:11:31.837778 IP 192.168.1.111 > 193.99.144.80: ICMP echo request, id 36668, seq 4, length 64
18:11:32.838830 IP 192.168.1.111 > 193.99.144.80: ICMP echo request, id 36668, seq 5, length 64
18:11:33.838249 IP 192.168.1.111 > 193.99.144.80: ICMP echo request, id 36668, seq 6, length 64
[...]
しかし、NIC 1 から送信されることはありません。
$ sudo tcpdump -i enp2s0 icmp -n
listening on enp2s0, link-type EN10MB (Ethernet), capture size 262144 bytes
[nothing]
Debian ルーター ボックスから直接 ping を発行すると、tcpdump
予想どおりの結果になります。
$ sudo tcpdump -i enp2s0 icmp -n
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on enp2s0, link-type EN10MB (Ethernet), capture size 262144 bytes
18:35:16.577795 IP 192.168.23.91 > 193.99.144.80: ICMP echo request, id 13146, seq 1, length 64
18:35:16.600861 IP 193.99.144.80 > 192.168.23.91: ICMP echo reply, id 13146, seq 1, length 64
18:35:17.578164 IP 192.168.23.91 > 193.99.144.80: ICMP echo request, id 13146, seq 2, length 64
18:35:17.599898 IP 193.99.144.80 > 192.168.23.91: ICMP echo reply, id 13146, seq 2, length 64
質問
NIC 2 に到着した ping パケットが NIC 1 を介して中継されないのはなぜですか? これらのパケットのルーティングを有効にするには、何をする必要がありますか?
答え1
コメントで交わされた内容をまとめると次のようになります。
システムがルーターとして明示的に設定されていない
つまり、次のようなものを適用する明示的な構成はありません:
sysctl -w net.ipv4.ip_forward=1
システムはDockerを実行している
つまり、次のようになります。
Dockerはシステムをルーターに変える
それは自らを設定します:
sysctl -w net.ipv4.ip_forward=1
-
ルーター上のDocker
Docker は FORWARD チェーンのポリシーも DROP に設定します。Docker ホストがルーターとしても機能する場合、この結果、そのルーターはトラフィックを転送しなくなります。システムをルーターとして機能させ続ける場合は、チェーンに明示的な ACCEPT ルールを追加して
DOCKER-USER
許可することができます。$ iptables -I DOCKER-USER -i src_if -o dst_if -j ACCEPT
それで
- Docker が転送されたパケットをドロップする (コンテナを除く)
- Docker を停止しても転送は有効になりませんでした (少なくとも次回の起動時には)
どちらの場合も、システムは最終的にルーティングしませんでした。
おそらく、以下の両方のことを行う必要があります。
- ルーティングを明示的に有効にする(
/etc/sysctl.conf
またはのどこか/etc/sysctl.d/
) - Dockerガイドに従う前のリンクルーティングされたトラフィックを許可する