web-dev-qa-db-ja.com

iptables NATネットワークブリッジ、コンテナ、systemd-networkd:転送なし

CentOS7でiptables NATを構成する際に問題が発生しました。現在、NATの背後にあるクライアントは外部IPに到達できますが、外部ネットワークには到達できません。

GentooとArchでうまく機能することを知って、このチュートリアルに従ってNATを設定しました。

http://www.revsys.com/writings/quicktips/nat.html

私の問題を図式化するには:

  • eth0(外部)= 192.168.1.1/24
  • eth1(内部)= 192.168.2.1/24

192.168.2.2からpingを実行すると:

  • ping 192.168.1.1:OK
  • ping 192.168.1.2:NOK
  • ping 8.8.8.8:NOK

192.168.1.1:80から192.168.2.2:80へのポート転送ルールも設定していることに注意してください。 Wiresharkによると、これはうまく機能し、私のパケットは192.168.2.2に正常に転送されます。次に、192.168.2.2が応答しますが、パケットがドロップされるため、複数のTCP再送信が表示されます。「ホストの管理上禁止」メッセージはありません。

外部から192.168.2.2:80に接続しようとしたときのドロップウォッチメッセージは次のとおりです。

1 drops at ip_error+68 (0xffffffff815c47d8)
1 drops at ip_error+68 (0xffffffff815c47d8)
1 drops at ip_error+68 (0xffffffff815c47d8)
1 drops at ip_error+68 (0xffffffff815c47d8)
1 drops at tcp_rcv_state_process+1b0 (0xffffffff815e5030)
1 drops at ip_error+68 (0xffffffff815c47d8)
1 drops at tcp_rcv_state_process+1b0 (0xffffffff815e5030)
1 drops at ip_error+68 (0xffffffff815c47d8)
2 drops at ip_error+68 (0xffffffff815c47d8)
1 drops at tcp_v4_do_rcv+80 (0xffffffff815ef160)
1 drops at ip_error+68 (0xffffffff815c47d8)
1 drops at tcp_v4_do_rcv+80 (0xffffffff815ef160)
1 drops at ip_error+68 (0xffffffff815c47d8)
2 drops at ip_error+68 (0xffffffff815c47d8)
1 drops at tcp_v4_do_rcv+80 (0xffffffff815ef160)
2 drops at ip_error+68 (0xffffffff815c47d8)
1 drops at tcp_v4_do_rcv+80 (0xffffffff815ef160)
1 drops at ip_error+68 (0xffffffff815c47d8)

誰かが私が間違ったことを知っていますか?みなさん、ありがとうございました。

編集:

-P INPUT ACCEPT
-P FORWARD ACCEPT
-P OUTPUT ACCEPT
-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
-A INPUT -p icmp -j ACCEPT
-A INPUT -i lo -j ACCEPT
-A INPUT -p tcp -m state --state NEW -m tcp --dport 22 -j ACCEPT
-A FORWARD -i eth0 -o eth1 -m state --state RELATED,ESTABLISHED -j ACCEPT
-A FORWARD -i eth1 -o eth0 -j ACCEPT
-A FORWARD -d 192.168.2.2/32 -p tcp -m tcp --dport 80 -m state --state NEW,RELATED,ESTABLISHED -j ACCEPT

Chain PREROUTING (policy ACCEPT 1270 packets, 123K bytes)
 pkts bytes target     prot opt in     out     source               destination         
   30  1696 DNAT       tcp  --  eth0 any     anywhere             anywhere             tcp dpt:http to:192.168.2.2:80

Chain INPUT (policy ACCEPT 347 packets, 42272 bytes)
 pkts bytes target     prot opt in     out     source               destination         

Chain OUTPUT (policy ACCEPT 6 packets, 431 bytes)
 pkts bytes target     prot opt in     out     source               destination         

Chain POSTROUTING (policy ACCEPT 30 packets, 1696 bytes)
 pkts bytes target     prot opt in     out     source               destination                                             
    6   431 MASQUERADE  all  --  any    eth0  anywhere             anywhere 

編集:

はいIP転送は正しく設定されています。 192.168.2.2から192.168.1.2にpingを実行すると、192.168.1.2でWiresharkを使用して着信するパケットが表示されません。また、Wiresharkを使用すると、eth0からパケットが送信されるのを確認できません。

不思議なことに、192.168.2.2から192.168.1.1に正常にpingを実行すると、eth0から着信するICMPパケットも表示されません。

関連性がないと思ったので、開示しなかったものを追加しなければならないと思います。実際には、ローカルLANへのbr0(ここでは私のeth1)という名前のネットワークブリッジをNATしようとしています。サーバー192.168.2.2は、ブリッジに接続されたvethを備えたコンテナ内にあります。

状況をよりよく反映するためにすべての投稿を編集する必要があるかどうかはわかりません。私の問題は純粋にiptableの間違いだと思いましたが、192.168.1.1にpingを実行すると着信ICMPパケットが表示されるため、ネットワークスタックに問題があるようです。

私がすでにGentooとArchでこのセットアップを行ったと言ったとき、それはLXCを使用したコンテナーでもありました。今、私はsystemd-nspawnを使おうとしています。 Selinuxは許容として設定されています。 CentOSホストから192.168.2.2にpingを実行しても問題ありません。強制的にeth0を使用することはできませんが、正常な動作です。

ルートホスト:

default via 192.168.1.254 dev eth0 proto static metric 100 
192.168.2.0/24 dev br0 proto kernel scope link src 192.168.2.1 
192.168.1.0/24 dev eth0 proto kernel scope link src 192.168.1.1 metric 100

ルートコンテナ:

default via 192.168.2.1 dev Host0 proto static 
192.168.2.0/24 dev Host0 proto kernel scope link src 192.168.2.2
1
MathieuR

非常に頭痛の種の後にようやく解決策を見つけました...

Systemd-networkdを使用してブリッジをセットアップしていました。 net.ipv4.ip_forwardが正しく1に設定され、net.ipv4.conf.all.forwardingも1に設定されましたが、systemd-networkdは、ブリッジを見ているときにデフォルトを考慮していなかったようです。

Siは、net.ipv4.conf.br0.forwardingが0に設定されたことを終了しました。1に設定しただけで、動作するようになりました。

同様の問題が発生したすべての人に対して、次のコマンドを実行します。

sysctl -a | grep "\.forwarding" | grep ipv4

すべてのインターフェースで転送が有効になっていることを確認してください。

ごきげんよう。

1
MathieuR