Um cliente no seu servidor OpenVPN tem de perder o acesso à LAN enquanto todos os outros túneis continuam ativos. Se procurar isto, a melhor resposta costuma dizer que o daemon não consegue, o que só é meio verdade: o OpenVPN não tem firewall por cliente, mas o host que termina o túnel já filtra pacotes. As duas decisões que importam são a identidade que bloqueia e a posição da regra. Acerte nas duas e a mudança passa a ser uma linha que pode testar e remover.

Fixe o cliente antes de escrever a regra

O OpenVPN atribui endereços de túnel a partir de um pool, por isso 10.8.0.6 é um lugar, não uma pessoa. Quando a sessão termina, o aluguer regressa e pode ser entregue à ligação seguinte, o que significa que uma regra escrita contra esse endereço segue o lugar, não o utilizador. Decida primeiro o que bloqueia de facto: um endereço para uma experiência curta ou um certificado para alguém que quer manter fora.

Para ligar o endereço ao certificado, crie um ficheiro no diretório indicado por client-config-dir e dê ao ficheiro exatamente o common name do certificado. Coloque lá uma diretiva, ifconfig-push 10.8.0.6 255.255.255.0, e esse cliente mantém o mesmo endereço de túnel entre reconexões. Têm de existir duas definições para isto ter efeito: client-config-dir tem de estar declarado na configuração do servidor, e o endereço enviado tem de estar numa sub-rede que o servidor consiga encaminhar. Se faltar uma, o ficheiro é ignorado sem erro, o que torna enganador o teste de firewall seguinte.

Um bloqueio temporário pode usar um endereço do pool, desde que o ticket registe que sessão o tinha na altura.

A ordem decide se o descarte é executado

Num gateway Linux que encaminha entre o túnel e a LAN, os pacotes atravessam a cadeia FORWARD. Leia o comando abaixo como uma frase: inserir no topo de FORWARD, corresponder ao tráfego que entra de tun0, daquele único host, endereçado à sub-rede da LAN, e descartá-lo.

iptables -I FORWARD -i tun0 -s 10.8.0.6/32 -d 192.168.1.0/24 -j DROP

É o -I que faz a regra correr. Acrescentada com -A, fica abaixo de qualquer aceitação ampla para a sub-rede do túnel e nunca vê um pacote. Verifique a posição com iptables -vnL FORWARD --line-numbers e leia também os contadores: um descarte no topo que não conta nada significa que o tráfego está a chegar por outro caminho.

O próprio endereço LAN do gateway é outro caminho. Os pacotes enviados para a máquina vão para INPUT, não para FORWARD, por isso um cliente pode perder um host da LAN e ainda abrir a página de administração do router. Acrescente a regra INPUT correspondente quando isso importar.

O que o filtro não consegue ver

A filtragem acontece quando um pacote é avaliado, por isso uma sessão TCP estabelecida pode continuar até fechar ou ser reiniciada. Se o bloqueio tiver de morder de imediato, limpe os fluxos rastreados dessa origem com conntrack -D -s 10.8.0.6 depois de a regra entrar. Se alguns segundos de sobreposição forem aceitáveis, registe essa escolha em vez de a deixar implícita. De qualquer forma, a pessoa seguinte tem de saber se a regra para o tráfego vivo ou apenas as ligações novas.

O tráfego entre pares nunca toca na firewall do host. Com client-to-client ativo, o OpenVPN encaminha esses pacotes dentro do daemon, por isso nem FORWARD nem INPUT os veem. As únicas soluções são desligar o client-to-client ou aceitar que os pares se podem alcançar; uma regra de iptables não verá esse tráfego.

IPv6, firmware e sobrevivência ao reinício

Uma regra IPv4 não diz nada sobre IPv6. Se o túnel e a LAN transportam as duas famílias, a regra equivalente tem de existir em ip6tables, ou no conjunto de regras nftables que detém a política nesse host. O firmware do router esconde muitas vezes o netfilter atrás da sua própria abstração, por isso a sintaxe e os nomes de tabela copiados de um fórum podem não se aplicar.

No OpenWrt, o caminho documentado é uma entrada de configuração da firewall e não uma linha de iptables escrita à mão, e uma linha escrita à mão pode desaparecer quando a firewall recarrega. Outras distribuições restauram regras através de netfilter-persistent, de uma unidade de arranque ou de um armazém do fabricante, e esses mecanismos não são intercambiáveis. Prove o que escolheu com um reinício, porque um recarregamento exercita outro caminho.

Verifique por caminho e depois reverta de forma limpa

Teste cada caminho em separado, porque uma verificação bem-sucedida esconde as outras. Um cliente bloqueado deve continuar a chegar à internet pelo túnel mas falhar contra um host da LAN, um segundo cliente deve chegar a esse mesmo host, e o endereço do gateway e o caminho entre pares precisam cada um da sua observação. Escreva os resultados ao lado da regra para que a mudança seguinte tenha uma base. A tabela abaixo é o conjunto que vale a pena guardar no ticket.

CaminhoEsperado com a regraQuando falha
Cliente bloqueado para um host da LANSem respostaA regra está abaixo de uma aceitação, ou a origem não corresponde
Cliente bloqueado para a internetFunciona por tun0A regra é demasiado ampla, sem correspondência de destino
Segundo cliente para o mesmo host da LANFuncionaA regra correspondeu a mais do que o host pretendido
Cliente bloqueado para o endereço LAN do gatewayBloqueado apenas com a regra INPUT correspondenteFalta a regra INPUT
Cliente bloqueado para um endereço de túnel de um parContinua a funcionarclient-to-client está ativo e fora do alcance da firewall

Reverter é apagar por especificação, não um flush: iptables -D FORWARD -i tun0 -s 10.8.0.6/32 -d 192.168.1.0/24 -j DROP remove exatamente essa entrada e deixa o resto da cadeia intacto. Remova a mesma linha do ficheiro que restaura as regras no arranque, recarregue-o e confirme que o cliente volta a chegar ao host da LAN. Um flush de FORWARD também desfaria regras que não escreveu, o que transforma uma reversão num segundo incidente.

Antes de fechar o ticket, confirme três coisas: o endereço fixado corresponde ao certificado, a regra está acima das aceitações com um contador diferente de zero, e o ficheiro de persistência contém a mesma regra que testou. Se faltar alguma, o bloqueio é uma ilusão de sessão shell.

Artigos relacionados