Linux Netfilter: Como o rastreamento de conexão rastreia as conexões alteradas pelo NAT?

4

No momento, estou mergulhando nos detalhes da Arquitetura do Netfilter do Linux. Eu já estou familiarizado com ganchos, tabelas, correntes, os diferentes módulos do kernel, etc. do Netfilter. Mas há um detalhe de NAT em combinação com rastreamento de conexão que eu não entendo.

Eu tento explicar meu problema com um pequeno exemplo de SNAT. Neste exemplo, vou ignorar a camada de transporte, porque acho que não é necessário entender o meu problema. Por favor corrija-me se eu estiver errado!

Existe um computador cliente na rede local com o endereço IP 192.168.2.55 e um gateway NAT com o endereço IP externo 193.157.56.3. Agora o cliente quer se comunicar com um servidor e o endereço IP 217.254.1.76 na Internet.
Assim, o cliente envia um pacote com src = 192.168.2.55/dst = 217.254.1.76 para o gateway NAT, que também é o gateway padrão. O rastreamento de conexão rastreia essa nova conexão e cria duas novas tuplas:

IP_CT_DIR_ORIGINAL: src = 192.168.2.55, dst = 217.254.1.76
IP_CT_DIR_REPLY: src = 217.254.1.76, dst = 192.168.2.55

IP_CT_DIR_ORIGINAL e IP_CT_DIR_REPLY são macros para acessar uma matriz de duas tuplas.

No gancho POSTROUTING, NAT pergunta o rastreamento de conexão para uma conexão existente e, se isso for bem-sucedido, altera o endereço de origem no cabeçalho do pacote. Ele também cria silenciosamente uma regra DNAT para reverter o endereço de destino das respostas.
Agora chego ao ponto do meu poblema. NAT altera o endereço de destino em IP_CT_DIR_REPLY para seu endereço IP externo 193.157.56.3. Então as tuplas ficam assim:

IP_CT_DIR_ORIGINAL: src = 192.168.2.55, dst = 217.254.1.76
IP_CT_DIR_REPLY: src = 217.254.1.76, dst = 193.157.56.3

É por isso que o rastreamento de conexão pode rastrear as respostas no gancho PREROUTING porque existe uma tupla existente para a resposta. Mas depois de rastrear o pacote NAT altera o endereço de destino para o endereço do cliente, 192.168.2.55. Agora minha pergunta: Como o rastreamento de conexão rastreia esse pacote no gancho POSTROUTING? Não há uma tupla de resposta com src = 217.254.1.76/dst = 192.168.2.55 porque o NAT a alterou.
Existe algo que eu perdi?

    
por idlmn89 19.11.2017 / 17:45

1 resposta

2

Você deve instalar o comando conntrack geralmente empacotado como conntrack ou conntrack-tools, do link . Ele exibirá principalmente o mesmo conteúdo que /proc/net/nf_conntrack , mas pode fazer mais.

Execute conntrack no modo de evento no gateway NAT: conntrack -E (ou você pode escolher conntrack -E --proto tcp --orig-port-dst 443 para limitar a HTTPS). Agora, seu exemplo anterior com uma solicitação HTTPS forneceria algo semelhante a isso:

    [NEW] tcp      6 120 SYN_SENT src=192.168.2.55 dst=217.254.1.76 sport=50798 dport=443 [UNREPLIED] src=217.254.1.76 dst=193.157.56.3 sport=443 dport=50798
 [UPDATE] tcp      6 60 SYN_RECV src=192.168.2.55 dst=217.254.1.76 sport=50798 dport=443 src=217.254.1.76 dst=193.157.56.3 sport=443 dport=50798
 [UPDATE] tcp      6 432000 ESTABLISHED src=192.168.2.55 dst=217.254.1.76 sport=50798 dport=443 src=217.254.1.76 dst=193.157.56.3 sport=443 dport=50798 [ASSURED]
 [UPDATE] tcp      6 120 FIN_WAIT src=192.168.2.55 dst=217.254.1.76 sport=50798 dport=443 src=217.254.1.76 dst=193.157.56.3 sport=443 dport=50798 [ASSURED]
 [UPDATE] tcp      6 60 CLOSE_WAIT src=192.168.2.55 dst=217.254.1.76 sport=50798 dport=443 src=217.254.1.76 dst=193.157.56.3 sport=443 dport=50798 [ASSURED]
 [UPDATE] tcp      6 30 LAST_ACK src=192.168.2.55 dst=217.254.1.76 sport=50798 dport=443 src=217.254.1.76 dst=193.157.56.3 sport=443 dport=50798 [ASSURED]
 [UPDATE] tcp      6 120 TIME_WAIT src=192.168.2.55 dst=217.254.1.76 sport=50798 dport=443 src=217.254.1.76 dst=193.157.56.3 sport=443 dport=50798 [ASSURED]
