Do 'no route to host' ao virtual host: debugging de Nginx standalone e redes na nuvem#
Recentemente, configurei uma instância de NGINX standalone para atender diretamente na porta 80 em um ambiente de nuvem. Embora a configuração inicial de um servidor web pareça direta, a realidade do terminal frequentemente envolve detalhes de baixo nível: permissões de binding no kernel, comportamento de filtros de pacotes e regras de borda de firewalls de nuvem.
Abaixo, compartilho o fluxo prático: do ciclo de vida dos processos do NGINX ao diagnóstico do erro No route to host e à implementação modular de Virtual Hosts (server blocks).
1. O ponto de partida: Nginx standalone e portas privilegiadas#
Para escutar na porta HTTP padrão (80), a diretiva básica no bloco server {} é:
server {
listen 80 default_server;
listen [::]:80 default_server; # Suporte a IPv6
server_name _;
location / {
root /usr/share/nginx/html;
index index.html;
}
}
Para cenários com alta concorrência em sistemas multi-core, a diretiva listen pode ser otimizada com a flag de kernel reuseport:
listen 80 default_server reuseport;
O que acontece no kernel (master-worker e capabilities)#
A porta 80 está na faixa privilegiada do Linux (0 a 1023):
- O processo Master do NGINX inicia como
rootpara invocar a syscallsocket()e realizar obind()exigindo a capabilityCAP_NET_BIND_SERVICE. - Após o
listen(), o Master gera os processos Worker viafork()e rebaixa seus privilégios viasetuid()esetgid()para o usuárionginxouwww-data, mitigando riscos de segurança.
Se for necessário rodar o binário sem privilégios de root, conceda a capability diretamente ao arquivo:
setcap 'cap_net_bind_service=+ep' /usr/sbin/nginx
2. O sintoma: "no route to host" no IP público#
Ao testar a conectividade externa contra o IP público da instância (203.0.113.10):
telnet 203.0.113.10 80
# Trying 203.0.113.10...
# telnet: Unable to connect to remote host: No route to host
Verificando os sockets ativos no host com ss -tulpn:
tcp LISTEN 0 511 0.0.0.0:80 0.0.0.0:* users:(("nginx",pid=4356,fd=5))
tcp LISTEN 0 511 [::]:80 [::]:* users:(("nginx",pid=4356,fd=6))
Testando localmente na interface de loopback:
telnet 127.0.0.1 80
# Connected to 127.0.0.1.
Análise da causa raiz#
Se o socket responde em 127.0.0.1:80, o NGINX está funcionando perfeitamente. O erro No route to host (ICMP Type 3, Code 1) indicava rejeição ativa na camada de rede.
Inspecionando a tabela de roteamento e regras do iptables:
# Verificar contadores do iptables na porta 80
iptables -L INPUT -n -v | grep :80
# 0 0 ACCEPT 6 -- * * 0.0.0.0/0 0.0.0.0/0 tcp dpt:80
Três fatores explicavam o bloqueio:
- Contador zerado no iptables: A regra da porta 80 acumulava
0 pkts, provando que o tráfego era descartado antes dessa linha ou fora do host. - Falta de Hairpin NAT: A rota local enviava pacotes para o IP público através do gateway padrão (
10.0.0.1), que não fazia loopback para a própria interface. - Firewall de borda da nuvem: Em provedores como Oracle Cloud, AWS ou GCP, as Security Lists ou Network Security Groups bloqueiam tráfego de entrada na porta 80 por padrão até que uma regra explícita de Ingress seja criada.
3. Desbloqueio e ajustes de firewall#
- Precedência no iptables local:
Insira a regra de liberação na primeira posição da chain para ficar acima de qualquer regra genérica de REJECT:
iptables -I INPUT 1 -p tcp --dport 80 -j ACCEPT
netfilter-persistent save
- Liberação nas Security Lists da nuvem:
No painel da nuvem (VCN > Security Lists), adicione uma regra de entrada:
- Source CIDR:
0.0.0.0/0 - Protocolo: TCP
- Destination Port:
80
4. Implementando virtual hosts modulares#
Com a conectividade restabelecida, o passo seguinte foi estruturar vHosts limpos e modulares.
Inclusão no /etc/Nginx/nginx.conf#
No bloco http {}:
http {
include /etc/nginx/sites-enabled/*;
}
Configuração do vhost (/etc/Nginx/sites-available/meusite.com.br.conf)#
server {
listen 80;
listen [::]:80;
server_name meusite.com.br www.meusite.com.br;
access_log /var/log/nginx/meusite.access.log combined buffer=16k;
error_log /var/log/nginx/meusite.error.log warn;
root /var/www/meusite.com.br/public_html;
index index.html index.php;
# Bloqueio de arquivos ocultos (.git, .env, .htaccess)
location ~ /\.(?!well-known).* {
deny all;
access_log off;
log_not_found off;
}
location / {
try_files $uri $uri/ /index.html;
sendfile on;
tcp_nodelay on;
keepalive_timeout 65;
}
}
Performance: sendfile on transfere dados diretamente do descritor de arquivo no disco para o socket de rede no Kernel Space, eliminando cópias desnecessárias na memória do User Space.
Ativação e recarga segura#
# 1. Criar o symlink
ln -s /etc/nginx/sites-available/meusite.com.br.conf /etc/nginx/sites-enabled/
# 2. Testar sintaxe
nginx -t
# 3. Recarregamento gracioso (SIGHUP)
nginx -s reload
Validando a resposta do vhost localmente#
Para testar o roteamento antes da propagação do DNS:
curl -H "Host: meusite.com.br" http://127.0.0.1
O NGINX processa o cabeçalho Host e entrega o conteúdo exato do vHost configurado.
Boas práticas de rede e vhosts no Nginx#
- Valide em etapas: Teste primeiro em
127.0.0.1antes de depurar a rede pública. Se a loopback responde, o serviço está saudável e o bloqueio é de firewall ou roteamento. - Cuidado com a ordem do iptables: Regras adicionadas com
-Aficam no final da chain, muitas vezes atrás de uma regra padrão de descarte (REJECT-with-icmp-host-prohibited). Use-Ipara garantir precedência. - Use sendfile e buffers: Diretivas como
sendfile one buffers em logs de acesso reduzem o impacto de I/O em servidores com grande volume de requisições.
Este artigo foi útil?
Deixe uma reação rápida para apoiar o conteúdo:
Este post está licenciado sob CC BY-NC.



Comentários
Participe da discussão abaixo.
0 comentários