IPTables и вопросы DHCP?

8

В другой теме я говорил о некоторых интересных вещах о политике и состояниях iptables , теперь я хотел бы больше узнать о том, как работает DHCP и как iptables его понимает.

ETH0 подключен к моему главному коммутатору, который получает динамический IP-адрес от моего маршрутизатора, чтобы получить не только доступ к Интернету, но и доступ к моей внешней сети.

ETH1 - это внутренняя карта, подключенная к внутреннему коммутатору, где клиенты X получают свои IPS с этого сервера.

Сеть ETH1 - 192.168.1.0/255.255.255.0, где ip сервера - 192.168.1.254.

Из того, что я понял, dhcp является протоколом bootp, поэтому даже если у вас есть политики брандмауэра для DROP всего, ваша сеть все равно получит DHCP, что в тестах, которые я сделал, казалось правдой.

Из tcpdump:

root@test:~# tcpdump -i eth1 port 67 or 68
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth1, link-type EN10MB (Ethernet), capture size 96 bytes
11:34:03.943928 IP 192.168.1.2.bootpc > 255.255.255.255.bootps: BOOTP/DHCP, Request from 00:0c:29:29:52:8b (oui Unknown), length 303
11:34:03.957647 IP 192.168.1.254.bootps > 192.168.1.2.bootpc: BOOTP/DHCP, Reply, length 300
11:34:06.492153 IP 192.168.1.2.bootpc > 192.168.1.254.bootps: BOOTP/DHCP, Request from 00:0c:29:29:52:8b (oui Unknown), length 303
11:34:06.506593 IP 192.168.1.254.bootps > 192.168.1.2.bootpc: BOOTP/DHCP, Reply, length 300

Я сделал простое правило журнала, чтобы увидеть, что делает iptables:

root@test:~# tail -f /var/log/syslog
Oct 15 11:30:58 test kernel: IN=eth1 OUT= MAC=ff:ff:ff:ff:ff:ff:00:0c:29:29:52:8b:08:00 SRC=192.168.1.2 DST=255.255.255.255 LEN=331 TOS=0x00 PREC=0x00 TTL=128 ID=9527 PROTO=UDP SPT=68 DPT=67 LEN=311
Oct 15 11:31:43 test kernel: IN=eth1 OUT= MAC=ff:ff:ff:ff:ff:ff:00:0c:29:29:52:8b:08:00 SRC=192.168.1.2 DST=255.255.255.255 LEN=331 TOS=0x00 PREC=0x00 TTL=128 ID=9529 PROTO=UDP SPT=68 DPT=67 LEN=311
Oct 15 11:33:32 test kernel: IN=eth1 OUT= MAC=ff:ff:ff:ff:ff:ff:00:0c:29:29:52:8b:08:00 SRC=192.168.1.2 DST=255.255.255.255 LEN=331 TOS=0x00 PREC=0x00 TTL=128 ID=9531 PROTO=UDP SPT=68 DPT=67 LEN=311
Oct 15 11:34:03 test kernel: IN=eth1 OUT= MAC=ff:ff:ff:ff:ff:ff:00:0c:29:29:52:8b:08:00 SRC=192.168.1.2 DST=255.255.255.255 LEN=331 TOS=0x00 PREC=0x00 TTL=128 ID=9533 PROTO=UDP SPT=68 DPT=67 LEN=311

Вот мои правила iptables на данный момент:

# deny all traffic
$IPT -P INPUT DROP
$IPT -P FORWARD DROP
$IPT -P OUTPUT DROP

# Use stateful inspection feature to only allow incoming connections
# related to connections I have already established myself
$IPT -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
$IPT -A OUTPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT

# allow all traffic on lo interface
$IPT -A INPUT -i lo -j ACCEPT
$IPT -A OUTPUT -o lo -j ACCEPT

Таким образом, даже при использовании ПОЛИТИКИ по умолчанию для отбрасывания всего, я все равно получаю DHCP в своей сети, в то время как обновление IP занимает много времени.

Если я добавлю следующее правило к своему брандмауэру:

$IPT -I OUTPUT -o $INTIF -p udp --dport 67:68 --sport 67:68 -j ACCEPT

Это займет МНОГО МЕНЬШЕ ВРЕМЕНИ, чтобы обновить любого клиента DHCP.

