Вопрос или проблема
Я прочитал другие ответы на этом сайте, прочитал статью и посмотрел видео на эту тему, но все еще не могу подключить свое сетевое пространство имен к внешнему миру.
Настройка
Я создал пространство имен с именем “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), что препятствует вашим попыткам установить соединение с внешними сетями. Давайте рассмотрим каждый аспект настройки и возможные проблемы, которые могут возникнуть.
Теория
Для обеспечения возможности подключения сетевого пространства имен к Интернету обычно требуется несколько шагов:
-
Создание и конфигурация сетевого пространства имен: Вы создаете новое сетевое пространство имен и виртуальные интерфейсы
veth
, связывающие пространство имен с основной сетью вашей системы. -
Назначение IP-адресов и активация интерфейсов: Каждому интерфейсу назначается уникальный IP-адрес, и они переводятся в активное состояние.
-
Настройка маршрутизации: Чтобы пакеты могли проходить между пространством имен и основной сетью, необходимо правильно настроить таблицы маршрутизации.
-
Настройка NAT и переадресации (IP forwarding): Переадресация IP-пакетов и NAT настраиваются для преобразования адресов внутренних сетей в глобально видимые IP-адреса вашей основной сети.
Пример
На основе вашего описания, вы правильно создали сетевое пространство имен и настроили интерфейсы veth
. Однако ошибки могут возникнуть на каждом из этапов настройки.
Проблемы маршрутизации и NAT:
-
Неправильные маршруты: Вы добавили маршруты для связи между пространством имен и глобальной сетью. Однако убедитесь, что маршруты корректны и все интерфейсы имеют корректные настройки.
-
Конфигурация NAT: Настройка команд
iptables
для сетевых правил может быть сложной. Пользователь может ошибиться в синтаксисе правил, что приведет к неправильной трансляции адресов. В вашем случае, убедитесь, что диапазон адресов и интерфейсы в правилахPOSTROUTING
правилах правильны. -
Проблемы с MASQUERADE: Команда
iptables -t nat -A POSTROUTING -s 192.168.15.1/24 -o enp1s0 -j MASQUERADE
должна предполагает использование адресов исходящих соединений, которые может быть неправильно рассчитан. Убедитесь, что ваш основной интерфейс (enp1s0
) правильно настроен как выходной для правил NAT.
Применение
Учитывая ваше описание, давайте рассмотрим эти аспекты более подробно в вашем контексте:
-
Адреса интерфейсов: Проверьте, что конфигурация IP-адресации соответствует планируемой сети. Например, IP
192.168.15.1/32
кажется ограничительным для интерфейсов veth, вам следует использовать более подходящую маску подсети, например,/24
. -
Маршруты: Перепроверьте, что маршруты действительно позволяют пересылку пакетов между всеми необходимыми узлами. Например, текущий маршрут
192.168.15.1 через 192.168.15.2
должен быть дополнен прямым маршрутом к вашему шлюзу Интернет, например,10.0.2.2
. -
Трансляция и переадресация: Проверьте, что включена переадресация IP пакетов, как в системных параметрах, так и в iptables. Кажется, вы уже сделали это (
echo 1 > /proc/sys/net/ipv4/ip_forward
).
Дополнительно, попробуйте выполнить проверку связи на каждом этапе прохождения пакета (с помощью tcpdump
), это поможет локализовать проблему. Например, убедитесь, что между интерфейсами внутри системы есть связь и что пакеты могут выходить за пределы вашего виртуального сетевого пространства.
Частые ошибки и рекомендации:
-
Проблемы с обработкой DNS: Если маршрутизация для 8.8.8.8 не работает, но ваше сетевое пространство имен может пинговать узлы в локальной сети, дело может быть в DNS. Попробуйте настроить резолверы в вашем пространстве имен (
/etc/resolv.conf
). -
Ошибка в маскарадинге: Убедитесь, что в правилах
iptables
нет конкретного значения, которое бы нарушало трансляцию. Попробуйте изменить порядок правил. -
Ошибка в тестовых действиях: Примите во внимание, что средство
traceroute
может использовать как ICMP, так и UDP, выберите подходящую опцию (-I
для ICMP).
Надеюсь, это анализ поможет вам выявить и устранить причины, не позволяющие вашему сетевому пространству имен подключаться к Интернету. Используйте эти проверки и дополнительно рассмотрите логи, чтобы найти другие потенциальные проблемы.