Tenho as interfaces eth0 (acesso à internet) e tap_vpn0 (interface tap vpn, com rede 192.168.110.0/24). O que eu quero é DNAT todas as conexões de entrada através de eth0 para 192.168.110.2, mas SOMENTE se NÃO houver serviço de escuta no próprio servidor (principalmente, o próprio servidor VPN, mas basicamente qualquer outro serviço que apareça netstat -plunt
, incluindo SSH ).
Por enquanto o que estou fazendo é
iptables -t nat -I PREROUTING 1 -i eth0 -p tcp --dport 22 -j ACCEPT iptables -t nat -I PREROUTING 1 -i eth0 -p tcp --dport 443 -j ACCEPT iptables -t nat -I PREROUTING 1 -i eth0 -p tcp --dport 5555 -j ACCEPT iptables -t nat -I PREROUTING 1 -i eth0 -p tcp --dport 992 -j ACCEPT iptables -t nat -I PREROUTING 1 -i eth0 -p tcp --dport 1194 -j ACCEPT iptables -t nat -I PREROUTING 1 -i eth0 -p udp --dport 4500 -j ACCEPT iptables -t nat -I PREROUTING 1 -i eth0 -p udp --dport 500 -j ACCEPT iptables -t nat -I PREROUTING 1 -i eth0 -p udp --dport 1194 -j ACCEPT iptables -t nat -I PREROUTING 1 -i eth0 -p udp --dport 1701 -j ACCEPT iptables -t nat -I PREROUTING 1 -i eth0 -p udp --dport 54700 -j ACCEPT iptables -t nat -I PREROUTING 1 -i eth0 -p udp --dport 63486 -j ACCEPT iptables -t nat -I PREROUTING 1 -i eth0 -p udp --dport 68 -j ACCEPT iptables -t nat -I PREROUTING 1 -i eth0 -p gre -j ACCEPT iptables -t nat -A PREROUTING -i eth0 -j DNAT --to-destination 192.168.110.2
anotando uma longa lista de exceções estáticas. Mas existe uma maneira de dizer ao IPTables para não DNAT caso a porta não esteja fechada no host real, se o pacote for tratado localmente com sucesso? Então, se por exemplo eu tiver uma porta aleatória de 9988 aberta posteriormente no servidor, não preciso adicionar outra exceção, iptables -t nat -I PREROUTING 1 -i eth0 -p tcp --dport 9988 -j ACCEPT
mas ela simplesmente não será editada por DNAT?
Responder1
Parece que iptables -t nat -I PREROUTING 1 -i eth0 -m socket --nowildcard -j ACCEPT
funciona. -m socket
pela descrição faz exatamente isso - corresponde se existe algum soquete de aceitação para este pacote. O truque foi usar a --nowildcard
opção, que omiti anteriormente - até mesmo a página de manual diz "A correspondência de soquete não aceitará ouvintes com limite zero por padrão, pois os serviços locais poderiam interceptar o tráfego que, de outra forma, seria encaminhado". - que é exatamente o que eu precisava - que os serviços locais interceptassem se houvesse algum disponível!
As regras resultantes são:
iptables -t nat -I PREROUTING 1 -i eth0 -m socket --nowildcard -j ACCEPT iptables -t nat -I PREROUTING 1 -i eth0 -p tcp --dport 22 -j ACCEPT iptables -t nat -I PREROUTING 1 -i eth0 -p gre -j ACCEPT iptables -t nat -A PREROUTING -i eth0 -j DNAT --to-destination 192.168.110.2
Deixei a porta 22 (ssh) para o caso de não funcionar como esperado - mas pelos testes parece estar funcionando perfeitamente!