iptables roteia todo o tráfego para duas cadeias diferentes?

iptables roteia todo o tráfego para duas cadeias diferentes?

Estou depurando uma configuração do iptables que não escrevi. Esta configuração deve fornecer um firewall em torno de alguns contêineres Docker (Portainer e Nginx Proxy Manager) em execução no próprio roteador, mas algo está errado e nenhum contêiner Docker pode servir sites para a WAN. iptables -L -v -na saída fica assim:

root@FriendlyWrt:/proc/sys/net/bridge# iptables -L -v -n
# Warning: iptables-legacy tables present, use iptables-legacy to see them
Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination         

Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination         
1400K  251M DOCKER-USER  all  --  *      *       0.0.0.0/0            0.0.0.0/0           
1397K  251M DOCKER-ISOLATION-STAGE-1  all  --  *      *       0.0.0.0/0            0.0.0.0/0           
 5815  404K ACCEPT     all  --  *      docker0  0.0.0.0/0            0.0.0.0/0            ctstate RELATED,ESTABLISHED
 2580  116K DOCKER     all  --  *      docker0  0.0.0.0/0            0.0.0.0/0           
15447 7639K ACCEPT     all  --  docker0 !docker0  0.0.0.0/0            0.0.0.0/0           
    0     0 ACCEPT     all  --  docker0 docker0  0.0.0.0/0            0.0.0.0/0           

Chain OUTPUT (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination         

Chain DOCKER (1 references)
 pkts bytes target     prot opt in     out     source               destination         
   83  4836 ACCEPT     tcp  --  !docker0 docker0  0.0.0.0/0            172.17.0.2           tcp dpt:9443
    1    60 ACCEPT     tcp  --  !docker0 docker0  0.0.0.0/0            172.17.0.2           tcp dpt:8000
   29  1740 ACCEPT     tcp  --  !docker0 docker0  0.0.0.0/0            172.17.0.3           tcp dpt:443
    1    60 ACCEPT     tcp  --  !docker0 docker0  0.0.0.0/0            172.17.0.3           tcp dpt:81
    2   120 ACCEPT     tcp  --  !docker0 docker0  0.0.0.0/0            172.17.0.3           tcp dpt:80

Chain DOCKER-ISOLATION-STAGE-1 (1 references)
 pkts bytes target     prot opt in     out     source               destination         
15447 7639K DOCKER-ISOLATION-STAGE-2  all  --  docker0 !docker0  0.0.0.0/0            0.0.0.0/0           
1397K  251M RETURN     all  --  *      *       0.0.0.0/0            0.0.0.0/0           

Chain DOCKER-ISOLATION-STAGE-2 (1 references)
 pkts bytes target     prot opt in     out     source               destination         
    0     0 DROP       all  --  *      docker0  0.0.0.0/0            0.0.0.0/0           
15447 7639K RETURN     all  --  *      *       0.0.0.0/0            0.0.0.0/0           

Chain DOCKER-MAN (1 references)
 pkts bytes target     prot opt in     out     source               destination         
 8395  519K RETURN     all  --  br-lan docker0  0.0.0.0/0            0.0.0.0/0           
 2805  167K DROP       all  --  *      docker0  0.0.0.0/0            0.0.0.0/0            ctstate INVALID,NEW
  236 59251 RETURN     all  --  *      docker0  0.0.0.0/0            0.0.0.0/0            ctstate RELATED,ESTABLISHED
1388K  251M RETURN     all  --  *      *       0.0.0.0/0            0.0.0.0/0           

Chain DOCKER-USER (1 references)
 pkts bytes target     prot opt in     out     source               destination         
1400K  251M DOCKER-MAN  all  --  *      *       0.0.0.0/0            0.0.0.0/0           
  236 59251 REJECT     all  --  eth0   docker0  0.0.0.0/0            0.0.0.0/0            reject-with icmp-port-unreachable
1397K  251M RETURN     all  --  *      *       0.0.0.0/0            0.0.0.0/0           

Parece que no início da cadeia "forward" todo o tráfego é enviado para a cadeia "docker-user" e, na próxima regra, todo o tráfego restante é enviado para a cadeia "docker-isolation-stage-1" . Eu presumiria que depois de enviar tudo para "docker-user", não haveria mais tráfego para classificar e o resto da cadeia ficaria completamente sem uso. Mas parece que quantidades iguais de tráfego são capturadas por cada regra e, em seguida, mais tráfego segue para a linha 3. O que está acontecendo aqui? O que realmente está sendo testado nas duas primeiras linhas do “forward”?

Responder1

No celular e muito longo para um comentário

Parece que você assume que enviar um pacote para uma cadeia nova/personalizada significa que ele não retornará de lá. Isso é um tanto incorreto.

As regras no iptables são verificadas sequencialmente

O processamento é interrompido quando um pacote corresponde a uma regra que dá uma decisão final sobre o destino desse pacote (geralmente ACCEPT , DROP, REJECT e talvez outras que esqueci)

Quando uma regra é pular para uma cadeia nova/personalizada:

  • essa cadeia é inserida
  • todas as regras nessa cadeia são verificadas sequencialmente até que uma decisão final seja tomada sobre o destino daquele pacote
  • Se nenhuma decisão final sobre o destino do pacote for tomada:
    RETORNAR à cadeia anterior

Isso é o que acontece na sua cadeia DOCKER-USER , apenas alguns pacotes correspondem a uma regra na cadeia DOCKER-MAN ou à regra REJECT subsequente que resulta em uma decisão final. Quase todos os pacotes que entraram não atendem a uma decisão final e retornam para a cadeia FORWARD onde são processados ​​pela próxima regra, entrarão na cadeia DOCKER-ISOLATION-STAGE-1

informação relacionada