Site NGINX só para VPN: listener, firewall e lista de permissão HTTP
Um site NGINX privado precisa de um socket VPN vinculado, uma regra de entrada de host limitada e uma lista de acesso HTTP intacta. Teste as três, não apenas um bloco de servidor.
Três decisões independentes separam um site privado da internet: qual socket aceita a conexão, qual caminho pode entregá-la e a quais clientes HTTP o servidor escolhido responde. Um bloco de servidor toma apenas a primeira decisão. Trate as outras duas como controles separados, ou o site parecerá privado enquanto uma entrada antiga continua aberta. A maioria das falhas de NGINX só para VPN vem de testar apenas a primeira camada.
O exemplo usa um gateway Linux OpenVPN em 10.90.0.1 na tun0, clientes em 10.90.0.0/24, origens preservadas e TCP 8443 reservado para esta entrada. Ajuste os valores, mantenha as camadas.
Comece pelo socket, não pelo nome do host
Vincule o listener HTTPS ao endereço do túnel e a uma porta dedicada. Um endereço específico é mais fácil de raciocinar do que um socket curinga mais uma verificação de nome, porque o kernel não entregará a porta a outro endereço local.
server {
listen 10.90.0.1:8443 ssl;
server_name admin.corp.example;
ssl_certificate /etc/nginx/tls/admin-fullchain.pem;
ssl_certificate_key /etc/nginx/tls/admin-key.pem;
root /srv/private-site;
allow 10.90.0.0/24;
deny all;
location / {
try_files $uri $uri/ =404;
}
}
O certificado deve nomear o host do serviço que os clientes digitam, e a visão DNS privada deve resolver esse host para o endereço vinculado. server_name apenas escolhe um host virtual; não autentica ninguém. Uma entrada DNS ausente produz um erro de certificado que parece uma falha de TLS. Verifique o nome antes de substituir o certificado.
Leia a configuração efetiva antes de adicionar o arquivo. Inclusões e listeners curinga podem servir a mesma raiz em outro lugar, e um servidor padrão pode responder a solicitações que o novo bloco nunca vê.
Feche todos os outros listeners para esse conteúdo
Liste as diretivas listen e compare as raízes que elas servem. Um bloco adicionado para outro aplicativo pode fazer proxy para o mesmo upstream, e um servidor padrão antigo pode continuar respondendo depois que o novo estiver no lugar. Essa saída é o inventário real, não o arquivo que você acabou de editar. Compare cada raiz que serve o mesmo conteúdo.
sudo nginx -T | grep -n "listen\|server_name\|root\|proxy_pass"
Verifique as duas famílias de endereços. Uma vinculação IPv4 deixa um socket IPv6 intacto, e um novo registro A não retira uma resposta AAAA antiga que ainda aponta para um caminho público.
Aposente o host virtual antigo como uma mudança separada. Remover o gêmeo público do novo bloco costuma ser o passo que realmente fecha a entrada; o listener privado apenas adiciona a pretendida.
Limite o caminho de entrada no host
O endereço de escuta limita o socket, não a interface de entrada. Um pacote roteado para esse endereço de outro lugar ainda chega como entrada local, por isso o firewall do host precisa da própria declaração sobre de onde a conexão pode vir. É por isso que uma vinculação sozinha raramente satisfaz uma auditoria.
Com uma política de entrada de negação por padrão e sem uma permissão mais ampla para este serviço, uma regra delimitada nomeia o túnel, o intervalo de origem, o destino e a porta juntos:
sudo ufw allow in on tun0 proto tcp from 10.90.0.0/24 to 10.90.0.1 port 8443
Leia a ordem efetiva do firewall antes de aplicá-la. Uma aceitação ampla anterior pode anular a restrição, e um descarte terminal anterior pode impedir que esta permissão seja alcançada. Não limpe regras não relacionadas nem desligue o firewall para que o exemplo se encaixe.
Essa regra é entrada do host, não uma rota para outra máquina da LAN, e o listener OpenVPN externo do gateway continua sendo um serviço separado. Se o site era público antes, planeje como a entrada antiga é aposentada e como as sessões existentes são tratadas.
Mantenha a lista HTTP intacta enquanto as localizações mudam
O NGINX avalia as entradas allow e deny em ordem, e a lista no nível do servidor acima admite o conjunto declarado antes do deny final. O módulo de acesso também registra que uma localização que define qualquer entrada de acesso usa a própria lista em vez da lista pai. A ordem importa tanto quanto as próprias entradas.
Esse reset é a regressão habitual. Uma nova localização de upload, API ou saúde que adiciona uma entrada substitui silenciosamente a restrição no nível do servidor, e o site fica mais amplo no caminho adicionado mais recentemente.
Revise cada localização, alias e bloco alternativo como parte da mesma política. Se as verificações de IP forem combinadas com a autenticação do NGINX, entenda satisfy: uma configuração any pode admitir um cliente por um mecanismo enquanto o outro não passou. Coloque a lista de acesso na lista de verificação de localizações.
Uma negação HTTP ocorre depois que a conexão TCP chega ao NGINX. Ela complementa a restrição de rede, e a autorização da própria aplicação continua valendo para cada usuário.
Verifique o caminho ativo e o caso de falha
Execute o analisador de configuração, inspecione os sockets em escuta e faça uma nova solicitação nomeada a partir de um cliente previsto. Confirme que o certificado valida, que o nome DNS resolve para o endereço vinculado e que a resposta vem da raiz esperada.
Teste a seguir uma origem excluída e uma entrada alternativa. Uma solicitação permitida que funciona não diz nada sobre os caminhos que você queria fechar, e é no teste excluído que aparece um listener remanescente ou uma aceitação ampla do firewall.
Repita o caso de inicialização ou recuperação de VPN. Se o NGINX iniciar antes de o endereço do túnel existir, a vinculação pode falhar mesmo com um arquivo perfeito. Coordene a prontidão do endereço e mantenha um caminho de recuperação local antes de alterar um servidor web compartilhado.
Registre o socket, a porta, o intervalo de origem e a lista HTTP que passaram. A próxima mudança de VPN ou DNS pode mover qualquer um deles, e quatro valores nomeados são mais fáceis de comparar do que uma aba de navegador que funciona.