2 つの NIC (LAN とインターネット) と NAT および VM のブリッジを使用した Linux ルーティング

2 つの NIC (LAN とインターネット) と NAT および VM のブリッジを使用した Linux ルーティング

私のセットアップ:

このセットアップには、2 つのネットワーク アダプターを備えた仮想マシン (VM) のホスト システムである物理マシンが 1 台だけあります。

1 つの NIC (eth0) は内部ネットワーク (LAN サブネット、例: 10.xxx/24) に接続され、内部トラフィックに使用されます。

もう一方の NIC (eth1) はパブリック インターネットに接続されています (パブリック ルーティング可能な IP が設定されています)。この接続は、パブリック インターネット トラフィックを VM の内部 IP にポート転送し (着信トラフィック)、VM が NAT 経由でパブリック インターネットにアクセスできるようにする (発信トラフィック) ために使用されます。

仮想マシンはLANサブネット内のIPアドレスを使用します(10.xxx/24、eth0と同じ)

VM (vnet0、vnet1、...) と LAN-NIC (eth0) の仮想ネットワーク インターフェイス用にブリッジ デバイス (br0) を設定しました。つまり、次のようになります。

  • br0 は LAN サブネット (10.xxx/24) に IP アドレスを持っています
  • eth0がブリッジに追加される
  • vnet0、vnet1、...(VMによって使用される)はブリッジに動的に追加されます

問題点

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

一方、yyy102 は 2 番目の NIC (eth1) のパブリック ルーティング可能な IP です。

「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 チェーンを通過するようです。

  • 「FORWARD」(通常) - そこで受け入れます(-j ACCEPT、カウンターが上がります)
  • 「PREROUTING」(nat) - そこで受け入れます(ポリシー ACCEPT、カウンターが上がります)
  • 「POSTROUTING」(nat) - SNATルールに一致する

しかし、これまでのところ、何らかの理由で、すべてのパケットが PRE/POSTROUTING に到着するわけではないようです。

しかし、もっと興味深いのは、tcpdump -i eth0パケットtcpdump -i eth1(VM 内から外部 IP に ping を実行しようとした) が間違ったインターフェイス eth0 (=LAN-NIC) 経由で送信されているように見えることです。NAT ルールも適用されたため、送信元アドレスが他の NIC (eth1) の IP に変更されました。

質問:

パブリック IP を送信元アドレスとして NAT されたパケットを正しい NIC (eth1) 経由で出力するようにシステムを構成するにはどうすればよいですか?

何らかの方法で eth1 をブリッジ (br0) に追加する必要がありますか? その場合、パブリック 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
  • IP: yyy126 はパブリックインターネット用のルーターです。
  • IP: yyy102はホストマシンのパブリックIPです
  • IP: 10.xx11はホストマシンのLAN IPです
  • サブネット: 10.xx0/24はLANです
  • サブネット: yyy96/27 はパブリック IP サブネットです

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

答え1

  1. VM の IP アドレスが 10.xxx/24 (ネットマスク 255.255.255.0) であることを確認します。

  2. VMのデフォルトゲートウェイとして10.xx11(br0 IPアドレス)を設定します

  3. 物理ホストでIP転送を有効にする

  4. SNAT を有効にするには:

    iptables -t nat -A POSTROUTING -s 10.x.x.x/24 -o eth1 -j SNAT --to y.y.y.102
    

答え2

iptables -t nat -I POSTROUTING -s 10.xxx/24 ! -d 10.xxx/24 -j SNAT --to-source yyy102

これを変更する必要があります

iptables -t nat -I POSTROUTING --out-interface eth1 -j SNAT --to-source y.y.y.102

最初のルールによると、宛先が 10.xxx のパッケージのみを処理する必要があります。では、外部からネットワークへのトラフィックはどうでしょうか? (ソース - 世界中から、宛先はパブリック IP です :)

パブリック IP を送信元アドレスとして NAT されたパケットを正しい NIC (eth1) 経由で出力するようにシステムを構成するにはどうすればよいですか?

上記を読んでください。NAT ルールを変更するだけです。

何らかの方法で eth1 をブリッジ (br0) に追加する必要がありますか? その場合、パブリック IP アドレスを正しく割り当てるにはどうすればよいですか? 通常、IP はブリッジ デバイスで設定する必要があります。ブリッジにエイリアス アドレス (br0:0 のパブリック IP) を割り当てる必要がありますか?

何を、なぜ行うのかを理解していない場合は、絶対に行わないでください。内部インターフェイスと外部インターフェイスを分離してください。ルーティングのみを許可してください。

私は 5 年以上にわたってライブ (本番) 構成について説明してきました。OpenVPN トンネルを介したブリッジ リンクを含む 3 台のホスト サーバーと 25 台の VM でスムーズに動作しています。

答え3

Silvio の投稿は、同様の構成を機能させるのに役立ちました。彼の投稿に加えて、私が行う必要があったことがいくつかあります。

  1. 新しいバージョンの Linux カーネル (Redhat 7 など) では、ブリッジ カーネル モジュールを有効にする必要があります。

    modprobe br_netfilter
    

そして、その変更をサーバーの再起動後も維持するには、/etc/modules-load.d/.confというファイルに同じ行を追加します。

  1. 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
    
  2. サーバー ホスティング施設内では 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
    

関連情報