Os clientes de dois servidores OpenVPN conseguem alcançar-se uns aos outros?
Dois servidores OpenVPN criam dois pools de clientes, não uma rede. Encaminhe entre eles com sub-redes distintas, rotas recíprocas e uma fronteira de confiança explícita.
Levantar um segundo OpenVPN servidor dá-lhe um segundo local para os clientes se ligarem, e nada mais. Não coloca esses clientes na rede do primeiro servidor, e a opção chamada client-to-client só altera o encaminhamento dentro de um único processo de servidor. Os dois pools tornam-se uma rede quando encaminha entre eles, de propósito, com um responsável por cada direção. Tudo abaixo assume o modo TUN em espaço de utilizador com esse encaminhamento interno desligado, para que o kernel tome a decisão.
O mito: uma lista de contas, uma rede
Autenticação e alcançabilidade confundem-se porque ambas vivem na configuração do servidor. Um utilizador que consegue iniciar sessão em qualquer um dos dois gateways parece, do exterior, um utilizador num sistema com duas portas. No interior, cada servidor distribui endereços do seu próprio pool e instala rotas apenas para os clientes que termina. Assim, um cliente no gateway A que envia um pacote para um cliente no gateway B está a pedir um destino de que o seu próprio servidor nunca ouviu falar. O pacote segue a rota padrão de A, sai do túnel e chega a uma firewall a quem nunca se pediu que o permitisse.
Acrescentar um segundo servidor não acrescenta, portanto, redundância, descoberta nem um domínio de broadcast partilhado. Acrescenta uma rede encaminhada que precisa de um plano, e o plano começa pelo endereçamento.
Dê a cada gateway o seu próprio pool e endereço de trânsito
Dois intervalos que não podem sobrepor-se a mais nada, mais uma pequena ligação de trânsito entre os hosts, é todo o plano de endereçamento. Mantenha o trânsito num segmento privado que controla, e escreva os números antes de qualquer servidor atribuir uma concessão.
| Gateway | Client pool | Transit address |
|---|---|---|
| gateway-a | 10.64.10.0/24 | 172.28.44.1/30 |
| gateway-b | 10.64.20.0/24 | 172.28.44.2/30 |
Resista à tentação de dar aos dois servidores o mesmo pool para que os perfis fiquem idênticos. Uma rota do kernel não consegue dizer qual de dois hosts possui atualmente um endereço arbitrário dentro de um intervalo partilhado, pelo que a tabela de rotas apontaria para um gateway e o cliente pode estar ligado ao outro. Os nomes das interfaces são convenções locais, não estado partilhado. Ambos os hosts aqui chamam ao dispositivo de túnel tun0 e à ligação de trânsito transit0, o que é aceitável porque nenhum pacote transporta esses nomes.
Instale a rota em ambos os lados
Cada gateway precisa de uma rota para o pool do outro através do endereço de trânsito, e o encaminhamento tem de estar ativo para qualquer um atuar como salto. Confirme primeiro a tabela atual, depois acrescente a entrada e torne-a persistente através do gestor de rede do host em vez de um hook de reconexão.
sysctl net.ipv4.ip_forward
ip route add 10.64.20.0/24 via 172.28.44.2 dev transit0
ip route get 10.64.20.37
Espelhe isso no outro host com os pools trocados. Acrescentar repetidamente a mesma rota a partir de um script não relacionado é como um host acaba com várias cópias e uma alteração misteriosa da próxima vez que alguém lê a tabela. Se a ligação de trânsito for ela própria um túnel, a rota aponta para a topologia desse túnel e o salto tem de sobreviver à sua reconexão. Um endereço de trânsito que desaparece durante trinta segundos leva consigo o caminho entre pools, o que é uma propriedade de projeto que vale a pena enunciar em vez de descobrir.
Empurre a rota do cliente sem fingir propriedade
Os clientes precisam de uma rota para o pool remoto, caso contrário o seu próprio sistema operativo envia o pacote para o gateway padrão e o túnel nunca o vê. A configuração do servidor é o local natural para a entregar.
push "route 10.64.20.0 255.255.255.0"
Coloque a linha espelhada na configuração do outro servidor, depois reconecte um cliente de teste e leia a sua tabela. Um cliente que ignora rotas empurradas precisa da sua própria configuração aprovada, e uma rota que nunca chega não é controlo de acesso. Não dê a um cliente um iroute para todo o pool do outro gateway. Essa diretiva existe para uma sub-rede atrás de um cliente ligado, e usá-la para encobrir uma rota ausente entre gateways produz um servidor que acredita possuir endereços que não consegue alcançar.
Prove um pedido e recuse outro
Escolha uma operação real, por exemplo HTTPS de um cliente em 10.64.10.21 para um serviço em 10.64.20.37, e permita exatamente isso em ambos os hosts. Cada firewall admite o pedido do lado de entrada e a resposta rastreada do lado de retorno; a política do próprio serviço de destino ainda tem de o aceitar.
iptables -A FORWARD -i tun0 -o transit0 -s 10.64.10.21 -d 10.64.20.37 -p tcp --dport 443 -j ACCEPT
iptables -A FORWARD -i transit0 -o tun0 -d 10.64.10.21 -s 10.64.20.37 -p tcp --sport 443 -m conntrack --ctstate ESTABLISHED -j ACCEPT
Com rotas recíprocas, o NAT de origem é desnecessário e aqui ativamente prejudicial: traduzir a origem esconde qual cliente fez o pedido e derrota a política baseada na origem do lado do destino. Verifique se uma regra de masquerade existente para saída para a internet também não apanha este caminho. Depois teste a recusa. Um serviço que deve permanecer local ao pool B tem de continuar inalcançável a partir do pool A, e os pares de clientes no mesmo gateway também precisam de teste, já que a política de encaminhamento que acabou de alterar também se lhes aplica.
Mais uma correção ao modelo mental: a ligação de trânsito transporta pacotes internos desencriptados, pelo que é uma fronteira de confiança e não uma garantia privada. Se atravessar uma rede que não controla, proteja esse salto com um túnel encriptado aprovado e encaminhe pela sua topologia real. O TLS ponta a ponta continua a autenticar a aplicação por si, e é por isso que o serviço interno deve continuar a usá-lo.