このセットアップには、2つのネットワークアダプターを備えた仮想マシン(VM)のホストシステムという1つの物理マシンしかありません。
1つのNIC(eth0)は内部ネットワーク(LANサブネット、例:10.x.x.x/24)に接続され、内部トラフィックに使用されます。
もう1つのNIC(eth1)はパブリックインターネットに接続されています(パブリックルーティング可能なIPが構成されています)。この接続は、パブリックインターネットトラフィックをVMの内部IPにポート転送するために使用されます(着信トラフィック)およびVMがNATを介してパブリックインターネット(発信トラフィック)にアクセスできるようにします。
仮想マシンはLANサブネットのIPアドレスを使用します(10.x.x.x/24、eth0と同じ)
VM(vnet0、vnet1、...)とLAN-NIC(eth0)の仮想ネットワークインターフェイス用に構成されたブリッジデバイス(br0)があります。つまり、次のことを意味します。
LAN内の通信は正常に機能します。また、VMホストはパブリックIP経由でアクセスでき、インターネットにアクセスできます。
私の問題は、VMがパブリックインターネットにもアクセスできるようにするためのNAT構成です。
単純な(S)NATルールを使用しようとしました:
iptables -t nat -I POSTROUTING -s 10.x.x.x/24 ! -d 10.x.x.x/24 -j SNAT --to-source y.y.y.102
一方、y.y.y.102は、2番目のルーティング可能なパブリックIPですNIC(eth1)。
「ip_forward」と「bridge-nf-call-iptables」を有効にする必要があることがわかりました。
echo 1 > /proc/sys/net/ipv4/ip_forward
echo 1 > /proc/sys/net/bridge/bridge-nf-call-iptables
それ以外の場合、ブリッジされたパッケージはiptablesによって処理されません。
これで、VMからのパケットは次のiptablesのチェーンを通過するように見えます。
しかし、私がこれまで理解できなかった何らかの理由で、すべてのパケットがPRE/POSTROUTINGに到着するとは限りません。
ただし、興味深いことにtcpdump -i eth0
対tcpdump -i eth1
パケット(VM内から外部IPにpingを実行しようとしました)が間違ったインターフェイスeth0(= LAN-NIC)を介して送信されているように見えることを示します。 NATルールが適用されたため、送信元アドレスは他のNIC(eth1)のIPに変更されました。
正しいNIC(eth1)を介して送信される送信元アドレスとしてパブリックIPを使用してNATパケットを出力するようにシステムを構成するにはどうすればよいですか?
どういうわけか、ブリッジ(br0)にeth1を追加する必要がありますか?その場合、パブリックIPアドレスを正しく割り当てるにはどうすればよいですか?通常、IPはブリッジデバイスで設定する必要があります。ブリッジにエイリアスアドレスを割り当てる必要がありますか(br0:0のパブリックIP)?
ホストシステムのルーティング構成:
# ip r
default via y.y.y.126 dev eth1
10.x.x.0/24 dev br0 proto kernel scope link src 10.x.x.11
y.y.y.96/27 dev eth1 proto kernel scope link src y.y.y.102
NIC構成:
# ifconfig
br0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 10.x.x.11 netmask 255.255.255.0 broadcast 10.x.x.255
inet6 ####::###:####:####:#### prefixlen 64 scopeid 0x20<link>
ether ##:##:##:##:##:## txqueuelen 0 (Ethernet)
RX packets 2139490 bytes 243693436 (232.4 MiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 29085 bytes 2398024 (2.2 MiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet6 ####::###:####:####:#### prefixlen 64 scopeid 0x20<link>
ether ##:##:##:##:##:## txqueuelen 1000 (Ethernet)
RX packets 2521995 bytes 290600491 (277.1 MiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 383089 bytes 48876399 (46.6 MiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
device memory 0xdfa60000-dfa7ffff
eth1: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet y.y.y.102 netmask 255.255.255.224 broadcast y.y.y.127
inet6 ####::###:####:####:#### prefixlen 64 scopeid 0x20<link>
ether ##:##:##:##:##:## txqueuelen 1000 (Ethernet)
RX packets 2681476 bytes 597532550 (569.8 MiB)
RX errors 0 dropped 130 overruns 0 frame 0
TX packets 187755 bytes 21894113 (20.8 MiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
device memory 0xdfa00000-dfa1ffff
ブリッジ構成:
# brctl show
bridge name bridge id STP enabled interfaces
br0 8000.002590eb1900 no eth0
vnet0
そしてiptablesのルール:
# iptables -vnL
Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
723 106K DROP udp -- * * y.y.y.0/24 0.0.0.0/0 udp spt:5404
586 40052 ACCEPT all -- * * 0.0.0.0/0 0.0.0.0/0 state RELATED,ESTABLISHED
5 420 ACCEPT icmp -- * * 0.0.0.0/0 0.0.0.0/0
0 0 ACCEPT all -- lo * 0.0.0.0/0 0.0.0.0/0
0 0 ACCEPT tcp -- * * 0.0.0.0/0 0.0.0.0/0 state NEW tcp dpt:22
2 458 LOG all -- * * 0.0.0.0/0 0.0.0.0/0 LOG flags 0 level 4
2 458 REJECT all -- * * 0.0.0.0/0 0.0.0.0/0 reject-with icmp-Host-prohibited
Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
1343 173K ACCEPT tcp -- * * 10.x.x.2 0.0.0.0/0 tcp spt:3389
1648 127K ACCEPT tcp -- * * 0.0.0.0/0 10.x.x.2 tcp dpt:3389
18 1040 LOG all -- * * 0.0.0.0/0 0.0.0.0/0 LOG flags 0 level 4
18 1040 ACCEPT all -- * * 0.0.0.0/0 0.0.0.0/0
Chain OUTPUT (policy ACCEPT 525 packets, 84016 bytes)
pkts bytes target prot opt in out source destination
# iptables -vnL -t nat
Chain PREROUTING (policy ACCEPT 13 packets, 1218 bytes)
pkts bytes target prot opt in out source destination
Chain INPUT (policy ACCEPT 5 packets, 420 bytes)
pkts bytes target prot opt in out source destination
Chain OUTPUT (policy ACCEPT 13 packets, 880 bytes)
pkts bytes target prot opt in out source destination
Chain POSTROUTING (policy ACCEPT 14 packets, 920 bytes)
pkts bytes target prot opt in out source destination
5 300 SNAT all -- * * 10.x.x.0/24 !10.x.x.0/24 to:y.y.y.102
そして、ここでは、LANインターフェイスカードでキャプチャされたNATされたパケット(VMからのping)を示します。
# tcpdump -i eth0
12:53:55.243350 IP y.y.y.102 > y.y.y.110: ICMP echo request, id 2, seq 5, length 40
「ipルール」の出力:
# ip rule
0: from all lookup local
32766: from all lookup main
32767: from all lookup default
VMに10.x.x.x/24(ネットマスク255.255.255.0)のIPアドレスがあることを確認します
VMのデフォルトゲートウェイとして10.x.x.11(br0 ipアドレス)を設定
物理ホストでIP転送を有効にする
SNATを有効にするには:
iptables -t nat -A POSTROUTING -s 10.x.x.x/24 -o eth1 -j SNAT --to y.y.y.102
iptables -t nat -I POSTROUTING -s 10.x.x.x/24! -d 10.x.x.x/24 -j SNAT --to-source y.y.y.102
これはに変更する必要があります
iptables -t nat -I POSTROUTING --out-interface eth1 -j SNAT --to-source y.y.y.102
最初のルールに従って、宛先が10.x.x.xのパッケージのみを処理する必要があります。では、外部からネットワークへのトラフィックはどうでしょうか。 (ソース-世界中から、宛先はパブリックIPです:)
正しいNIC(eth1)を介して送信される送信元アドレスとしてパブリックIPを使用してNATパケットを出力するようにシステムを構成するにはどうすればよいですか?
上記参照。 NATルールを変更するだけです。
どういうわけか、ブリッジ(br0)にeth1を追加する必要がありますか?その場合、パブリックIPアドレスを正しく割り当てるにはどうすればよいですか?通常、IPはブリッジデバイスで設定する必要があります。ブリッジにエイリアスアドレスを割り当てる必要がありますか(br0:0のパブリックIP)?
あなたがこれをしていることとその理由に気付いていない限り、決してそうではありません。内部インターフェースと外部インターフェースを分離してください。ルーティングのみを許可します。
私は、5年以上ライブ構成(本番)について説明しました。 openvpnトンネルを介したブリッジリンクを含む、3つのホストサーバーと25のVMでスムーズに動作します。
Silvioの投稿は、同様の構成を機能させるのに役立ちました。彼の投稿に加えて、ここでも私が実行する必要があるいくつかのことを示します。
Linuxカーネルの新しいバージョン(Redhat 7など)では、ブリッジカーネルモジュールを有効にする必要があります。
modprobe br_netfilter
サーバーの再起動後もその変更を永続的にするには、同じ行を/etc/modules-load.d/.confという名前のファイルに追加します
Br_netfilterを有効にしたら、VMへのiptable転送ルールも有効にする必要がありました。例:
iptables -I FORWARD -d 10.x.x.x/24 -j ACCEPT
iptables -I FORWARD -s 10.x.x.x/24 -j ACCEPT
サーバーホスティング施設内に必要なルートは1つだけなので、SNATの代わりにマスカレードルールを使用しました。
iptables -t nat -A POSTROUTING -s <single-local-vm-ip>/32 -d <my-destination-subnet>/24 -p tcp -j MASQUERADE --to-ports 1024-65535