Estou usando uma instalação mínima nova do Ubuntu server 24.04.1 LTS. Eu executo esses comandos como root para configurar a rede e fazer alguns experimentos:
apt install netcat-traditional
ip netns add ns1
ip netns add ns2
ip link add my_veth1 type veth peer name my_veth2
ip link set my_veth1 up netns ns1
ip link set my_veth2 up netns ns2
ip -n ns1 address add 1.2.3.4 dev my_veth1
ip -n ns1 route add 2.3.4.0/24 dev my_veth1
ip netns exec ns2 nc -u -l -p 8080
então eu executo isso de outro terminal:
ip netns exec ns1 nc -u 2.3.4.5 8080 <<< 'Hello world from network namespace ns1'
UDP é um protocolo sem conexão. Se meu entendimento estiver correto, isso deve significar que o servidor UDP netcat do namespace de rede ns2 deve ser capaz de imprimir a mensagem que o cliente do ns1 enviou, independentemente de o servidor poder alcançar o cliente ou não, então, em teoria, eu não deveria ter que configurar uma rota em ns2
ou um endereço IP em my_veth2
. No entanto, nenhuma mensagem está sendo impressa no primeiro terminal, a menos que o endereço IP e a entrada da tabela de roteamento estejam configurados. Por quê?
- Tentei adicionar o endereço IP
2.3.4.5
,my_veth2
mas não funcionou. - Tentei criar uma nova entrada na tabela de roteamento
ns2
para redirecionar todo o tráfego de1.2.3.0/24
paramy_veth2
, mas isso também não funcionou. - A mensagem só seria impressa ao adicionar o endereço IP
2.3.4.5
amy_veth2
AND criar uma nova entrada de tabela de roteamento em ns2 para redirecionar todo o tráfego de1.2.3.0/24
paramy_veth2
. Por que isso?
EDIT: Desabilitar o rp_filter não parece resolver o problema:
ip netns exec ns1 dd of=/proc/sys/net/ipv4/conf/all/rp_filter <<< '0'
ip netns exec ns2 dd of=/proc/sys/net/ipv4/conf/all/rp_filter <<< '0'
ip netns exec ns1 dd of=/proc/sys/net/ipv4/conf/my_veth1/rp_filter <<< '0'
ip netns exec ns2 dd of=/proc/sys/net/ipv4/conf/my_veth2/rp_filter <<< '0'
EDIT 2: Instalando e executando o tcpdump Aprendi que havia algumas solicitações ARP sendo enviadas e não estavam sendo respondidas:
$ ip netns exec ns1 tcpdump -l -i my_veth1
23:38:14.402259 ARP, Request who-has 2.3.4.5 tell 1.2.3.4, length 28
23:38:14.402259 ARP, Request who-has 2.3.4.5 tell 1.2.3.4, length 28
23:38:14.402259 ARP, Request who-has 2.3.4.5 tell 1.2.3.4, length 28
...
ns2 my_veth2 fornece a mesma saída
Então tentei criar a entrada da tabela ARP manualmente...
ip -n ns1 neighbour add 2.3.4.5 dev my_veth1 lladdr $(ip netns exec ns2 cat /sys/class/net/my_veth2/address)
E agora aparentemente o pacote UDP está sendo enviado
$ ip netns exec ns1 tcpdump -l -i my_veth1
00:24:15.164245 IP 1.2.3.4.36170 > 2.3.4.5.8080: UDP, length 39
ns2 my_veth2 fornece a mesma saída
No entanto, o primeiro terminal que tem o servidor UDP netcat em execução ainda não produz nada. Por quê?
EDIT 3: Depois de fazer tudo isso, tentei atribuir um endereço IP para my_veth2
:
ip -n ns2 address add 2.3.4.5 dev my_veth2
E agora, quando envio o pacote UDP, recebo este erro no terminal que está executando o netcat em modo de escuta:
no connection : Network is unreachable
Por quê? Quero dizer, é claro que a rede está inacessível, mas isso não deve impedir o servidor de receber e exibir pacotes UDP. Na verdade, esse erro só é exibido quando ele recebe o pacote UDP. Então, mesmo que ele saiba que não pode responder, ele deve ser capaz de receber e exibir a mensagem, certo?
Inicialmente, você cria apenas um endereço IP "IP1" no ns1 e uma rota para um endereço IP imaginário (inexistente) "IP2" no ns2.
Tentar enviar de ns1 para IP2 falhará, pois precisa de um endereço MAC (camada de link) para entregar o pacote. Daí a solicitação ARP que você vê. ns2 não responde à solicitação ARP para IP2, pois não tem IP2.
Adicionar manualmente uma entrada ARP para IP2 no ns1 permite passar esse problema de camada de link. No ns2, o pacote do ns1 agora pode ser observado.
Mas o netcat ainda não mostra nada, pois ele só espera pacotes em 0.0.0.0 - o que significa qualquer endereço IP configurado no ns2. Só que o IP2 não está configurado no ns2. Portanto, mesmo que o pacote tenha sido recebido na camada de link, ele não é processado na camada de rede (IP) - simplesmente não há endereço IP que corresponda ao destino do pacote.
Somente quando o IP2 é adicionado como IP para o ns2 a camada de rede no ns2 se sente responsável por ele e entrega a carga útil ao aplicativo (nc).
Respondendo a minha própria terceira edição...
Não sei o REAL motivo pelo qual a decisão de rejeitar pacotes UDP naquele caso foi tomada, mas consigo pensar em algumas razões para isso: