Eu tenho um servidor Debian 12 (IP público 85.xxx.xxx.xxx
em enp6s0
) executando vários contêineres LXC em uma ponte de rede cbr0
.
Como o IP público é dinâmico, tive que configurar forward
+ prerouting
regras dnat
para que as solicitações recebidas chegassem aos contêineres. Por exemplo. a porta 80/443 é atribuída ao contêiner 10.10.0.1
. Aqui estão minhas nftables
regras:
flush ruleset
table inet filter {
chain input {
type filter hook input priority 0; policy drop;
ct state {established, related} accept
iifname lo accept
iifname cbr0 accept
ip protocol icmp accept
ip6 nexthdr icmpv6 accept
}
chain forward {
type filter hook forward priority 0; policy accept;
}
chain output {
type filter hook output priority 0;
}
}
table ip filter {
chain forward {
type filter hook forward priority 0; policy drop;
oifname enp6s0 iifname cbr0 accept
iifname enp6s0 oifname cbr0 ct state related, established accept
# Webproxy
iifname enp6s0 oifname cbr0 tcp dport 80 accept
iifname enp6s0 oifname cbr0 udp dport 80 accept
iifname enp6s0 oifname cbr0 tcp dport 443 accept
iifname enp6s0 oifname cbr0 udp dport 443 accept
}
}
table ip nat {
chain postrouting {
type nat hook postrouting priority 100; policy accept;
}
chain prerouting {
type nat hook prerouting priority -100; policy accept;
# Webproxy
iifname enp6s0 tcp dport 80 dnat to 10.10.0.1:80
iifname enp6s0 udp dport 80 dnat to 10.10.0.1:80
iifname enp6s0 tcp dport 443 dnat to 10.10.0.1:443
iifname enp6s0 udp dport 443 dnat to 10.10.0.1:443
}
}
Agora o problema é: NAT hairpin. Tenho vários contêineres hospedando sites e às vezes acontece que alguns deles precisam se comunicar com outros contêineres usando nomes de domínio. Quando eles executam uma consulta DNS para esses domínios, eles obtêm o IP do host e a comunicação falha:
Como posso corrigir esta situação sem recorrer a hacks de DNS ? Existe uma maneira de configurar nftables
o encaminhamento de solicitação internamente enquanto se tem um IP dinâmico? Como o iifname
acima brinca com isso?
Obrigado.
O que você provavelmente precisa é de uma 'EXPRESSÃO FIB' na página de manual do nft. Esta é a regra que uso para meu DNAT (você precisará ajustar sua configuração):
fib daddr type local
é a parte que correspondedaddr
a qualquer endereço correspondente da caixa NAT.Observe que talvez você também precise fornecer o mapeamento SNAT apropriado para que isso funcione (já que os pacotes de retorno podem ser enviados diretamente para a interface da ponte com endereço de origem interno que não corresponderá a nenhuma conexão na VM).
Ok, consegui consertar isso e também simplifiquei minha configuração.
forward
cadeia não precisa aceitar explicitamente o tráfego para portas específicas, posso apenas dizer para encaminhar qualquer coisa que tenha regrasdnat
específicas posteriormente:dnat
possa vir de ambosenp6s0
ecbr0
:Agora tudo parece funcionar, porém há um pequeno detalhe: quando meu contêiner webproxy recebe solicitações da internet (
enp6s0
) ele registra o IP real da máquina remota como origem dessas solicitações, porém quando elas vêm de outro contêiner o IP de origem aparece como 10.0 .0.254 que é o IP do host emcbr0
.