Vi outras respostas neste site, li um artigo e assisti a um vídeo sobre o assunto, mas ainda não consigo conectar meu namespace de rede ao mundo externo.
Configurar
Criei um namespace chamado "foo" e um par de veth
interfaces e movi uma para o namespace.
ip netns add foo
ip link add veth-foo type veth peer name veth-out
ip link set dev veth-foo netns foo
Atribuí um endereço IP a cada interface e verifiquei se ambas estavam ativas.
ip -n foo addr add 192.168.15.1 dev veth-foo
ip addr add 192.168.15.2 dev veth-out
ip -n foo link set dev veth-foo up
ip link set dev veth-out up
# Just in case, I made sure the loopback interfaces, too, are up, though they still show "UNKNOWN".
ip link set dev lo up
ip -n foo link set dev lo up
Adicionei entradas às tabelas de roteamento dos namespaces global e "foo", para que eles possam se comunicar entre si.
ip route add 192.168.15.1 via 192.168.15.2
ip -n foo route add default via 192.168.15.1
Agora, posso alcançar "foo" do namespace global e o namespace global de "foo".
$ traceroute -n 192.168.15.1
traceroute to 192.168.15.1 (192.168.15.1), 30 hops max, 60 byte packets
1 192.168.15.1 0.257 ms 0.209 ms 0.194 ms
$ ip netns exec foo traceroute -n 192.168.15.2
traceroute to 192.168.15.2 (192.168.15.2), 30 hops max, 60 byte packets
1 192.168.15.2 0.046 ms 0.009 ms 0.008 ms
Também posso acessar a interface Ethernet que conecta a VM ao mundo externo de dentro de "foo".
# I ran this after I finished setting up IP forwarding, packet forwarding,
# and IP masquerading, so I'm not sure if it would work at this stage.
$ ip netns exec foo traceroute -n 10.0.2.15
traceroute to 10.0.2.15 (10.0.2.15), 30 hops max, 60 byte packets
1 10.0.2.15 0.065 ms 0.010 ms 0.008 ms
Por fim, configurei o encaminhamento de IP, o encaminhamento de pacotes e o mascaramento de IP.
echo 1 > /proc/sys/net/ipv4/ip_forward
iptables -A FORWARD -o enp1s0 -i veth-out -j ACCEPT
iptables -A FORWARD -i enp1s0 -o veth-out -j ACCEPT
iptables -t nat -A POSTROUTING -s 192.168.15.1/24 -o enp1s0 -j MASQUERADE
Como resultado, meu sistema fica assim:
$ sysctl -a | grep ip_forward
net.ipv4.ip_forward = 1
net.ipv4.ip_forward_update_priority = 1
net.ipv4.ip_forward_use_pmtu = 0
$ iptables -t nat -L -v
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 102 packets, 6816 bytes)
pkts bytes target prot opt in out source destination
0 0 MASQUERADE all -- any enp1s0 192.168.15.0/24 anywhere
$ 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:c3:cd:ac brd ff:ff:ff:ff:ff:ff
inet 10.0.2.15/24 brd 10.0.2.255 scope global dynamic noprefixroute enp1s0
valid_lft 83383sec preferred_lft 83383sec
inet6 fec0::11b8:4b3b:59ba:bae4/64 scope site dynamic noprefixroute
valid_lft 86026sec preferred_lft 14026sec
inet6 fe80::f3fd:90f2:d15f:d570/64 scope link noprefixroute
valid_lft forever preferred_lft forever
3: veth-out@if4: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
link/ether da:a2:13:05:c4:f5 brd ff:ff:ff:ff:ff:ff link-netns foo
inet 192.168.15.2/32 scope global veth-out
valid_lft forever preferred_lft forever
inet6 fe80::d8a2:13ff:fe05:c4f5/64 scope link proto kernel_ll
valid_lft forever preferred_lft forever
$ ip -n foo 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 proto kernel_lo
valid_lft forever preferred_lft forever
4: veth-foo@if3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
link/ether 7e:84:e6:16:92:8e brd ff:ff:ff:ff:ff:ff link-netnsid 0
inet 192.168.15.1/32 scope global veth-foo
valid_lft forever preferred_lft forever
inet6 fe80::7c84:e6ff:fe16:928e/64 scope link proto kernel_ll
valid_lft forever preferred_lft forever
$ ip route
default via 10.0.2.2 dev enp1s0 proto dhcp src 10.0.2.15 metric 100
10.0.2.0/24 dev enp1s0 proto kernel scope link src 10.0.2.15 metric 100
192.168.15.1 via 192.168.15.2 dev veth-out
$ ip -n foo route
default via 192.168.15.1 dev veth-foo
Testando
Neste ponto, espero conseguir alcançar o mundo exterior, mas não.
$ ip netns exec foo traceroute -n 8.8.8.8
traceroute to 8.8.8.8 (8.8.8.8), 30 hops max, 60 byte packets
1 192.168.15.1 3067.680 ms !H 3067.655 ms !H 3067.650 ms !H
$ sudo ip netns exec foo ping -c 3 8.8.8.8
PING 8.8.8.8 (8.8.8.8) 56(84) bytes of data.
From 192.168.15.1 icmp_seq=1 Destination Host Unreachable
From 192.168.15.1 icmp_seq=2 Destination Host Unreachable
From 192.168.15.1 icmp_seq=3 Destination Host Unreachable
--- 8.8.8.8 ping statistics ---
3 packets transmitted, 0 received, +3 errors, 100% packet loss, time 2077ms
É claro que a própria VM está conectada à Internet.
$ traceroute -n 8.8.8.8
traceroute to 8.8.8.8 (8.8.8.8), 30 hops max, 60 byte packets
1 10.0.2.2 0.719 ms 0.691 ms 0.676 ms
2 192.168.100.1 1.913 ms 2.593 ms 5.264 ms
3 31.146.255.37 18.493 ms 18.740 ms 19.041 ms
4 188.123.128.85 19.384 ms 19.658 ms 19.925 ms
5 188.123.128.96 20.275 ms 21.787 ms 188.123.128.84 21.773 ms
6 192.178.69.213 47.953 ms 53.145 ms 53.127 ms
7 192.178.69.212 53.116 ms 51.893 ms 188.123.128.33 51.293 ms
8 192.178.107.87 48.513 ms 192.178.107.135 43.582 ms 192.178.107.203 43.391 ms
9 72.14.237.137 43.195 ms 8.8.8.8 43.207 ms 43.200 ms
$ ping -c 3 8.8.8.8
PING 8.8.8.8 (8.8.8.8) 56(84) bytes of data.
64 bytes from 8.8.8.8: icmp_seq=1 ttl=255 time=40.2 ms
64 bytes from 8.8.8.8: icmp_seq=2 ttl=255 time=37.9 ms
64 bytes from 8.8.8.8: icmp_seq=3 ttl=255 time=38.0 ms
--- 8.8.8.8 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2003ms
rtt min/avg/max/mdev = 37.859/38.698/40.205/1.067 ms
Tcpdump
Aqui está a saída de tcpdump -n -i veth-out icmp
. Ele capturou pacotes quando eu mirei 192.168.15.2
& 10.0.2.15
, mas não obteve nada quando eu mirei 8.8.8.8
.
listening on veth-out, link-type EN10MB (Ethernet), snapshot length 262144 bytes
# This is the output when I ran `traceroute -n 192.168.15.2` (the address
# of "veth-out") in another terminal window (from inside "foo", of course).
12:44:19.172007 IP 192.168.15.2 > 192.168.15.1: ICMP 192.168.15.2 udp port traceroute unreachable, length 68
12:44:19.172029 IP 192.168.15.2 > 192.168.15.1: ICMP 192.168.15.2 udp port mtrace unreachable, length 68
12:44:19.172046 IP 192.168.15.2 > 192.168.15.1: ICMP 192.168.15.2 udp port 33436 unreachable, length 68
12:44:19.172063 IP 192.168.15.2 > 192.168.15.1: ICMP 192.168.15.2 udp port 33437 unreachable, length 68
12:44:19.172102 IP 192.168.15.2 > 192.168.15.1: ICMP 192.168.15.2 udp port 33438 unreachable, length 68
12:44:19.172119 IP 192.168.15.2 > 192.168.15.1: ICMP 192.168.15.2 udp port 33439 unreachable, length 68
# And this is when I ran the same command but addressed 10.0.2.15 (the
# ethernet interface to the outside world).
12:44:35.305689 IP 10.0.2.15 > 192.168.15.1: ICMP 10.0.2.15 udp port traceroute unreachable, length 68
12:44:35.305715 IP 10.0.2.15 > 192.168.15.1: ICMP 10.0.2.15 udp port mtrace unreachable, length 68
12:44:35.305733 IP 10.0.2.15 > 192.168.15.1: ICMP 10.0.2.15 udp port 33436 unreachable, length 68
12:44:35.305750 IP 10.0.2.15 > 192.168.15.1: ICMP 10.0.2.15 udp port 33437 unreachable, length 68
12:44:35.305766 IP 10.0.2.15 > 192.168.15.1: ICMP 10.0.2.15 udp port 33438 unreachable, length 68
12:44:35.305783 IP 10.0.2.15 > 192.168.15.1: ICMP 10.0.2.15 udp port 33439 unreachable, length 68
^C
12 packets captured
12 packets received by filter
0 packets dropped by kernel
Nem capturou tcpdump -n -i lo icmp
nenhum tcpdump -n -i enp1s0 icmp
pacote, independentemente do alvo de traceroute
—sim, mesmo quando "foo" alcançou com sucesso a interface "enp1s0" (endereçada 10.0.2.15
).
Informações do sistema
Isso foi feito dentro de uma VM (GNOME Boxes), no Fedora 41, versão do kernel 6.11.4-301.fc41.x86_64.
Minha máquina host também está executando o Fedora 41, embora o kernel esteja na versão 6.13.5-200.fc41.x86_64.
Edição: Só para garantir que isso fosse um problema do Fedora, testei em uma VM Mint e aconteceu exatamente a mesma coisa.