Что я пытаюсь сделать?
Я пытаюсь получить 3 общедоступных IP-адреса через DHCP на одном физическом восходящем кабеле ISP.
Что не так?
Продления идут не так, как надо. Из интерфейсов virtual0 работает нормально, когда он пытается обновить через одноадресное соединение с DHCP-сервером. Интерфейсы virtual1 и virtual2 не работают при одноадресной передаче. Они переходят в резервный режим, чтобы использовать широковещательные рассылки и успешно с ними, но спамят журналы, полные вещей, которые не могут быть хорошими. Я использую Debian 8 и isc-dhcp-client v. 4.3.1.
Я настроил интерфейсы при загрузке следующим образом:
IF_VIRTUAL_BASE=eth0 IF_PUB0=virtual0 IF_PUB1=virtual1 IF_PUB2=virtual2 IF_LAN=eth2 ifconfig "$IF_VIRTUAL_BASE" up ip link add link "$IF_VIRTUAL_BASE" address 00:90:0b:ff:10:5b "$IF_PUB0" type macvlan ip link set "$IF_PUB0" up ip link add link "$IF_VIRTUAL_BASE" address 00:90:0b:ff:11:5b "$IF_PUB1" type macvlan ip link set "$IF_PUB1" up ip link add link "$IF_VIRTUAL_BASE" address 00:90:0b:ff:12:5b "$IF_PUB2" type macvlan ip link set "$IF_PUB2" up # Enable forwarding echo 1 > /proc/sys/net/ipv4/ip_forward
Я тоже делаю unset new_routers
при выполнении dhcprequest для virtual1 и virtual2.
И знаете что, это чудовище работает:
Jul 11 20:45:43 gw dhclient: DHCPREQUEST on virtual0 to 255.255.255.255 port 67 Jul 11 20:45:43 gw dhclient: DHCPREQUEST on virtual1 to 255.255.255.255 port 67 Jul 11 20:45:43 gw ifup[582]: DHCPREQUEST on virtual0 to 255.255.255.255 port 67 Jul 11 20:45:43 gw ifup[592]: DHCPREQUEST on virtual1 to 255.255.255.255 port 67 Jul 11 20:45:43 gw dhclient: DHCPREQUEST on virtual2 to 255.255.255.255 port 67 Jul 11 20:45:43 gw ifup[634]: DHCPREQUEST on virtual2 to 255.255.255.255 port 67 Jul 11 20:45:46 gw dhclient: DHCPREQUEST on virtual1 to 255.255.255.255 port 67 Jul 11 20:45:46 gw ifup[592]: DHCPREQUEST on virtual1 to 255.255.255.255 port 67 Jul 11 20:45:46 gw dhclient: DHCPACK from 88.113.75.2 Jul 11 20:45:46 gw ifup[592]: DHCPACK from 88.113.75.2 Jul 11 20:45:46 gw logger: virtual1 (REBOOT): IP: -> 88.113.75.59; GW: -> 88.113.75.1 Jul 11 20:45:47 gw dhclient: DHCPREQUEST on virtual0 to 255.255.255.255 port 67 Jul 11 20:45:47 gw ifup[582]: DHCPREQUEST on virtual0 to 255.255.255.255 port 67 Jul 11 20:45:47 gw dhclient: DHCPACK from 88.113.75.2 Jul 11 20:45:47 gw ifup[582]: DHCPACK from 88.113.75.2 Jul 11 20:45:47 gw logger: virtual0 (REBOOT): IP: -> 88.113.75.65; GW: -> 88.113.75.1 Jul 11 20:45:50 gw dhclient: DHCPREQUEST on virtual2 to 255.255.255.255 port 67 Jul 11 20:45:50 gw ifup[634]: DHCPREQUEST on virtual2 to 255.255.255.255 port 67 Jul 11 20:45:50 gw dhclient: DHCPACK from 88.113.75.2 Jul 11 20:45:50 gw ifup[634]: DHCPACK from 88.113.75.2 Jul 11 20:45:50 gw logger: virtual2 (REBOOT): IP: -> 88.113.75.61; GW: -> 88.113.75.1
Значит, они работали? И это широковещательные запросы. Хорошо, перемотаем вперед на час или около того, мы получим много такого:
Jul 11 21:45:09 gw dhclient: DHCPREQUEST on virtual2 to 195.74.6.55 port 67 Jul 11 21:45:11 gw dhclient: DHCPREQUEST on virtual1 to 195.74.6.55 port 67 Jul 11 21:45:22 gw dhclient: DHCPREQUEST on virtual2 to 195.74.6.55 port 67 Jul 11 21:45:25 gw dhclient: DHCPREQUEST on virtual1 to 195.74.6.55 port 67 Jul 11 21:45:32 gw dhclient: DHCPREQUEST on virtual1 to 195.74.6.55 port 67 Jul 11 21:45:43 gw dhclient: DHCPREQUEST on virtual2 to 195.74.6.55 port 67 Jul 11 21:45:46 gw dhclient: DHCPREQUEST on virtual1 to 195.74.6.55 port 67 Jul 11 21:45:56 gw dhclient: DHCPREQUEST on virtual2 to 195.74.6.55 port 67 Jul 11 21:46:05 gw dhclient: DHCPREQUEST on virtual1 to 195.74.6.55 port 67 Jul 11 21:46:11 gw dhclient: DHCPREQUEST on virtual2 to 195.74.6.55 port 67 Jul 11 21:46:21 gw dhclient: DHCPREQUEST on virtual1 to 195.74.6.55 port 67 Jul 11 21:46:30 gw dhclient: DHCPREQUEST on virtual2 to 195.74.6.55 port 67 Jul 11 21:46:33 gw dhclient: DHCPREQUEST on virtual1 to 195.74.6.55 port 67 Jul 11 21:46:42 gw dhclient: DHCPREQUEST on virtual2 to 195.74.6.55 port 67 Jul 11 21:46:47 gw dhclient: DHCPREQUEST on virtual1 to 195.74.6.55 port 67 Jul 11 21:47:00 gw dhclient: DHCPREQUEST on virtual2 to 195.74.6.55 port 67 Jul 11 21:47:01 gw dhclient: DHCPREQUEST on virtual1 to 195.74.6.55 port 67 Jul 11 21:47:09 gw dhclient: DHCPREQUEST on virtual1 to 195.74.6.55 port 67
Интерфейсы virtual1 и virtual2 отчаянно пытаются обновить свои IP-адреса через одноадресное соединение с предыдущим DHCP-сервером 195.74.6.55. Они не работают с одноадресной передачей. Но потом происходит что-то забавное, в конце концов они переключаются на трансляцию как запасной вариант и преуспевают!
Jul 11 22:30:41 gw dhclient: DHCPREQUEST on virtual1 to 195.74.6.55 port 67 Jul 11 22:30:47 gw dhclient: DHCPREQUEST on virtual2 to 195.74.6.55 port 67 Jul 11 22:30:52 gw dhclient: DHCPREQUEST on virtual1 to 255.255.255.255 port 67 Jul 11 22:30:52 gw dhclient: DHCPACK from 88.113.75.2 Jul 11 22:30:52 gw logger: virtual1 (RENEW): IP: 88.113.75.59 -> 88.113.75.59; GW: 88.113.75.1 -> 88.113.75.1 Jul 11 22:30:58 gw dhclient: DHCPREQUEST on virtual2 to 255.255.255.255 port 67 Jul 11 22:30:58 gw dhclient: DHCPACK from 88.113.75.2 Jul 11 22:30:59 gw logger: virtual2 (RENEW): IP: 88.113.75.61 -> 88.113.75.61; GW: 88.113.75.1 -> 88.113.75.1
Обратите внимание на интерфейс virtual0:
Jul 11 22:38:17 gw dhclient: DHCPREQUEST on virtual0 to 195.74.6.55 port 67 Jul 11 22:38:18 gw dhclient: DHCPACK from 195.74.6.55 Jul 11 22:38:18 gw logger: virtual0 (RENEW): IP: 88.113.75.65 -> 88.113.75.65; GW: 88.113.75.1 -> 88.113.75.1
Вывод состоит в том, что для интерфейса virtual0 работают одноадресные (dhclient) DHCP-запросы, а для virtual1 и virtual2 работают только широковещательные обновления DHCP. Значит, это проблема маршрутизации? Вот что показывает IP-маршрут после обычной загрузки:
root@gw:~# ip route default via 88.113.75.1 dev virtual0 88.113.75.0/24 dev virtual0 proto kernel scope link src 88.113.75.65 88.113.75.0/24 dev virtual1 proto kernel scope link src 88.113.75.59 88.113.75.0/24 dev virtual2 proto kernel scope link src 88.113.75.61 172.16.8.0/28 via 172.16.8.2 dev tun0 # For openvpn 172.16.8.0/24 dev eth2 proto kernel scope link src 172.16.8.254 # For LAN 172.16.8.2 dev tun0 proto kernel scope link src 172.16.8.1 #For openvpn
Как заставить dhclients на интерфейсах на основе macvlan virtual1 и virtual2 правильно маршрутизировать свои одноадресные запросы на обновление и получать ответы соответствующим образом?
Я выполнил множество поисков в Google, попытался перевернуть многие настройки, включая политики брандмауэра, маршрутизацию на основе политик, режим eth0 promisc и переменные sysctl, урезав общие настройки сети и т. Д. В настоящее время я выполняю strace для dhclient. Одна комбинация этих настроек должна работать. Если потребуется дополнительная информация, я буду более чем счастлив предоставить ее.
РЕДАКТИРОВАТЬ1: dhclient strace стал готов.
Это происходит в самом начале:
bind(5, {sa_family=AF_PACKET, proto=0x7669, if1635087474, pkttype=PACKET_HOST, addr(0)={12652, }, 16) = 0 bind(6, {sa_family=AF_INET, sin_port=htons(68), sin_addr=inet_addr("0.0.0.0")}, 16) = 0 sendto(5, "......", 342, 0, {sa_family=AF_PACKET, proto=0x7669, if1635087474, pkttype=PACKET_HOST, addr(0)={12652, }, 18) = 342
«Sendto (5», насколько я понимаю, был первой успешной отправкой dhclient на основе широковещательной рассылки.
Затем, позже первая неудачная одноадресная отправка:
sendto(6, "......", 300, 0, {sa_family=AF_INET, sin_port=htons(67), sin_addr=inet_addr("195.74.6.55")}, 16) = 300
И следующий успешный широковещательный отправляем:
sendto(5, "......", 342, 0, {sa_family=AF_PACKET, proto=0x7669, if1635087474, pkttype=PACKET_HOST, addr(0)={12652, }, 18) = 342
Я смог это исправить! Немного неортодоксальным образом, но все же.
Так что я сделал? Я просто удалил isc-dhcp-client 4.3.1 и установил dhcpcd 6.0.5 (от Роя Марплеса, имя пакета debian dhcpcd5). Вот и все.
Я перезагрузил компьютер примерно в 23:00 и проверил, все ли интерфейсы в порядке, затем запустил tcpdump. Примерно в 00:02 истекает срок действия одного из таймеров DHCP, и все 3 интерфейса аккуратно получают свои IP-адреса без каких-либо вопросов:
https://i.stack.imgur.com/xGQpq.png
В основном мне не нужно было ничего менять в /etc/dhcpcd.conf. Похоже, что dhcpcd построен умнее, чем dhclient. По крайней мере, по моему сценарию.
(Примечание: я должен сказать, что было довольно легко перейти с isc-dhcp-client на dhcpcd. Debian 8 имел встроенную поддержку; кажется, если вы установите dhcpcd5, удалите isc-dhcp-client и перезагрузитесь, система подберет новый клиент автоматически. Что касается сценариев, кажется, что нет каталога сценариев для dhcpcd, но один файл для всех обработчиков ввода и один файл для всех обработчиков выхода. Файлы были названы: /etc/dhcpcd.enter-hook и / etc / dhcpcd. exit-hook. Если вы поместите в эти файлы скрипты хуков dhclient, они будут работать без изменений. Я впечатлен!)