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

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

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

Настройка

Я создал неймспейс под названием “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-интерфейса, который подключает VM к внешнему миру изнутри “foo”.

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

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).

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

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

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

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

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

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

Теория

Сетевые неймспейсы позволяют изолировать сетевые стеки, позволяя работать нескольким независимым сетевым конфигурациям на одном устройстве. Таким образом можно запускать изолированные сервисы или приложения, которые не взаимодействуют друг с другом напрямую. Однако, сама по себе изоляция несёт в себе определенные сложности при необходимости доступа к глобальной сети Интернет.

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

  1. Обеспечить, чтобы пакеты данных из неймспейса попадали на интерфейс, связанный с глобальной сетью.
  2. Настроить бриджинг или маршрутизацию между виртуальным и физическим интерфейсом.
  3. Применить IP-маскарадинг, чтобы пакеты, выходящие из неймспейса, могли получить обратную связь от адресатов в Интернете.

Пример

На практике вы уже создали пару виртуальных Ethernet-устройств veth, с одной стороной в неймспейсе "foo". Настроили IP-адреса и подняли интерфейсы, что позволило взаимодействовать между главным пространством имён и "foo". Тем не менее, когда вы пытаетесь достичь внешних адресов, как например, 8.8.8.8, вы сталкиваетесь с проблемой: "Destination Host Unreachable".

Реализация

Давайте разберемся, в чем может быть причина.

  1. IP-маскарад: Вы правильно задали команду для маскарадинга:

    iptables -t nat -A POSTROUTING -s 192.168.15.1/24 -o enp1s0 -j MASQUERADE

    Однако, возможно, стоит проверить сам NAT-тэйбл для других правил, которые могут блокировать доступ.

  2. Маршрутизация: Проверьте маршруты, особенно маршрут по умолчанию в неймспейсе "foo".

    ip -n foo route

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

  3. IP-адресация: Обратите внимание на формат ваших IP-адресов. На устройстве veth-out у вас адрес:

    inet 192.168.15.2/32 scope global veth-out

    <prefix>/32 здесь может ограничивать адрес совокупности, так как используется одиночный хостовой адрес. Попробуйте изменить на /24.

    ip addr add 192.168.15.2/24 dev veth-out 
  4. Корректное сетевое соединение между veth-out и физическим интерфейсом enp1s0. Проверьте, что маршруты на физическом интерфейсе корректны и интерфейс видит внешние сети:

    ip route

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

  5. Проутинг и трансляция. Проверьте, что интерфейс enp1s0 настраивает внешнюю маршрутизацию и соединение работает правильно через стек TCP/IP.

  6. Диагностика через tcpdump позволяет мониторить попытки пакетов ICMP, что может указать на проблемы в самой маршрутизации. Поскольку данные не достигали enp1s0, необходимо попробовать иные варианты отладки.

Заключение

Корректная настройка сети — важный и тонкий процесс. В вашем случае, возможно, проблема с маршрутизацией либо маскарадом. Проверьте индивидуальные компоненты и взаимодействие между ними. Возможно, ошибка лежит в классе IP-адресов или распределении маски.

Надеюсь, этот детальный разбор поможет вам в поиске и устранении проблемы.

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

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