У меня есть сервер виртуализации KVM в Hetzner. Hetzner предоставляет мне главный IP-адрес (95.xxx.xxx.235), подсеть / 29 IPv4 (95.xxx.xxx.184 / 29) и сеть / 64 IPv6 (2a01: xxxx: xxxx: xxxx :: / 64).
KVM Guest (Debian Stretch) теряет возможность подключения по IPv6 ровно через 20 минут после перезагрузки при перезапуске сетевых служб. Даже если соединение потеряно, я могу пропинговать шлюз по умолчанию (fe80 :: 1). Подключение по IPv4 работает постоянно и без проблем.
В настоящее время интерфейс настроен как macvlan в режиме моста, и я также безуспешно пробовал VEPA и частные режимы. Также тип NIC установлен на e1000, но я тоже пробовал virtio, но безуспешно.
После потери соединения я взял дамп TCP с физического сетевого адаптера на хосте, и он показывает, что есть эхо-запросы и приходят эхо-ответы на интерфейс, но tcpdump, взятый с гостевой сетевой карты, я мог видеть только запросы, выходящие из NIC.
/ etc / network / interfaces на хосте:
auto lo
iface lo inet loopback
iface lo inet6 loopback
auto enp2s0
iface enp2s0 inet static
address 95.xxx.xxx.235
netmask 255.255.255.192
gateway 95.xxx.xxx.193
up route add -net 95.xxx.xxx.192 netmask 255.255.255.192 gw 95.xxx.xxx.193 dev enp2s0
iface enp2s0 inet6 static
address 2a01:xxx:xxx:xxx::2
netmask 64
gateway fe80::1
/ etc / network / interfaces в гостевой системе:
auto lo
iface lo inet loopback
iface lo inet6 loopback
auto ens3
iface ens3 inet static
address 95.xxx.xxx.187
netmask 255.255.255.248
gateway 95.xxx.xxx.185
iface ens3 inet6 static
address 2a01:xxx:xxx:xxx::20
netmask 64
gateway fe80::1
# route -6 -n на хосте:
Kernel IPv6 routing table
Destination Next Hop Flag Met Ref Use If
2a01:xxxx:xxxx:xxxx::/64 :: U 256 8 1162 enp2s0
fe80::/64 :: U 256 0 0 macvtap0
fe80::/64 :: U 256 0 0 enp2s0
::/0 fe80::1 UG 1024 8 4534 enp2s0
::/0 :: !n -1 1 11069 lo
::1/128 :: Un 0 9 81 lo
2a01:xxxx:xxxx:xxxx::/128 :: Un 0 1 0 lo
2a01:xxxx:xxxx:xxxx::2/128 :: Un 0 9 82 lo
fe80::/128 :: Un 0 1 0 lo
fe80::/128 :: Un 0 1 0 lo
fe80::/128 :: Un 0 1 0 lo
fe80::xxxx:xxxx:xxxx:1069/128 :: Un 0 1 0 lo
fe80::xxxx:xxxx:xxxx:22e1/128 :: Un 0 1 0 lo
fe80::xxxx:xxxx:xxxx:201/128 :: Un 0 2 79 lo
ff00::/8 :: U 256 0 0 macvtap0
ff00::/8 :: U 256 0 0 enp2s0
::/0 :: !n -1 1 11069 lo
# route -6 -n для гостя:
Kernel IPv6 routing table
Destination Next Hop Flag Met Ref Use If
2a01:xxxx:xxxx:1414::/64 :: U 256 0 0 ens3
fe80::/64 :: U 256 0 0 ens3
::/0 fe80::1 UG 1024 2 77 ens3
::/0 :: !n -1 1 6846 lo
::1/128 :: Un 0 5 525 lo
2a01:xxxx:xxxx:xxx::20/128 :: Un 0 3 70 lo
fe80::xxxx:xxxx:xxx:22e1/128 :: Un 0 2 6 lo
ff00::/8 :: U 256 0 0 ens3
::/0 :: !n -1 1 6846 lo
# ip -6 neigh на хосте:
2a01:xxxx:xxxx:xxxx::20 dev enp2s0 FAILED
fe80::1 dev enp2s0 lladdr xx:xx:xx:8d:22:06 router STALE
# ip -6 neigh on Guest:
fe80::1 dev enp2s0 lladdr xx:xx:xx:8d:22:06 router REACHABLE
Вероятно, актуальные вещи из /etc/sysctl.conf на хосте:
net.ipv4.ip_forward=1
net.ipv4.conf.enp2s0.send_redirects=0
net.ipv6.conf.all.forwarding=1
Возможно, уместные вещи из /etc/sysctl.conf в гостевой системе:
net.ipv6.conf.default.accept_ra=2
net.ipv6.conf.default.autoconf=1
net.ipv6.conf.all.accept_ra=2
net.ipv6.conf.all.autoconf=1
net.ipv6.conf.ens3.accept_ra=2
net.ipv6.conf.ens3.autoconf=1
Вероятно, соответствующий раздел гостевой libvirt-config:
<interface type='direct' trustGuestRxFilters='yes'>
<mac address='xx:xx:xx:xx:xx:xx'/>
<source dev='enp2s0' mode='bridge'/>
<model type='e1000'/>
<address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/>
</interface>
Поскольку я боролся с этим около двух недель и читал почти все соответствующие сообщения с аналогичными проблемами, я видел, что Hetzner, по-видимому, делает какие-то подозрительные реализации IPv6. Я уже связывался с ними, но они поинтересовались, что у меня самого возникнет проблема с маршрутизацией. Это может быть правдой, поскольку через 20 минут я все еще получаю эхо-ответы на физическом NIC, даже если они не пересылаются гостю.
Итак, есть идеи от коллег по IPv6?
Обновить:
Итак, Хетцнер подтвердил мне, что сеть 2a01: xxxx: xxxx: xxxx :: / 64 маршрутизируется на локальный адрес физического интерфейса. При перезапуске сети запись NDP остается в течение 20 минут, но впоследствии удаляется, поскольку виртуальная машина не отвечает с правильным локальным адресом канала, так как у нее другой MAC-адрес.
Начинает казаться, что я не могу использовать здесь интерфейсы macvtap, но я должен создать для этого мост. Однако мне интересно, почему хост не может видеть гостя (и наоборот) с IPv6, когда IPv4 все еще работает. Думаю, это позволит мне направлять трафик прямо с основного локального адреса ссылки.
У меня была такая же проблема с сервером Hetzner, но с использованием VirtualBox вместо KVM.
Проблема:
Hetzner направляет все пакеты IPv6, имеющие любой целевой IP-адрес в вашей подсети / 64, на MAC-адрес вашего физического хоста. Это означает, что если вы отправляете эхо-запрос откуда-то из Интернета на свою виртуальную машину, у которой есть IPv6-адрес с тем же префиксом, что и у хоста, шлюз Hetzer не запрашивает соседа для поиска MAC-адреса вашей виртуальной машины, а просто пересылает ICMP пакеты к MAC вашего хоста. Это причина, по которой вы можете видеть эхо-ответы на вашем физическом хосте, но не на вашей виртуальной машине: они нацелены на MAC вашего хоста, а не на MAC виртуальной машины.
Однако, похоже, есть ошибка в реализации IPv6 Hetzner (или это может быть сделано специально, я не знаю): если виртуальная машина отправляет запрос соседу для поиска MAC-адреса шлюза (fe80 :: 1) и он использует свой глобальный IPv6 IP в качестве исходного адреса запроса, каким-то образом шлюз Hetzner, кажется, обновляет свою внутреннюю таблицу IPv6-to-MAC-адресов. В течение следующих 20 минут шлюз Hetzner будет отправлять любой пакет, предназначенный для IPv6-адреса виртуальных машин, на MAC-адрес виртуальных машин. Если в течение 20 минут никакие дальнейшие запросы от MAC-адреса виртуальной машины и глобального IP-адреса виртуальной машины не отправляются на шлюз, он возвращается к отправке пакетов IPv6 на MAC-адрес хоста.
Теперь ваша виртуальная машина - сразу после запуска сети, возможно из-за того, что локальный адрес канала не назначен на этом этапе - ONCE отправляет запрос, используя свой глобальный адрес IPv6 в качестве источника, и поэтому «случайно» обновляет таблицу MAC-адресов Hetzner на этот раз. Во время выполнения виртуальная машина по-прежнему непрерывно отправляет запросы на поиск MAC-адреса шлюза, чтобы поддерживать его таблицу MAC-адресов в актуальном состоянии, но для этого использует свой локальный IPv6-адрес (что вполне нормально с точки зрения IPv6), но которые не будут обновлять таблицу MAC-адресов Hetzner Gatway. По этой причине после запуска виртуальной машины IPv6 кажется полностью работоспособным, но только в течение 20 минут.
Решения:
Есть грязный раствор и чистый раствор:
Грязное решение: ваша виртуальная машина должна время от времени отправлять запрос на получение MAC-адреса шлюза, используя его глобальный IPv6-адрес (скажем, каждые 5 минут). Это сложно: ваша виртуальная машина будет отправлять запросы, но с использованием локального IPv6. Итак, я использовал дешевый трюк: я удаляю локальный IP-адрес из интерфейса, отправляю запрос (который затем принудительно использует глобальный IP-адрес) и повторно присоединяю локальный IP-адрес:
ip -6 addr del fe80::a00:27ff:fecf:e270/64 dev enp0s3
ndisc6 fe80::1 enp0s3
ip -6 addr add fe80::a00:27ff:fecf:e270/64 dev enp0s3
Чистое решение: не используйте перемычку. Теперь я использую Host-only-Networking. Это означает, что виртуальная машина подключена к отдельному сетевому адаптеру (vboxnet0). Я добавил маршрут IPv6, который перенаправляет весь трафик с хоста на IPv6-адрес виртуальной машины:
ip -6 route add <my IPv6 pefix>::20 dev vboxnet0
На виртуальной машине я использую локальный IPv6-адрес хоста в качестве GW по умолчанию. Чтобы позволить хосту подключать виртуальную машину к глобальному IPv6 IP, я назначил другой IP из той же подсети / 64 для vboxnet0. Для меня это отлично работает.