nftables / iptables para reescrever o IP de origem por interface

2

Eu tenho uma rede física com um servidor Linux (Ubuntu 16.04, kernel 4.13) e vários gadgets nela. Cada gadget tem o mesmo IP estático imutável, por exemplo. 192.168.0.222/24. Gostaria de me comunicar com todos esses gadgets por meio de um protocolo IP arbitrário (por exemplo, ping ICMP ou um protocolo UDP personalizado)

Felizmente, tenho um switch de rede gerenciado conectando o servidor e os gadgets. Eu configurei o switch para ter uma porta de tronco para o servidor e acessar portas para cada gadget, cada uma em uma VLAN diferente (VIDs 11, 12, etc).

Eu adicionei 8021q a / etc / modules e configurei as entradas de VLAN em / etc / network / interfaces:

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

Com as entradas, conforme mostrado acima, posso me comunicar com o gadget 1 (por exemplo, ping 192.168.0.222 ) e não vejo nenhum tráfego do gadget 2.

Mas eu gostaria de poder me comunicar com todos os gadgets ao mesmo tempo e ser capaz de distinguir um do outro. Eles não precisam falar um com o outro. Eu estava pensando que, para cada gadget, eu poderia criar um IP e uma sub-rede de host exclusivos, por exemplo,

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

Eu usaria iptables ou nftables para lidar com a tradução em cada direção. Então, eu poderia ping 192.168.101.222 alcançar o gadget 1 e ping 192.168.102.222 alcançar o gadget 2. Do ponto de vista de cada gadget, seu IP próprio ainda seria 192.168.0.222 e veria as solicitações de eco ICMP provenientes de 192.168.0.1.

Isso parece uma variante um tanto incomum do NAT. Observe que o tráfego com os IPs "falsos" não precisa (e não deveria) deixar o servidor - não estamos encaminhando para outra rede.

  1. Esta é uma abordagem razoável para o problema?
  2. Como eu configuro o / etc / network / interfaces e iptables ou nftables para conseguir isso?
por pericynthion 15.07.2018 / 06:19

2 respostas

1

Consegui alcançar isso com o seguinte conjunto de regras nftables (eu tive que criar nft a partir da fonte como v0.5, que vem com o Ubuntu 16.04 não suporta mangling de campos de pacotes ):

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
        }
}

e as seguintes entradas em /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

Isso não "descontrolará" o IP de origem dos pacotes de saída, ou seja, os gadgets ainda veem solicitações do servidor como provenientes de 192.168.101.1 , 192.168.102.1 etc em vez de 192.168.0.1 - em meu aplicativo isso não acontece importa, mas provavelmente poderia ser endereçada com regras adicionais na cadeia output .

    
por 16.07.2018 / 00:49
1
  1. Sim, é razoável.

  2. Infelizmente, o DNAT do Linux ("NAT de reescrita de destino") está restrito à cadeia prerouting . Este é um PITA no seu caso, porque isso significa que você:

    (a). faça o DNAT no seu servidor, mas você pode usar esses endereços somente de fora do servidor, não do próprio servidor; ou

    (b). você cria artificialmente a situação acima, criando um namespace de rede, conecta o namespace de rede ao namespace principal do servidor com um par de veth e, em seguida, faz o DNAT dentro do namespace de rede. Isso significa que todas as suas interfaces VLAN também vão dentro do namespace da rede.

Eu não tenho ideia de por que as pessoas da rede Linux fizeram dessa maneira, mas é assim. Um método geral para apenas reescrever pacotes teria sido muito útil ...

Google para "namespace de rede" e "iptables DNAT", isso deve ser suficiente para você começar (a menos que alguém com mais tempo do que eu escreva uma resposta passo-a-passo ...)

    
por 15.07.2018 / 09:25