nftables/iptables 규칙은 인터페이스별로 소스 IP를 다시 작성합니다.

nftables/iptables 규칙은 인터페이스별로 소스 IP를 다시 작성합니다.

Linux 서버(Ubuntu 16.04, 커널 4.13)와 여러 가젯이 포함된 물리적 네트워크가 있습니다. 모든 가젯에는동일한192.168.0.222/24와 같이 변경할 수 없는 고정 IP입니다. ICMP 핑이나 사용자 정의 UDP 프로토콜과 같은 임의의 IP 프로토콜을 통해 이러한 모든 가젯과 통신하고 싶습니다.

운 좋게도 서버와 가젯을 연결하는 관리형 네트워크 스위치가 있습니다. 서버용 트렁크 포트와 각 가젯용 액세스 포트를 각각 다른 VLAN(VID 11, 12 등)에 갖도록 스위치를 구성했습니다.

/etc/modules에 추가하고 8021q/etc/network/interfaces에 VLAN 항목을 설정했습니다.

auto eno2 # For switch management interface
iface eno2 inet static
  address 192.168.2.2/24

auto eno2.11 # Gadget 1 (only)
iface eno2 inet static
  address 192.168.0.1/24

#auto eno2.12 # Gadget 2 - disabled
#iface eno2 inet static
#  address 192.168.0.1/24

위에 표시된 항목을 사용하면 Gadget 1(예: ping 192.168.0.222)과 통신할 수 있으며 Gadget 2의 트래픽은 표시되지 않습니다.

하지만 나는 동시에 모든 장치와 통신하고 서로를 구별할 수 있기를 원합니다. 그들은 서로 이야기할 필요가 없습니다. 각 가젯에 대해 고유한 호스트 IP와 서브넷을 만들고 싶습니다.

Host IP & subnet    "Fake" gadget IP     Actual gadget IP    VLAN Interface
192.168.101.1/24    192.168.101.222      192.168.0.222       eno2.11
192.168.102.1/24    192.168.102.222      192.168.0.222       eno2.12

나는 각 방향으로 번역을 사용 iptables하거나 nftables처리할 것입니다. 그런 다음 ping 192.168.101.222가젯 1에 도달하고 가젯 2에 도달할 수 있습니다 ping 192.168.102.222. 각 가젯의 관점에서 볼 때 자체 IP는 여전히 192.168.0.222이며 192.168.0.1의 ICMP 에코 요청을 확인합니다.

이는 NAT의 특이한 변형인 것 같습니다. "가짜" IP가 포함된 트래픽은 서버를 떠날 필요가 없으며, 나가서도 안 됩니다. 우리는 해당 트래픽을 네트워크의 다른 곳으로 전달하지 않습니다.

  1. 이것이 문제를 해결하는 합리적인 방법입니까?
  2. 이를 달성하려면 /etc/network/interfaces 및 iptables 또는 nftables를 어떻게 설정합니까?

답변1

  1. 예, 이것은 합리적입니다.

  2. 불행하게도 Linux DNAT("Destination Rewrite NAT")는 다음으로 제한됩니다.사전 라우팅체인. 귀하의 경우 이는 다음을 의미하기 때문에 PITA입니다.

    (ㅏ). 서버에 DNAT가 있지만 이 주소만 사용할 수 있습니다.외부서버 자체가 아닌 서버;

    (b) 네트워크 네임스페이스를 생성하고 veth-pair를 사용하여 네트워크 네임스페이스를 서버 기본 네임스페이스에 연결한 다음 네트워크 네임스페이스 내에서 DNAT를 수행하여 위 상황을 인위적으로 만들었습니다. 이는 모든 VLAN 인터페이스도 네트워크 네임스페이스에 포함된다는 의미입니다.

Linux 네트워킹 전문가들이 왜 이런 일을 하는지는 모르겠지만, 그게 바로 그 일입니다. 패킷을 재정의하는 일반적인 방법은 매우 편리할 것입니다...

Google "네트워크 네임스페이스" 및 "iptables DNAT"는 시작하기에 충분합니다(다른 사람이 나보다 단계별 답변을 작성할 시간이 더 많지 않은 한...).

답변2

다음 규칙 세트를 사용하여 이를 달성 할 수 있었습니다 ( Ubuntu 16.04와 함께 제공된 v0.5는 지원하지 않기 때문에 소스에서 빌드 nftables해야 했습니다).nft패킷 필드 수정):

table ip mytable {
        chain prerouting {
                type filter hook prerouting priority -300; policy accept;
                iifname "eno2.11" ip saddr 192.168.0.222 ip saddr set 192.168.101.222
                iifname "eno2.12" ip saddr 192.168.0.222 ip saddr set 192.168.102.222
                iifname "eno2.13" ip saddr 192.168.0.222 ip saddr set 192.168.103.222
        }

        chain output {
                type filter hook output priority -300; policy accept;
                ip daddr 192.168.101.222 ip daddr set 192.168.0.222
                ip daddr 192.168.102.222 ip daddr set 192.168.0.222
                ip daddr 192.168.103.222 ip daddr set 192.168.0.222
        }
}

다음 항목은 다음과 같습니다 /etc/network/interfaces.

auto eno2 # For switch management interface
iface eno2 inet static
  address 192.168.2.2/24

auto eno2.11
iface eno2.11 inet static
  address 192.168.101.1
  netmask 255.255.255.0

auto eno2.12
iface eno2.12 inet static
  address 192.168.102.1
  netmask 255.255.255.0

auto eno2.13
iface eno2.13 inet static
  address 192.168.103.1
  netmask 255.255.255.0

이는 나가는 패킷의 소스 IP를 "압축 해제"하지 않습니다. 즉, 가젯은 여전히 ​​서버의 요청을 등에서 오는 것으로 간주합니다. 대신 192.168.101.1내 애플리케이션에서는 이는 실제로 중요하지 않지만 추가 규칙을 통해 해결이 가능할 수 있습니다. 쇠사슬.192.168.102.1192.168.0.1output

관련 정보