Учитывая вышеизложенное:

  1. почему его обновление занимает больше времени, даже если оно не заблокировано?
  2. Можно ли вообще DROP DHPP-сервер, не выключая его?
  3. Можно ли принять сервер DHCP в пределах iptables с BOOTP? как это сделать?

Если вы знаете хорошие ссылки, я не возражаю против того, чтобы брать много :)

Guapo
источник
Я немного сбит с толку вашим выводом журнала tcpdump и iptables. Вы контролируете сетевой интерфейс в случайном режиме? Ваш сервер firewalled фактически использует DHCP для настройки своей сетевой карты?
Стивен Понедельник
@ На сервере, на котором установлен брандмауэр, упомянутый выше, установлены eth0 и eth1, eth0 получает dhcp в качестве клиента извне, а eth1 - мой dhcp-сервер для моей внутренней сети, о котором я говорю. Что вы подразумеваете под тем, что Are you monitoring the network interface in promiscuous modeя все еще учусь ...
Гуапо
О хорошо Вам действительно нужно лучше описать свою сеть и серверы, если вы хотите, чтобы кто-нибудь понял ваш вопрос!
Стивен Понедельник
Об смешном режиме: en.wikipedia.org/wiki/Promiscuous_mode
Стивен Понедельник,
@Steven сделает это сейчас, спасибо за замечание, вы думаете, мне нужно указать что-то еще, кроме сетевого макета?
Гуапо

Ответы:

13

Я отвечу № 2: Нет.

При получении IP-адреса демон dhcp создает необработанный сокет для сетевого интерфейса и обрабатывает сам протокол UDP. Таким образом, пакеты UDP никогда не проходят через iptables.

Причина, по которой демон dhcp должен реализовывать UDP, заключается в том, что ядро ​​может обрабатывать UDP (фактически весь пакет TCP / IP) только тогда, когда интерфейс имеет IP-адрес. Ранее демоны dhcp сначала предоставляли интерфейсу IP-адрес 0.0.0.0, но это больше не работает.

Марк Вагнер
источник
пакетный сокет. сырые сокеты этого пройти через IPTables. AFAICT. unix.stackexchange.com/a/447524/29483
sourcejedi
5

Добавление

$IPT -I INPUT -i $INTIF -p udp --dport 67:68 --sport 67:68 -j ACCEPT

заставит DHCPD обновляться быстрее :) Он должен работать как на входе, так и на выходе. Вы можете DROP dhcpd с ebtables, а не с iptables. DHCPD прослушивает 0.0.0.0, не в пределах IP

Та Коен
источник
+1 У меня это было на INPUT, и это занимало столько же времени, сколько у меня не было по моим правилам. Когда я сделал это ВЫХОД, это имело ОГРОМНОЕ различие. Я буду читать о ebtables спасибо.
Гуапо
$ IPT -I INPUT -i $ INTIF -s 0/0 -p udp --dport 67:68 --sport 67:68 -j ПРИНЯТЬ
Та Коен
только что попробовал выше и по-прежнему занимает слишком много времени по сравнению с использованием правила OUTPUT.
Гуапо
Поскольку политика DROP, вы должны использовать как INPUT, так и OUTPUT.
Та Коен
3

Мое недавнее наблюдение о OpenWRT Kamikaze 7.09 = 2.4.34 и udhcpc из busybox 1.4.2:

У меня есть политика «ПРИНЯТЬ» в цепочке OUTPUT, и в направлении INPUT изначально я опирался на это классическое правило всеобщего охвата:

iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT

разрешить ответы DHCP в (на мой udhcpc) ​​на интерфейсе WAN. Т.е. именно здесь вышестоящий DHCP-сервер моего провайдера назначает мне IP-адрес.

Помните разницу между первоначальным обменом DHCP (обнаружение, предложение, запрос, подтверждение) и обновлением аренды DHCP (запрос, подтверждение).

После загрузки udhcpc запускается при полном первоначальном обмене. Этот обмен будет успешным. И еще одно или два обновления будут успешными - просто запрос и подтверждение. DHCP-сервер моего провайдера обычно запрашивает время обновления от часа до 1,5 часов, поэтому мой DHCP-клиент запрашивает обновление каждые 30–45 минут (это поведение основано на RFC).