[DESTROY] tcp      6 src=192.168.2.55 dst=217.254.1.76 sport=50798 dport=443 src=217.254.1.76 dst=193.157.56.3 sport=443 dport=50798 [ASSURED]

A tabela nat é especial, pois é usada somente uma vez por fluxo *, quando o estado [NEW] é criado. Tudo o mais é curto-circuitado pela entrada conntrack encontrada. A regra SNAT em POSTROUTING não "criou silenciosamente uma regra DNAT" para a resposta. Ele alterou a entrada conntrack para ter resposta dst = 193.157.56.3, e disse ao netfilter "Eu mudei algo", isso é mais do que isso. Todo o resto (incluindo a alteração ip de origem) é tratado por conntrack (módulos nf_conntrack, nf_conntrack_ipv4) e nat (módulos nf_nat, nf_nat_ipv4 e talvez mais alguns aqui), não pelo iptables. Considere as entradas como um banco de dados de estado de conexões.

Quando um pacote de resposta é recebido, o pacote, não tendo nenhuma associação armazenada, é examinado através das entradas do conntrack (na verdade procurando uma associação nos dois sentidos, na parte original ou na parte de resposta, isso não importa) e uma correspondência é encontrada porque a entrada foi criada antes. Em seguida, as informações compactadas são atualizadas com essa associação de conexão. Não há necessidade de procurar este pacote mais tarde, mesmo que algumas de suas propriedades (fonte ou destino ...) sejam alteradas, as informações estão diretamente disponíveis. Algumas das funções macro / inline que tratam disso são definidas em skbuff.h . Procure _nfct e nfct . O pacote (também conhecido como skbuff), após a pesquisa, recebe esse valor em skb->_nfct .

Então, as poucas coisas que você pode ter perdido:

  • iptables não é netfilter. É um usuário do netfilter. nftables é outro usuário do netfilter. conntrack e nat (por exemplo, módulo nf_nat) fazem parte do netfilter.
  • o gancho POSTROUTING nunca verá o pacote de resposta porque a conexão não é NEW: a tabela nat não é mais chamada para esse fluxo e os pacotes são identificados como parte desse fluxo.
  • a maior parte da manipulação de conntrack e nat é feita ... por conntrack e nat, não pelo iptables. iptables podem usar os recursos de conntrack (por exemplo: -m conntrack --ctstate ESTABLISHED ) ou nat (qualquer coisa na tabela nat precisa). Para o exemplo acima, A entrada conntrack sozinha tem as informações para "de-SNAT" do pacote e, de fato, é semelhante a um DNAT com uma conexão originalmente de entrada.
  • Geralmente não há necessidade de procurar as entradas do conntrack mais de uma vez por uma parte de pacote de uma conexão existente, o "índice" é anexado ao pacote após a consulta.

Você pode estar convencido de que a tabela nat não vê outros pacotes após o primeiro executando algumas vezes iptables-save -c e observando como os contadores incrementam as regras na tabela nat: somente para o primeiro pacote. / p>

* veja a parte do NAT:

This table is slightly different from the 'filter' table, in that only the first packet of a new connection will traverse the table: the result of this traversal is then applied to all future packets in the same connection.

    
por 20.11.2017 / 18:40