Bloquear um cliente OpenVPN da LAN sem parar o túnel
Fixe o endereço de túnel do cliente ao certificado, descarte o tráfego LAN no topo de FORWARD e depois verifique IPv6, sessões rastreadas e sobrevivência ao reinício.
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.
| Caminho | Esperado com a regra | Quando falha |
|---|---|---|
| Cliente bloqueado para um host da LAN | Sem resposta | A regra está abaixo de uma aceitação, ou a origem não corresponde |
| Cliente bloqueado para a internet | Funciona por tun0 | A regra é demasiado ampla, sem correspondência de destino |
| Segundo cliente para o mesmo host da LAN | Funciona | A regra correspondeu a mais do que o host pretendido |
| Cliente bloqueado para o endereço LAN do gateway | Bloqueado apenas com a regra INPUT correspondente | Falta a regra INPUT |
| Cliente bloqueado para um endereço de túnel de um par | Continua a funcionar | client-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.