NAT 및 VM용 브리징을 갖춘 2개의 NIC(LAN 대 인터넷)를 사용한 Linux 라우팅

NAT 및 VM용 브리징을 갖춘 2개의 NIC(LAN 대 인터넷)를 사용한 Linux 라우팅

내 설정:

이 설정에는 두 개의 네트워크 어댑터가 있는 가상 머신(VM)용 호스트 시스템인 물리적 머신이 하나만 있습니다.

하나의 NIC(eth0)는 내부 네트워크(LAN 서브넷, 예: 10.xxx/24)에 연결되며 내부 트래픽에 사용됩니다.

다른 NIC(eth1)는 공용 인터넷에 연결되어 있습니다(공용 라우팅 가능 IP가 구성되어 있음). 이 연결은 공용 인터넷 트래픽을 VM의 내부 IP(수신 트래픽)로 포트 전달하고 VM이 NAT를 통해 공용 인터넷(발신 트래픽)에 액세스할 수 있도록 하는 데 사용됩니다.

가상 머신은 LAN-Subnet(10.xxx/24, eth0과 동일)의 IP 주소를 사용합니다.

VM(vnet0, vnet1, ...) 및 LAN-NIC(eth0)의 가상 네트워크 인터페이스에 대해 구성된 브리지 장치(br0)가 있습니다. 그 의미는:

  • br0에는 LAN 서브넷(10.xxx/24)의 IP 주소가 있습니다.
  • eth0이 브릿지에 추가됩니다.
  • vnet0, vnet1, ...(VM에서 사용)은 브리지에 동적으로 추가됩니다.

문제

LAN 내 통신이 제대로 작동합니다. 또한 VM-Host는 공용 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는 두 번째 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 eth0tcpdump -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
  • 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에 10.xxx/24(넷마스크 255.255.255.0)의 IP 주소가 있는지 확인하세요.

  2. 10.xx11(br0 IP 주소)을 VM의 기본 게이트웨이로 설정합니다.

  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 --소스로 yyy102

이는 다음으로 변경되어야 합니다.

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

첫 번째 규칙에 따르면 대상이 10.xxx인 패키지만 처리해야 합니다. 그렇다면 외부에서 네트워크로 유입되는 트래픽은 어떻습니까? (출처 - 전 세계에서 대상은 공개 IP입니다 :)

올바른 NIC(eth1)를 통해 전송될 소스 주소로 공용 IP를 사용하여 NAT 패킷을 출력하도록 시스템을 구성하려면 어떻게 해야 합니까?

위에서 읽어보세요. NAT 규칙을 변경하면 됩니다.

어떻게든 브리지(br0)에 eth1을 추가해야 합니까? 그렇다면 공인 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. 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
    

관련 정보