Perguntas sobre IPTables e DHCP?

8

No meu outro segmento, eu estava falando sobre algumas coisas interessantes sobre a política e os estados do iptables , agora gostaria de entender mais sobre como o DHCP funciona e como o iptables o entende.

O ETH0 está conectado ao meu switch principal que recebe o ip dinâmico do meu roteador para obter não apenas acesso à Internet, mas também acesso à minha rede externa.

ETH1 é a placa interna conectada a um comutador interno no qual os clientes X recebem seus IPS desse servidor

A rede ETH1 é 192.168.1.0/255.255.255.0, em que o ip do servidor é 192.168.1.254.

Pelo que entendi, dhcp é um protocolo de bootp, portanto, mesmo se você tiver suas políticas de firewall para remover tudo, sua rede ainda receberá o DHCP, o que, nos testes que fiz, parecia verdadeiro.

Do 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

Eu fiz uma regra de log simples para ver o que o iptables faz:

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

Aqui estão as minhas regras do iptables no momento:

# 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

Assim, mesmo com a POLÍTICA padrão para descartar tudo, ainda recebo o DHCP na minha rede, enquanto leva muito mais tempo para renovar um IP e tal.

Se eu adicionar a regra a seguir no meu firewall:

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

Levará muito menos tempo para atualizar qualquer dhcp do cliente.

Considerando o exposto acima:

  1. por que realmente demora mais tempo para atualizá-lo, mesmo que não esteja sendo bloqueado?
  2. é possível DROP o servidor dhcp de todo sem desligá-lo?
  3. é possível ACEITAR o servidor dhcp dentro de iptables com o BOOTP? como isso é feito?

Se você conhece bons links, eu não me importaria de tomar muito :)

Guapo
fonte
Estou um pouco confuso com a saída de log do tcpdump e iptables. Você está monitorando a interface de rede no modo promíscuo? Seu servidor firewall está realmente usando o DHCP para configurar sua NIC?
Steven segunda-feira
@ Mesmo o servidor que possui o firewall mencionado acima possui eth0 e eth1, eth0 recebe dhcp como cliente externo e eth1 é meu servidor dhcp para a minha rede interna, que é o que eu estou falando. O que você quer dizer por Are you monitoring the network interface in promiscuous modeque eu ainda estou aprendendo ...
Guapo
Ah ok. Você realmente precisa descrever melhor sua rede e servidores se quiser que alguém entenda sua pergunta!
Steven segunda-feira
Sobre o modo promíscuo: en.wikipedia.org/wiki/Promiscuous_mode
Steven segunda-feira
@ Steven vai fazer isso agora obrigado por apontar, você acha que eu tenho que especificar outra coisa senão o layout de rede?
Guapo

Respostas:

13

Eu vou responder # 2: Não.

Ao obter um endereço IP, o daemon dhcp cria um soquete bruto para a interface de rede e manipula o próprio protocolo UDP. Assim, os pacotes UDP nunca passam por iptables.

A razão pela qual o daemon dhcp precisa implementar o UDP é que o kernel pode manipular apenas o UDP (de fato, todo o conjunto TCP / IP) quando a interface possui um endereço IP. Anteriormente, os daemons dhcp dariam a uma interface o endereço IP 0.0.0.0, mas isso não funciona mais.

Mark Wagner
fonte
soquete de pacote . soquetes brutos que passar por iptables. aflito. unix.stackexchange.com/a/447524/29483
sourcejedi
5

Adicionando

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

tornará a atualização do DHCPD mais rápida :) Deve funcionar nos dois lados ENTRADA e SAÍDA. Você pode DROP dhcpd com ebtables, não com iptables. DHCPD escutando em 0.0.0.0, não dentro do IP

Ta Coen
fonte
+1 Eu o tinha no INPUT e estava demorando o mesmo tempo que eu não tinha nas minhas regras. Quando eu fiz OUTPUT, fez uma enorme diferença. Vou ler sobre ebtables obrigado.
Guapo
$ IPT -I INPUT -i $ INTIF -s 0/0 -p udp --dport 67:68 --sport 67:68 -j ACEITAR
Ta Coen
apenas tentei o acima e ainda demore muito em comparação ao uso da regra OUTPUT.
Guapo
Como a política é DROP, você deve usar INPUT e OUTPUT.
Ta Coen
3

Minha observação recente, no OpenWRT Kamikaze 7.09 = 2.4.34 e no udhcpc from busybox 1.4.2:

Eu tenho uma política "ACEITAR" na cadeia OUTPUT e, na direção INPUT, originalmente confiei nesta regra clássica:

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

para permitir as respostas DHCP em (para meu udhcpc) ​​na interface WAN. Ou seja, é aqui que o servidor DHCP upstream do meu ISP atribui um endereço IP para mim.

