Relay stream do Nginx para o UDP do OpenVPN: o que muda
O UDP não pertence a um location HTTP. Mova-o para a camada stream, dimensione o tempo limite de sessão para uma VPN e conte com o proxy como origem.
O seu cliente está definido para UDP, o servidor Nginx tem um bloco location que aponta para a porta da VPN, e nada chega. Isso é esperado: um location HTTP não consegue transportar um datagrama UDP, seja qual for o nome dado à interface. O Nginx precisa de um listener stream para isto, e depois de mover a configuração para lá, um segundo conjunto de detalhes decide se uma sessão sobrevive.
A camada de proxy vem antes do endereço
O módulo stream do Nginx faz proxy de TCP e UDP sem analisar HTTP. O seu módulo HTTP espera uma linha de pedido, cabeçalhos e uma resposta, e nada disso existe num datagrama OpenVPN nativo. Escolher a camada é, por isso, a primeira decisão, e é independente de o listener ser IPv4 ou IPv6.
Uma configuração que parece funcionar com OpenVPN em TCP não diz nada sobre o caso UDP. Aqui o transporte faz parte do protocolo, não é um detalhe da implementação.
O listener e o backend
nginx -V 2>&1 | tr ' ' '\n' | grep stream
stream {
server {
listen [::]:1194 udp reuseport;
proxy_pass [2001:db8::20]:1194;
}
}
Confirme que a compilação inclui o módulo stream antes de editar seja o que for; um pacote de distribuição pode separá-lo num módulo à parte, e um módulo em falta produz um erro de configuração em vez de um túnel. Coloque o bloco no contexto principal de configuração, não dentro de http, e substitua o endereço de documentação pelo backend real.
Tanto as duas rotas como as duas firewalls têm de permitir os datagramas: o caminho até ao listener e o caminho do proxy até ao backend. Um listener IPv6 também não cria um caminho IPv4, por isso, se alguns clientes ainda usam IPv4, esse listener é uma entrada separada com os seus próprios testes. Verifique a firewall do próprio backend a partir do endereço do proxy, não do seu portátil.
Os tempos limite de sessão não são tempos limite de pedido
O proxy stream guarda estado para uma sessão UDP e descarta-o segundo o seu tempo limite e as suas definições de resposta. Um tempo limite curto copiado de um relay DNS ajusta-se mal a uma VPN que espera trocar datagramas durante horas, e a falha aparece como uma ligação que morre em silêncio em vez de uma que se recusa a arrancar.
Leia o proxy_timeout efetivo da implementação e qualquer definição de contagem de respostas, e depois compare-os com o comportamento keepalive que a VPN usa realmente. Dois números escritos em ficheiros diferentes por pessoas diferentes é o estado normal de um sistema que funciona. Dois números que nunca foram comparados é o estado normal de um sistema intermitente. Escreva ambos no registo do serviço para que a comparação aconteça uma vez, à luz do dia.
O que o relay muda, e o que não muda
O proxy stream não termina o canal de controlo TLS do OpenVPN nem o converte em HTTPS. O backend continua a ser o serviço VPN, e a relação do certificado mantém-se entre o cliente e esse serviço. Preservar a identidade de backend pretendida continua a ser trabalho do cliente e do servidor.
O proxy comum também altera o endereço de origem que o backend vê. Os registos mostrarão o proxy, e qualquer regra de acesso baseada em IP no servidor VPN avaliará esse endereço em vez do do cliente. Preservar a origem de forma transparente é um desenho à parte de encaminhamento e privilégios, não algo que resulte de acrescentar udp a um listener. Planeie-o antes de ser escrita uma política que dependa do endereço do cliente.
Verifique a partir do cliente, não da porta
Uma verificação local de que a porta UDP está aberta prova que o listener existe. Não prova que um cliente consiga autenticar-se através dele ou continuar a trocar tráfego. Conclua uma ligação real a partir de um cliente aprovado e depois confirme que a sessão se mantém o tempo suficiente para ter importância.
Quando alguém relata que o Nginx não consegue fazer UDP porque uma ferramenta de relay simples funcionou no seu lugar, os dois factos não têm relação. A ferramenta provou que o backend responde; não disse nada sobre o que a interface suporta. Ambos podem ser verdadeiros, e apenas um deles é uma configuração para esta implementação.