Во-первых, я знаю, что вопросы, подобные моему, задавались в других местах (я прочитал многие из этих сообщений!), но я не смог найти решение своей проблемы, поэтому Я прошу помощи.
В моей локальной сети есть две сети: 192.168.0.0/24 и 10.11.12.0/24. Первый использует DHCP на моем WAN-маршрутизаторе, второй запускает dnsmasq на Ubuntu Server 20.04 на компьютере, который также служит маршрутизатором между двумя подсетями. Я настроил dnsmasq для обслуживания DHCP только на 10.11.12.0/24 с параметром no-dhcp-interface=wlp3s0, где wlp3s0 — это интерфейс на стороне 192.168.0.0/24.
Подводя итог:
WAN Router (gateway to WAN) is 192.168.0.1/24
Runs DHCP for clients on 192.168.0.0/24
Router (b/w subnets):
Ubuntu Server 20.04 with two interfaces
wlp3s0: 192.168.0.2/24 (static IP)
eno1: 10.11.12.1/24 (static IP)
Я настроил iptables для FWD и NAT следующим образом.
iptables -t nat -A POSTROUTING -o wlp3s0 -j MASQUERADE
iptables -A FORWARD -i wlp3s0 -o eno1 -m state --state RELATED,ESTABLISHED -j ACCEPT
iptables -A FORWARD -i eno1 -o wlp3s0 -j ACCEPT
Я разрешил DHCP через брандмауэр с помощью ufw allow 67/udp
:
To Action From
-- ------ ----
67/udp ALLOW IN Anywhere
Все работает нормально. Однако по опыту я знаю, что запуск двух таких DHCP-серверов может вызвать конфликты, если они не строго разделены. (Клиенты, предназначенные для сети 192.168.0.0/24, не были бы слишком довольны, если бы DHCP предоставил им IP-адрес в сети 10.11.12.0/24!)
Поэтому я сделал следующее, чтобы проверить это. Я настроил прослушивание tcpdump на интерфейсе wlp3s0 (192.168.0.2) и использовал nmap для имитации запроса DHCP Discover, исходящего от интерфейса eno1 (10.11.12.1/24), например так:
sudo tcpdump -i wlp3s0 -n udp port 67 or port 68
sudo nmap --script broadcast-dhcp-discover -e eno1
Как и ожидалось, я получаю предложение DHCP из dnsmasq, работающего на 10.11.12.1. Все идет нормально!
Некоторые детали опущены в выводе для краткости (он сказал)
Starting Nmap 7.80 ( https://nmap.org ) at 2021-12-22 16:19 UTC
Pre-scan script results:
| broadcast-dhcp-discover:
| Response 1 of 1:
| IP Offered: 10.11.12.53
| DHCP Message Type: DHCPOFFER
| Server Identifier: 10.11.12.1
| Broadcast Address: 10.11.12.255
| Subnet Mask: 255.255.255.0
| Domain Name Server: 10.11.12.1
|_ Router: 10.11.12.1
Однако tcpdump показывает, что оба DHCP-сервера отвечают на запрос обнаружения. (На самом деле, мой WAN-маршрутизатор отправляет 2 ответа!)
16:19:43.517029 IP 10.11.12.1.68 > 255.255.255.255.67: BOOTP/DHCP, Request from de:ad:c0:de:ca:fe, length 316
16:19:46.486227 IP 10.11.12.1.67 > 255.255.255.255.68: BOOTP/DHCP, Reply, length 321
16:19:46.794207 IP 192.168.0.1.67 > 255.255.255.255.68: BOOTP/DHCP, Reply, length 323
16:19:46.794207 IP 192.168.0.1.67 > 255.255.255.255.68: BOOTP/DHCP, Reply, length 323
Похоже, что запрос на обнаружение DHCP перенаправляется в сеть 192.168.0.0/24 через интерфейс wlp3s0. Глядя на мои правила iptables и брандмауэра, я не вижу причин этому удивляться. Однако то, с чем я действительно борюсь, - это выяснить, как это предотвратить.
Я пробовал различные перестановки правил как в ufw, так и в iptables, но безрезультатно, вероятно, потому, что я не до конца понимаю ни iptables, ни ufw.Несколько примеров того, что я пробовал:
(Все правила ufw/iptables были добавлены вверху соответствующего набора/цепочки правил, чтобы гарантировать, что они будут выполнены.)
ufw:
# Restrict 67/udp to one interface
ufw allow in on eno1 proto udp from 0.0.0.0/0 to 0.0.0.0/0 port 67
# Deny routing
ufw route deny in on eno1 out on wlp3s0 to 0.0.0.0/0 port 67 proto udp
iptables:
# Prevent forwarding of UDP port 67/68
iptables -I FORWARD 1 -p udp --match multiport --dports 67,68 -j DROP
# Drop outbound UDP port 67
iptables -I OUTPUT 1 -p udp --match multiport --dports 67,68 -o wlp3s0 -j DROP
I must отсутствует некоторое фундаментальное понимание того, как это работает, поскольку ничто из вышеперечисленного не мешает DHCP-маршрутизатору WAN получать обнаружение и предлагать IP-адрес в подсети 192.168.0.0/24.
Я где-то читал, что DHCP-серверы могут прослушивать необработанные (или пакетные?) сокеты, которые не подчиняются iptables. Это не относится к dnsmasq, как описано здесь https://github.com/imp/dnsmasq/blob/master/FAQ#L195. Я также доказал это, удалив правило allow 67/udp в ufw, после чего dnsmasq перестает отвечать на обнаружение DHCP. Возможно, это удивительно (или нет), но даже с удалением правила разрешения в ufw мой маршрутизатор WAN продолжает получать и отвечать на обнаружение DHCP. Предположительно, потому что у меня есть правила iptables, настроенные для пересылки всего трафика, но нет эквивалентного правила INPUT (пока я не добавлю его с помощью ufw).
Предпочтительно, я бы хотел, чтобы широковещательная рассылка DHCP в сети 10.11.12.0/24 не достигала даже сети 192.168.0.0/24.
Если это окажется затруднительным, я буду рад просто предотвратить попадание предложений DHCP от моего WAN-маршрутизатора в сеть 10.11.12.0/24.
Обратите внимание, что у меня нет проблем с сетью 192.168.0.0/24, поскольку я настроил dnsmasq так, чтобы он не предлагал DHCP на интерфейсе wlp3s0 (192.168.0.2). Похоже, это работает, и DHCP обнаруживает на wlp3s0 (192.168.0.2/24) не получает ответа от dnsmasq.
Так что же я упускаю? Я делаю это совершенно неправильно или я просто не совсем правильно понимаю? Любая помощь очень ценится.
С праздником!
В ответ на вопрос в комментариях от @sleepyhead,вот моя настройка iptables nat.
Chain PREROUTING (policy ACCEPT 13452 packets, 4312K bytes)
pkts bytes target prot opt in out source destination
Chain INPUT (policy ACCEPT 48 packets, 12715 bytes)
pkts bytes target prot opt in out source destination
Chain OUTPUT (policy ACCEPT 87 packets, 10884 bytes)
pkts bytes target prot opt in out source destination
Chain POSTROUTING (policy ACCEPT 55 packets, 8622 bytes)
pkts bytes target prot opt in out source destination
32 2262 MASQUERADE all -- * wlp3s0 0.0.0.0/0 0.0.0.0/0
Возможно ли, что это артефакт того, как я провожу тест? Что вызывает у меня подозрения, так это исходный IP-адрес вывода tcpdump. Может быть, запуск DHCP Discover на интерфейсе, у которого уже есть IP-адрес, дает другой результат, чем если бы его не было? В любом случае, если я смогу переназначить один из моих Raspberry Pis, я запущу этот тест с ним в качестве DHCP-клиента и посмотрю, получу ли я тот же результат, хотя я подозреваю, что получу.