Но примерно с третьим или четвертым обновлением это станет интересным. TCPdump покажет около трех или около того попыток обновления, после чего начнется полный первоначальный обмен, то есть в течение всего нескольких минут или даже секунд. Как будто udhcpc не понравилось то, что он получил обратно :-( и в конечном итоге был бы удовлетворен полным обменом. После этого, другое обновление через полчаса было бы успешным ... и история повторилась бы снова.

Я понял, что, возможно, что-то не так отслеживает соединение в ядре. Как будто запись conntrack истекает через два часа или около того, и более поздние обновления DHCP завершаются неудачно, потому что ACK от сервера фактически не делает его для udhcpc, прослушивающего сокет. Обратите внимание, что tcpdump (libpcap) прослушивает необработанный интерфейс и может видеть все входящие пакеты до того, как они станут объектом iptables. Как только udhcpc отказывается от обновлений и в отчаянии пытается начать все заново, используя полный обмен (начиная с DISCOVER), ядро ​​создает новую запись conntrack и может еще некоторое время понимать связанные пакеты ...

Конечно же, как только я добавил что-то вроде:

iptables -A INPUT -i $OUT_IF -p udp --sport 67 --dport 68 -j ACCEPT

обновления, кажется, работают вечно.

Вам могут пригодиться следующие аргументы tcpdump cmdline:

tcpdump -vv -s 1500 -i eth0.1 port 67 or port 68

Примечание: -vvзапрашивает подробный вывод диссектора. eth0.1мой порт WAN (также интерфейс "NAT снаружи").

Интересным атрибутом в пакетах ACK является LT: поле = рекомендуемое / максимальное предоставленное время аренды в секундах. DHCP-запросы отправляются с порта 68 на порт 67. Ответы поступают с порта 67 на порт 68.

ФПП
источник
Ваша история не имеет смысла. Независимо от того, начальный или возобновленный, обмен DHCP всегда запускается клиентом, отправляющим с порта 68 на порт 67 либо на определенный IP, либо в виде широковещательной рассылки. А с исходящим ACCEPT это всегда будет работать. Ответ от исходящего пункта назначения должен всегда проходить через входящий по правилу ESTABLISHED, поэтому обновление должно работать вечно только с правилом ESTABLISHED, так как каждое обновление также обновляет или воссоздает состояние conntrack.
Меки
Обновление отправляет запрос, openwrt:68 -> dhcpserver:67и ACK будет dhcpserver:67 -> openwrt:68. Это считается установленным и пройдет. Если старое состояние conntrack истекло, это устанавливает новое. Если есть проблема, это может быть только с первоначальным обменом, таким как ОТКРЫТИЕ 0.0.0.0:68 -> 255.255.255.255:67и ПРЕДЛОЖЕНИЕ dhcpserver:67 -> new-openwrt:68, которое не считается УСТАНОВЛЕННЫМ. Это работает только тогда, когда DHCP обычно обходит iptables с сокетом пакетов в Linux, в противном случае требуется входящее правило, разрешающее пакеты от порта UDP 67 или к порту 68 68.
Mecki,
1
Кроме того, вы говорите, что несколько обновлений были успешными, но каждое успешное обновление также будет обновлять состояние conntrack, поэтому, если ваши состояния conntrack истекают через 2 часа, обновление продлевает его снова еще на 2 часа и так далее, и, таким образом, оно никогда не истечет. , Тем не менее, время ожидания по умолчанию для UDP составляет всего 30 секунд, а не 2 часа, и я сомневаюсь, что OpenWRT изменил это значение на 2 часа, поскольку это было бы сумасшествием. Так что твоя история кажется мне совершенно ошибочной.
Меки
@Mecki, спасибо за ценный отзыв :-) Моему ответу уже 4 года. Около года назад мой ASUS WL500G Deluxe начинал казаться беспорядочным (после 12 лет работы из-за замены конденсаторов), и я бросил этот старый Kamikaze вместе с оборудованием. Прямо сейчас я использую более современный OpenWRT на современной AP TP-Link, и после некоторого размышления я не использовал мои старые сценарии брандмауэра. У OpenWRT теперь, кажется, есть хороший брандмауэр из коробки ... Я хочу сказать, что я не могу проверить свои прошлые утверждения. Все, что я знаю, это то, что дополнительное правило iptables помогло.
ОСТ