Eu tenho um contêiner Docker em execução em uma configuração vanilla que escuta na porta 9999:
docker run --rm -it -p 9999:9999 busybox nc -vvl -p 9999 0.0.0.0
Adicionei uma regra LOG à tabela POSTROUTING no NAT para capturar os pacotes do servidor. No entanto, quando me conecto de uma máquina externa a este contêiner, não vejo nada no log do sistema.
No entanto, posso ver pacotes de conexão ao fazer login no final da cadeia POSTROUTING do mangle. De acordo com o The Diagram(TM) , NAT-POSTROUTING deve ser a próxima cadeia a viajar.
Esta é a tabela NAT:
# iptables -nL -tnat
Chain PREROUTING (policy ACCEPT)
target prot opt source destination
DOCKER 0 -- 0.0.0.0/0 0.0.0.0/0 ADDRTYPE match dst-type LOCAL
Chain INPUT (policy ACCEPT)
target prot opt source destination
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
DOCKER 0 -- 0.0.0.0/0 !127.0.0.0/8 ADDRTYPE match dst-type LOCAL
Chain POSTROUTING (policy ACCEPT)
target prot opt source destination
LOG 0 -- 172.16.0.0/12 0.0.0.0/0 LOG flags 0 level 4 prefix "Packet:"
MASQUERADE 0 -- 172.17.0.0/16 0.0.0.0/0
MASQUERADE 6 -- 172.17.0.2 172.17.0.2 tcp dpt:9999
Chain DOCKER (2 references)
target prot opt source destination
RETURN 0 -- 0.0.0.0/0 0.0.0.0/0
DNAT 6 -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:9999 to:172.17.0.2:9999
Assistir journalctl -f | grep Packet:
não mostra nada. TRACE indica que a tabela NAT foi totalmente ignorada, ou seja, todas as cadeias são ignoradas para pacotes de saída do servidor.
Isto está definido:
net.bridge.bridge-nf-call-iptables=1
net.bridge.bridge-nf-call-ip6tables=1
Por que isso acontece neste caso? Ou, de maneira mais geral, por que alguns pacotes simplesmente ignoram completamente a tabela NAT?
A tabela NAT é consultada apenas uma vez para cada conexão.
Quando uma solicitação de conexão de entrada é recebida, ela possui um endereço de origem remota e o endereço do host como destino: src=remote e dst=host .
A primeira regra PREROUTING lança o pacote para a cadeia DOCKER, que eventualmente o DNAT para o endereço do contêiner: dst=container . Como se trata de um pré-roteamento, o pacote é roteado para o contêiner.
A terceira regra POSTROUTING MASQUERADE o endereço de origem do pacote: src=host (equivalente a SNAT neste caso). Isso faz com que o contêiner perceba o pacote como vindo do host e, portanto, responda diretamente ao host. O host removerá o NAT dos pacotes e os enviará de volta ao controle remoto.
Isso significa que a conexão agora está totalmente NAT de (remote, host) para (host, container) e a tabela NAT não é consultada novamente para esta conexão.