Quero testar a tabela NAT usando uma interface fictícia. Tenho a interface enp1s0 conectada à internet e configurei a tabela NAT para pacotes MASQUERADE conforme mostrado abaixo.
random@debian:~$ ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host noprefixroute
valid_lft forever preferred_lft forever
2: enp1s0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
link/ether 52:54:00:4d:63:c0 brd ff:ff:ff:ff:ff:ff
inet 192.168.122.10/24 brd 192.168.122.255 scope global enp1s0
valid_lft forever preferred_lft forever
inet6 fe80::5054:ff:fe4d:63c0/64 scope link
valid_lft forever preferred_lft forever
3: dummy0: <BROADCAST,NOARP,UP,LOWER_UP> mtu 1500 qdisc noqueue state UNKNOWN group default qlen 1000
link/ether 5e:81:f3:78:47:c0 brd ff:ff:ff:ff:ff:ff
inet 10.0.0.10/24 scope global dummy0
valid_lft forever preferred_lft forever
inet6 fe80::5c81:f3ff:fe78:47c0/64 scope link
valid_lft forever preferred_lft forever
random@debian:~$ ip route
default via 192.168.122.1 dev enp1s0 onlink
10.0.0.0/24 dev dummy0 proto kernel scope link src 10.0.0.10
192.168.122.0/24 dev enp1s0 proto kernel scope link src 192.168.122.10
random@debian:~$ sudo sysctl -w net.ipv4.ip_forward=1
net.ipv4.ip_forward = 1
random@debian:~$ lsmod | grep dummy
dummy 16384 0
random@debian:~$ ipt
Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
Chain OUTPUT (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
random@debian:~$ sudo iptables -t nat -A POSTROUTING -j MASQUERADE -s 10.0.0.0/24 -o enp1s0
random@debian:~$ ipt -t nat
Chain PREROUTING (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
Chain OUTPUT (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
Chain POSTROUTING (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
0 0 MASQUERADE all -- any enp1s0 10.0.0.0/24 anywhere
Com essas configurações de ip. Testando com ping
random@debian:~$ ping -I 10.0.0.10 8.8.8.8
PING 8.8.8.8 (8.8.8.8) from 10.0.0.10 : 56(84) bytes of data.
64 bytes from 8.8.8.8: icmp_seq=1 ttl=114 time=28.3 ms
64 bytes from 8.8.8.8: icmp_seq=2 ttl=114 time=30.9 ms
^C
--- 8.8.8.8 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1002ms
rtt min/avg/max/mdev = 28.302/29.583/30.865/1.281 ms
random@debian:~$ ping -I dummy0 8.8.8.8
PING 8.8.8.8 (8.8.8.8) from 10.0.0.10 dummy0: 56(84) bytes of data.
^C
--- 8.8.8.8 ping statistics ---
5 packets transmitted, 0 received, 100% packet loss, time 4095ms
O envio de pacotes através de interface fictícia não funciona. Os pacotes podem ser vistos na interface fictícia dummy0, mas não são encaminhados para enp1s0 conforme observado usando o wireshark.
Não existe "o outro lado" (exceto talvez um vazio) com uma interface fictícia. Em outras palavras, não é realmente diferente de
lo
, exceto que normalmente se configuraria um endereço de um bloco diferente do bloco de loopback (127.0.0.0/8
). (Para ser franco, não tenho certeza se, em alguma circunstância, alguém poderia literalmente precisar de uma interface fictícia atualmente. Parece-me que ela existe por razões mais históricas.)De qualquer forma, o verdadeiro problema aqui não é exatamente o dummy, mas o
-I
inping
. Já vi muitas pessoas terem mal-entendidos semelhantes, mas mal consegui ver/adivinhar de onde isso vem, então só posso esperar que a explicação a seguir possa ajudá-lo a sair dessa:O fato de você poder usar uma interface como uma "interface de origem" NÃO significa que você pode emular/simular um "host de origem", como quando você faz ping de uma rede diferente. A frase aqui realmente significa apenas que "ignore rotas que tenham uma interface diferente (
dev
)", ou em outras palavras, "garanta (certifique-se) que o tráfego saia apenas por meio desta interface, não importa o que aconteça". (Parece que se o destino não for coberto por nenhuma rota dessa interface, o destino seria considerado "onlink".)Em outras palavras, “interface de origem” NÃO significa “interface de entrada”.
Portanto, quando você usa
-I
uma interface fictícia, o único destino que poderia fazer sentido seria o IP configurado no próprio manequim, o que resultaria em tráfegos de loopback . Obviamente, esses tráfegos nunca sairiam do host por meio de outra interface comoenp1s0
. (Aparentemente, os tráfegos de loopback nem podem serDNAT
inseridos emPREROUTING
.) Os tráfegos destinados a, por exemplo,8.8.8.8
não iriam a lugar nenhum (mas seriam vazios).(NOTA: Na verdade, precisamente falando, o tráfego de loopback não sai do host, então suponho que, pelo menos em certo sentido, você pode considerar isso uma "exceção" em
-I
"tornado possível" com alocal
rota correspondente, porque o manequim interface ainda é sua interface de rota, mesmo quando faz com que o tráfego seja retornado e "ingresse" no host vialo
.)Dito isso, uma regra
SNAT
(notMASQUERADE
) que corresponda apenas (ou seja, não-o enp1s0
) a um endereço de origem (bloco) (por exemplo,-s 10.0.0.0/24
) "funcionaria" para tais tráfegos de loopback. Só que não consigo ver qual seria o sentido de realizar esse "teste".Para "testar" uma
MASQUERADE
regra, você precisaria de tráfegos que saíssem através da interface específica (por exemploenp1s0
, ). Portanto, você precisaria (bem, um pouco; veja a última seção) de outro "host" para ser o "host de origem", que formaria uma rede com esse host e, portanto, teria um IP de origem de alguma sub-rede IP diferente da aquele usado pela rede à qual a interface (por exemplo,enp1s0
) está conectada e, portanto, precisa ser mascarada (se esse "outro lado" não tiver rota de retorno para esta sub-rede).E hoje em dia a maneira mais fácil de "criar" um host de rede/(em termos de rede) é o par netns + veth.
Observe que isso
-I
funciona de maneira muito diferente quando você usa um endereço IP em vez de uma interface como argumento.AFAIK, neste caso, não afeta a decisão da rota. Basicamente, ele apenas define o endereço IP de origem dos tráfegos de antemão, em vez de deixá-lo sem definição e deixar o sistema escolher um para ele com base em/após a decisão da rota.
Portanto, uma
MASQUERADE
regra é realmente necessária e “funcionaria” para:Mas então a questão é: o que significa quando você não está testando com a coisa real (NÃO estou falando sobre um "teste de rede") que a
MASQUERADE
regra deve servir?