Lembre-se da diferença entre uma troca DHCP inicial (descoberta, oferta, solicitação, confirmação) e uma renovação de concessão de DHCP (solicitação, confirmação).

Após a inicialização, o udhcpc inicia com a troca inicial completa. Essa troca teria sucesso. E outra renovação ou duas seriam bem-sucedidas também - apenas uma solicitação e reconhecimento. O servidor DHCP do meu ISP normalmente solicita um tempo de renovação de cerca de uma hora a 1,5 horas; portanto, meu cliente DHCP solicita uma renovação a cada 30 a 45 minutos (esse comportamento é baseado no RFC).

Mas, na terceira ou quarta renovação, começaria a ficar interessante. O TCPdump mostraria cerca de três tentativas de renovação, seguidas por uma troca inicial completa - dentro de um período de tempo de apenas alguns minutos ou até segundos. Como se o udhcpc não gostasse do que voltou :-( e acabasse satisfeito com a troca completa. Depois disso, outra renovação em meia hora seria bem-sucedida ... e a história se repetiria novamente.

Eu descobri que talvez seja o rastreamento de conexão no kernel que tenha algo errado. Como se a entrada conntrack expire após duas horas ou mais, e as renovações posteriores do DHCP falhem porque o ACK do servidor não chega ao udhcpc escutando no soquete. Observe que o tcpdump (libpcap) escuta na interface bruta e pode ver todos os pacotes chegando, antes de estarem sujeitos ao iptables. Depois que o udhcpc renuncia a renovações e, desesperado, tenta começar do zero usando uma troca completa (começando com DISCOVER), o kernel estabelece uma nova entrada do conntrack e pode entender os pacotes relacionados por mais algum tempo ...

Com certeza, uma vez que eu adicionei algo como:

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

as renovações parecem funcionar para sempre.

Você pode achar úteis os seguintes argumentos do tcpdump cmdline:

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

Nota: -vvsolicita a saída detalhada do dissector. eth0.1é a minha porta WAN (também uma interface "NAT outside").

Um atributo interessante nos pacotes ACK é o LT: field = sugerido / tempo de concessão máximo concedido em segundos. As solicitações DHCP são enviadas da porta 68 para a porta 67. As respostas vêm da porta 67 para a porta 68.

frr
fonte
Sua história não faz sentido. Não importa se inicial ou renovada, a troca DHCP sempre é iniciada pelo cliente que envia da porta 68 para a porta 67, para um IP específico ou como broadcast. E com o ACCEPT de saída, isso sempre funcionará. Uma resposta do destino de saída sempre deve ser recebida pela regra ESTABLISHED, portanto, a renovação deve funcionar para sempre apenas com a regra ESTABLISHED, pois toda renovação também renova ou recria o estado conntrack.
Mecki 19/04
Uma renovação envia uma solicitação openwrt:68 -> dhcpserver:67e o ACK será dhcpserver:67 -> openwrt:68. Isso conta como ESTABELECIDO e passará. Se o antigo estado do conntrack expirou, isso estabelecerá um novo. Se houver algum problema, só poderá ser com a troca inicial como é a DESCOBERTA 0.0.0.0:68 -> 255.255.255.255:67e a OFERTA dhcpserver:67 -> new-openwrt:68, o que não conta como ESTABELECIDO. Isso só funciona como o DHCP geralmente ignora o iptables com um soquete de pacote no Linux; caso contrário, é necessária uma regra de entrada que permita pacotes da porta UDP 67 ou da porta UDP 68.
Mecki
1
Além disso, você diz que várias renovações foram bem-sucedidas, mas todas as renovações bem-sucedidas também renovarão o estado do conntrack; portanto, se os estados do conntrack expirarem após 2 horas, uma renovação o estenderá novamente por mais 2 horas e assim por diante e, portanto, nunca expirará . No entanto, o tempo limite padrão do conntrack para o UDP é de apenas 30 segundos e não de 2 horas, e duvido que o OpenWRT tenha alterado isso para 2 horas, pois isso seria uma loucura. Então sua história parece totalmente falho para mim.
Mecki 19/04
@Mecki, obrigado pelo valioso feedback :-) Até agora, minha resposta tem 4 anos. Há cerca de um ano, meu ASUS WL500G Deluxe estava começando a ficar em estado terminal (após cerca de 12 anos de execução, devido à substituição de capacitores) e eu joguei aquele velho Kamikaze junto com o hardware. No momento, estou executando um OpenWRT mais atual em um AP TP-Link moderno e, depois de pensar um pouco, não reutilizei meus scripts antigos de firewall. O OpenWRT agora parece ter um bom firewall pronto para uso ... quero dizer que não posso verificar minhas reivindicações anteriores. Tudo o que sei é que a regra extra do iptables ajudou.
frr 19/04