Почему я не могу подключить сетевое пространство имен к Интернету?

Вопрос или проблема

Я прочитал другие ответы на этом сайте, прочитал статью и посмотрел видео на эту тему, но все еще не могу подключить свое сетевое пространство имен к внешнему миру.

Настройка

Я создал пространство имен с именем “foo” и пару интерфейсов veth, переместив один из них в пространство имен.

ip netns add foo
ip link add veth-foo type veth peer name veth-out
ip link set dev veth-foo netns foo

Я назначил каждому интерфейсу IP-адрес и убедился, что они оба активны.

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

# На всякий случай я убедился, что интерфейсы loopback также активны, хотя они по-прежнему показывают "UNKNOWN".
ip link set dev lo up
ip -n foo link set dev lo up 

Я добавил записи в маршрутизационные таблицы как глобального, так и пространства имен “foo”, чтобы они могли общаться друг с другом.

ip route add 192.168.15.1 via 192.168.15.2
ip -n foo route add default via 192.168.15.1

Теперь я могу достичь “foo” из глобального пространства имен и глобального пространства имен из “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

Я также могу достичь интерфейса Ethernet, который подключает виртуальную машину к внешнему миру изнутри “foo”.

# Я запустил это после того, как закончил настройку IP-forwarding, перенаправления пакетов
# и маскировки IP, так что я не уверен, что это сработает на этом этапе.
$ 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

Наконец, я настроил IP-forwarding, перенаправление пакетов и маскировку 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

В результате моя система выглядит следующим образом:

$ 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

Тестирование

На данном этапе я ожидаю, что смогу достичь внешнего мира, но это не так.

$ 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

Конечно, сама виртуальная машина подключена к Интернету.

$ 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

Вот вывод tcpdump -n -i veth-out icmp. Он захватил пакеты при целевом назначении 192.168.15.2 & 10.0.2.15, но ничего не было, когда был выбран 8.8.8.8.

listening on veth-out, link-type EN10MB (Ethernet), snapshot length 262144 bytes

# Это вывод, когда я запустил `traceroute -n 192.168.15.2` (адрес
# адрес "veth-out") в другом терминальном окне (конечно, изнутри "foo").
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

# А это когда я запустил ту же команду, но адресовал 10.0.2.15 (Ethernet
# интерфейс к внешнему миру).
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

Ни tcpdump -n -i lo icmp, ни tcpdump -n -i enp1s0 icmp не захватили ни одного пакета, независимо от цели traceroute — да, даже когда “foo” успешно достиг интерфейса “enp1s0” (адресованного 10.0.2.15).

Информация о системе

Это было выполнено внутри виртуальной машины (GNOME Boxes), на Fedora 41, версия ядра 6.11.4-301.fc41.x86_64.

Моя хостовая машина также работает на Fedora 41, хотя ядро находится на версии 6.13.5-200.fc41.x86_64.

Правка: На всякий случай, если это была проблема с Fedora, я протестировал это на виртуальной машине Mint и произошло точно то же самое.

Ответ или решение

Настройка сетевых пространств имен в Linux может быть трудной задачей, особенно когда требуется подключение к Интернету. Судя по вашему описанию, вы столкнулись с трудностями, связанными с маршрутизацией и трансляцией адресов (NAT), что препятствует вашим попыткам установить соединение с внешними сетями. Давайте рассмотрим каждый аспект настройки и возможные проблемы, которые могут возникнуть.

Теория

Для обеспечения возможности подключения сетевого пространства имен к Интернету обычно требуется несколько шагов:

  1. Создание и конфигурация сетевого пространства имен: Вы создаете новое сетевое пространство имен и виртуальные интерфейсы veth, связывающие пространство имен с основной сетью вашей системы.

  2. Назначение IP-адресов и активация интерфейсов: Каждому интерфейсу назначается уникальный IP-адрес, и они переводятся в активное состояние.

  3. Настройка маршрутизации: Чтобы пакеты могли проходить между пространством имен и основной сетью, необходимо правильно настроить таблицы маршрутизации.

  4. Настройка NAT и переадресации (IP forwarding): Переадресация IP-пакетов и NAT настраиваются для преобразования адресов внутренних сетей в глобально видимые IP-адреса вашей основной сети.

Пример

На основе вашего описания, вы правильно создали сетевое пространство имен и настроили интерфейсы veth. Однако ошибки могут возникнуть на каждом из этапов настройки.

Проблемы маршрутизации и NAT:

  1. Неправильные маршруты: Вы добавили маршруты для связи между пространством имен и глобальной сетью. Однако убедитесь, что маршруты корректны и все интерфейсы имеют корректные настройки.

  2. Конфигурация NAT: Настройка команд iptables для сетевых правил может быть сложной. Пользователь может ошибиться в синтаксисе правил, что приведет к неправильной трансляции адресов. В вашем случае, убедитесь, что диапазон адресов и интерфейсы в правилах POSTROUTING правилах правильны.

  3. Проблемы с MASQUERADE: Команда iptables -t nat -A POSTROUTING -s 192.168.15.1/24 -o enp1s0 -j MASQUERADE должна предполагает использование адресов исходящих соединений, которые может быть неправильно рассчитан. Убедитесь, что ваш основной интерфейс (enp1s0) правильно настроен как выходной для правил NAT.

Применение

Учитывая ваше описание, давайте рассмотрим эти аспекты более подробно в вашем контексте:

  1. Адреса интерфейсов: Проверьте, что конфигурация IP-адресации соответствует планируемой сети. Например, IP 192.168.15.1/32 кажется ограничительным для интерфейсов veth, вам следует использовать более подходящую маску подсети, например, /24.

  2. Маршруты: Перепроверьте, что маршруты действительно позволяют пересылку пакетов между всеми необходимыми узлами. Например, текущий маршрут 192.168.15.1 через 192.168.15.2 должен быть дополнен прямым маршрутом к вашему шлюзу Интернет, например, 10.0.2.2.

  3. Трансляция и переадресация: Проверьте, что включена переадресация IP пакетов, как в системных параметрах, так и в iptables. Кажется, вы уже сделали это (echo 1 > /proc/sys/net/ipv4/ip_forward).

Дополнительно, попробуйте выполнить проверку связи на каждом этапе прохождения пакета (с помощью tcpdump), это поможет локализовать проблему. Например, убедитесь, что между интерфейсами внутри системы есть связь и что пакеты могут выходить за пределы вашего виртуального сетевого пространства.

Частые ошибки и рекомендации:

  1. Проблемы с обработкой DNS: Если маршрутизация для 8.8.8.8 не работает, но ваше сетевое пространство имен может пинговать узлы в локальной сети, дело может быть в DNS. Попробуйте настроить резолверы в вашем пространстве имен (/etc/resolv.conf).

  2. Ошибка в маскарадинге: Убедитесь, что в правилах iptables нет конкретного значения, которое бы нарушало трансляцию. Попробуйте изменить порядок правил.

  3. Ошибка в тестовых действиях: Примите во внимание, что средство traceroute может использовать как ICMP, так и UDP, выберите подходящую опцию (-I для ICMP).

Надеюсь, это анализ поможет вам выявить и устранить причины, не позволяющие вашему сетевому пространству имен подключаться к Интернету. Используйте эти проверки и дополнительно рассмотрите логи, чтобы найти другие потенциальные проблемы.

Оцените материал
Добавить комментарий

Капча загружается...