- Вопрос или проблема
- Предисловие
- НАСТРОЙКА ХОСТА
- НАСТРОЙКА ГОСТЯ
- теперь ГОСТЬ/ХОСТ могут пинговать друг друга, и vGUEST может пинговать за пределами машины
- Ответ или решение
- Почему veth не отвечает на ARP-запросы?
- Введение
- Основные аспекты работы veth
- Проблемы с ARP и возможные причины
- Пример настройки veth
- Заключение
Вопрос или проблема
Я решил поиграть с veth: создать пару veth и отправить ping с одного конца на другой.
$ ip link add type veth
$ ip addr add 192.168.99.1 dev veth4
$ ip addr add 192.168.99.2 dev veth5
$ ip link dev veth4 set up
$ ip link dev veth5 set up
Проверим.
$ ip a
18: veth4: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
link/ether 6a:dc:02:5b:f0:f3 brd ff:ff:ff:ff:ff:ff
inet 192.168.99.1/24 scope global veth4
valid_lft forever preferred_lft forever
19: veth5: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
link/ether 22:ec:d5:e8:7c:3e brd ff:ff:ff:ff:ff:ff
inet 192.168.99.2/24 scope global veth5
valid_lft forever preferred_lft forever
Все, кажется, в порядке. Теперь попробуем выполнить ping.
$ ping -I veth4 192.168.99.2
PING 192.168.99.2 (192.168.99.2) from 192.168.99.1 veth4: 56(84) bytes of data.
From 192.168.99.1 icmp_seq=1 Host-назначения недоступен
From 192.168.99.1 icmp_seq=2 Host-назначения недоступен
From 192.168.99.1 icmp_seq=3 Host-назначения недоступен
$ sudo tshark -i veth5
Захват на 'veth5'
l 1 0.000000 6a:dc:02:5b:f0:f3 -> Broadcast ARP 42 Кто имеет 192.168.99.2? Сообщите 192.168.99.1
1 2 1.003206 6a:dc:02:5b:f0:f3 -> Broadcast ARP 42 Кто имеет 192.168.99.2? Сообщите 192.168.99.1
Так что veth5 получает запросы arp, но не отвечает. В чем дело?
Это очень сложный, очень старый вопрос, который включает в себя несколько разных областей, в частности VETH, пространство имен сети, ARP, таблицы маршрутизации и NAT…
Я добавляю ответ на эту проблему не только для автора поста, но и для других, надеюсь, это сэкономит кому-то время и нервы, которые она мне стоила…
Достаточно сказать, после многочисленных исследований и тестирования — пары veth можно использовать именно так, так как они буквально два отдельных виртуальных интерфейса. Однако, поскольку они виртуальные — вы столкнетесь с некоторыми действительно странными проблемами относительно таблиц ARP/записей. После нескольких недель работы с этой конкретной ситуацией (необходимой для работы) я выяснил, как это сделать, а в процессе узнал гораздо больше о ARP, NAT и маршрутизации, чем хотел бы.
Чтобы выполнить именно то, что вы хотите, наберите следующее (в моем случае, Ubuntu 16.04). Обратите внимание, что, как только вы находитесь в пространстве имен test
, вам нужно выйти из bash, чтобы покинуть его, так как все (таблицы маршрутизации, iptables и т. д.) с этого момента отличаются от машин-хозяев. Обычно я открываю два терминала, один из которых остается на хосте — другой остаётся в пространстве имен гостя.
Предисловие
# Скажите системе, что мы хотим поддержать IPv4 переадресацию
добавьте/подтвердите, что следующее находится в `/etc/sysctl.conf`
`net.ipv4.ip_forward = 1`
# если этого не было, переразобрать sysctl + перезапустите сетевые службы
sysctl -p;
/etc/init.d/networking restart;
НАСТРОЙКА ХОСТА
# создайте пару veth
ip link add name vHOST type veth peer name vGUEST
# выберите частный MAC-адрес и частный IP-адрес
ifconfig vHOST hw ether 02:1d:8d:dd:0c:61
ifconfig vHOST 10.11.0.1/24 up
# необходимо настроить маршруты ОТ ХОСТА -> ГОСТЮ
ip route add 10.111.0.0/24 via 10.11.0.1 dev vHOST # шлюз
# необходимо явно назначить, какой MAC-адрес для vGUEST в таблице ARP интерфейса vHOST
arp -i vHOST -s 10.111.0.1 02:1d:8d:dd:0c:60 # ip vGUEST + MAC-адрес
# Мы должны сказать "туннелю" vHOST-vGUEST, что это не настоящий мост, поэтому любые запросы ARP должны обрабатываться vHOST
echo 1 > /proc/sys/net/ipv4/conf/vHOST/proxy_arp
# настройте переадресацию + NAT (чтобы пакеты могли возвращаться)
iptables -A FORWARD -s 10.111.0.0/24 -o vHOST -j ACCEPT
iptables -t nat -A POSTROUTING -s 10.111.0.1 -j SNAT --to 192.168.42.124
НАСТРОЙКА ГОСТЯ
# создайте пространство имен "test", чтобы мы могли проверить настройки
ip netns add test
# добавьте "интерфейс" vGUEST в пространство имен "test"
ip link set vGUEST netns test
# войдите в пространство имен "test" с помощью оболочки bash
ip netns exec test bash
# выберите частный MAC-адрес и частный IP-адрес
ifconfig vGUEST hw ether 02:1d:8d:dd:0c:60
ifconfig vGUEST 10.111.0.1/24 up
# необходимо настроить маршруты ОТ ГОСТЯ -> ХОСТА
ip route add default via 10.111.0.1 dev vGUEST # шлюз
# необходимо явно назначить, какой MAC-адрес для vHOST в таблице ARP интерфейса vGUEST
arp -i vGUEST -s 10.11.0.1 02:1d:8d:dd:0c:61 # ip vHOST + MAC-адрес
теперь ГОСТЬ/ХОСТ могут пинговать друг друга, и vGUEST может пинговать за пределами машины
Особенно стоит отметить, что multimac может делать то же самое, что и veth, несколько другим способом, поскольку multimac поддерживает отношения “много к одному”, в то время как veth — это “один к одному”.
Чтобы поддерживать это без пространств имен, вам нужно использовать маршрутизацию политик (что немного сложнее, чем пространства имен сети).
Пары veth не используются таким образом. Пара veth — это буквально трубопровод устройства, один конец, из которого пакеты выходят, а другой — это конец, куда они уходят.
Самый простой синоним, который я могу предложить, — это представить, что одна половина пары — это устройство Ethernet, в то время как другой конец — это порт коммутатора, в который подключено устройство. Не следует рассматривать пару как два отдельных устройства, а как одно устройство, у которого есть два “конца” для передачи/приема.
попробуйте установить эти параметры:
echo 1 > /proc/sys/net/ipv4/conf/all/accept_local
echo 1 > /proc/sys/net/ipv4/conf/default/accept_local
echo 1 > /proc/sys/net/ipv4/conf/veth4/accept_local
echo 1 > /proc/sys/net/ipv4/conf/veth5/accept_local
echo 0 > /proc/sys/net/ipv4/conf/all/rp_filter
echo 0 > /proc/sys/net/ipv4/conf/default/rp_filter
echo 0 > /proc/sys/net/ipv4/conf/veth4/rp_filter
echo 0 > /proc/sys/net/ipv4/conf/veth5/rp_filter
Для интерфейсов veth вам нужно немного изменить правило ip:
без arp, без ответа ping и т.д.
# ip rule
0: from all lookup local
1000: from all lookup [l3mdev-table]
32766: from all lookup main
32767: from all lookup default
После перемещения lookup local после l3mdev veth работает корректно
# ip rule
1000: from all lookup [l3mdev-table]
32000: from all lookup local
32766: from all lookup main
32767: from all lookup default
Вы можете отключить ARP с помощью ip link set arp off dev <veth>
, но с включенным lookup local удаленный veth в том же netns не будет отвечать на свой собственный трафик…
Вы можете сделать это без пространств имен. Убедитесь, что вы установили accept_local в 1, если вы пойдете этим путем.
ip link add name br0 type bridge
ip link add veth10 type veth peer name veth11
ip link add veth20 type veth peer name veth21
ip link set veth10 master br0
ip link set veth20 master br0
ip link set veth10 up
ip link set veth20 up
ip link set veth11 up
ip link set veth21 up
ip link set br0 up
ip addr add 192.168.1.1/24 dev veth11
ip addr add 192.168.1.2/24 dev veth21
echo 1 > /proc/sys/net/ipv4/conf/veth11/accept_local
echo 1 > /proc/sys/net/ipv4/conf/veth21/accept_local
# тестируем подключение veth11 -> veth12
ping 192.168.1.2 -I veth11
ping 192.168.1.1 -I veth21
Согласно документам ядра doc
accept_local - BOOLEAN
Принимать пакеты с локальными адресами источников. В комбинации с
подходящей маршрутизацией это можно использовать для направления пакетов между двумя
локальными интерфейсами по проводу и их правильного принятия.
по умолчанию FALSE
Ответ или решение
Почему veth не отвечает на ARP-запросы?
Введение
Работа с виртуальными Ethernet (veth) парами в Linux предоставляет множество возможностей для настройки сетевых взаимодействий. Однако, пользователи часто сталкиваются с проблемами, такими как отсутствие ответа на ARP-запросы, когда они пытаются установить связь между двумя концами veth-пары. Данная статья рассмотрит основные причины данного поведения и предложит решения.
Основные аспекты работы veth
veth-пары представляют собой два связанных виртуальных интерфейса, которые в основном функционируют как трубы: данные, отправленные на один интерфейс, появятся на другом. Это делает их идеальными для тестирования сетевых приложений, контейнеризации и других сценариев.
Однако, настройка сетевых параметров для этих интерфейсов может быть сложной, особенно в отношении ARP. ARP (Address Resolution Protocol) используется для сопоставления IP-адресов и MAC-адресов в локальной сети. Если ARP-запросы не обрабатываются должным образом, это может привести к невозможности установления соединения, как в вашем случае.
Проблемы с ARP и возможные причины
-
Настройки локальной обработки пакетов:
Многие дистрибутивы Linux по умолчанию не принимают локальные пакеты, что может вызвать проблемы с ARP. Для решения этой проблемы можно задать параметрaccept_local
в следующем формате:echo 1 > /proc/sys/net/ipv4/conf/veth4/accept_local echo 1 > /proc/sys/net/ipv4/conf/veth5/accept_local
-
Маршрутизация и таблицы маршрутов:
Неправильно настроенные таблицы маршрутизации могут также быть источником проблемы. Убедитесь, что маршруты настроены корректно для обеих сторон veth-пары. Это можно сделать командой:ip route add 192.168.99.0/24 dev veth4 ip route add 192.168.99.0/24 dev veth5
-
Фильтрация пакетов (rp_filter):
Такие параметры, какrp_filter
, могут препятствовать правильной обработке пакетов. Убедитесь, чтоrp_filter
отключен для обоих интерфейсов:echo 0 > /proc/sys/net/ipv4/conf/veth4/rp_filter echo 0 > /proc/sys/net/ipv4/conf/veth5/rp_filter
-
Настройки пространств имён (Namespaces):
Если вы работаете с пространствами имён (network namespaces), это может усложнить обработку ARP. ARP-запросы могут не обрабатываться, если вы находитесь в различных пространствах имен. Убедитесь, что оба интерфейса находятся в одном пространстве имён, или настройте маршрутизацию и NAT, чтобы обеспечить взаимодействие между ними.
Пример настройки veth
Для успешной настройки veth-пары и обеспечения корректной работы ARP можно использовать следующий пример:
# Создание пары veth
ip link add name veth0 type veth peer name veth1
# Настройка IP-адресов и активация интерфейсов
ip addr add 192.168.99.1/24 dev veth0
ip addr add 192.168.99.2/24 dev veth1
ip link set veth0 up
ip link set veth1 up
# Убедитесь, что accept_local и rp_filter настроены
echo 1 > /proc/sys/net/ipv4/conf/veth0/accept_local
echo 1 > /proc/sys/net/ipv4/conf/veth1/accept_local
echo 0 > /proc/sys/net/ipv4/conf/veth0/rp_filter
echo 0 > /proc/sys/net/ipv4/conf/veth1/rp_filter
Заключение
Проблемы с ответом на ARP-запросы между veth-интерфейсами могут быть вызваны рядом факторов, включая настройки локальной обработки пакетов, маршрутизации и конфигурации фильтрации. Правильная настройка параметров позволит вам обеспечить корректную работу veth-пары и успешное выполнение сетевых операций, таких как пинг. Если у вас возникли дополнительные вопросы или проблемы, рекомендуется ознакомиться с документацией по сетевым интерфейсам в Linux или обратиться за помощью к сообществу.