Nginx: não é possível determinar uma requisição de endereço no upstream
Há alguns dias, eu me deparei com uma mensagem de erro interessante no Nginx. Veja os detalhes!
Há alguns dias, eu me deparei com uma mensagem de erro interessante no Nginx.
[crit] 12889#0: *32401195 connect() to 127.0.0.1:80 failed (99: Cannot assign requested address) while connecting to upstream
Minha configuração foi muito simples. Isso foi um proxy Nginx que fez toda a criptografia SSL e enviou o tráfego para instância de Varnish, sendo executado em port :80 em localhost. A grande questão aqui é que foi um tráfego bastante elevado de proxy Nginx.
Mesmo com keepalive ativado no upstream do nginx, o erro apareceu. Mas o que isso significa?
Portas TCP e limitesÉ bom saber uma coisa ou duas sobre redes, além de apenas servidores, de vez em quando. O problema ocorreu porque o servidor não poderia ter uma porta TCP livre rápido o suficiente para fazer a conexão com 127.0.0.1.
$ ss -s Total: 3130 (kernel 3431) TCP: 51582 (estab 2866, closed 48611, orphaned 92, synrecv 0, timewait 48611/0), ports 35279
A ferramenta ss oferece estatísticas sobre soquetes/portas no servidor. Neste caso, eu tinha 51.582 sessões TCP em uso (tanto ativas, fechadas, à espera de serem fechada, …).
Um servidor normal tem aproximadamente 28.000 portas TCP possíveis que podem ser usadas para fazer uma conexão TCP para um sistema remoto (ou local). Tudo o que fala por meio de um endereço IP irá escolher uma porta livre dessas para servir como porta de origem para a conexão de saída. Esse intervalo de porta é definido pelo parâmetro sysctl ip_local_port_range.
$ cat /proc/sys/net/ipv4/ip_local_port_range 32768 61000 $ sysctl net.ipv4.ip_local_port_range net.ipv4.ip_local_port_range = 32768 61000
O formato é porta “minimum maximum“. Assim, 61.000-32.768 = 28 232 portas-fonte disponíveis.
Um proxy SSL Nginx que se conecta a uma instância Varnish rodando em localhost será parecido com isto em sua netstat.
$ netstat -anp | grep 127.0.0.1 ... tcp 0 0 127.0.0.1:37713 127.0.0.1:80 TIME_WAIT -
O principal tópico aqui é a conexão de fonte de 127.0.0.1:37713 que se conecta ao seu endpoint 127.0.0.1:80. Para cada origem de conexão, uma nova fonte porta TCP é selecionada a partir do intervalo no parâmetro ip_local_port_range.
A combinação de um IP de origem, porta de origem, IP de destino e destino IP deve ser única. Isso é o que é chamado um quadruplet em termos de rede. Você provavelmente não pode (facilmente) mudar o IP de origem. A porta de origem é escolhida de forma dinâmica. Isso só deixa a o IP de destino e a porta de destino livres para brincar.
Resolvendo a limitação da porta de origemHá algumas correções fáceis. Primeiro, o ip_local_port_range pode ser aumentado em uma máquina Linux (para obter mais material de leitura, ver aumentar o intervalo ip_local_port_range de portas TCP no Linux).
$ echo 15000 64000 > /proc/sys/net/ipv4/ip_local_port_range
Isso efetivamente aumenta o intervalo de portas totais do padrão de 28.232 para 49.000 portas.
Se isso não for suficiente, você pode adicionar mais IPs de destino para se conectar. Lembre-se de que cada conexão consiste em 4 partes (chamadas quadruplets) com porta de origem e IP de origem, IP de destino e porta de destino. Se você não pode mudar a porta de origem ou IP, basta alterar os IPs de destino.
Considere este tipo de definição para o upstream em Nginx;
upstream varnish {
server 127.0.0.1:80;
}
Essa definição pode ser usada em suas configurações nginx com a diretiva proxy_pass.
server {
listen 443;
...
location / {
proxy_pass http://varnish;
...
}
}
Agora, se você sabe que cada servidor tem geralmente 2 IPs ou mais, é muito fácil adicionar mais quadriplets à sua pilha de rede, fazendo uma adição ao seu IP Nginx upstream. Você já adicionou 127.0.0.1, mas o servidor terá um outro IP (será público ou DHCP IP) que você pode adicionar com segurança também, se o seu servidor web se liga a todas as portas.
upstream varnish {
server 127.0.0.1:80;
server 31.193.180.217:80;
server 10.50.5.1:80;
...
}
Cada IP que você adicionar em seu upstream está efetivamente adicionando 49.000 portas locais para a sua pilha de rede. Você pode até adicionar IPs locais não-roteáveis para o servidor, como aliases de interface, apenas para usar como novos IPs de destino para as suas configurações de proxy.
***
Mattias Geniar faz parte do time de colunistas internacionais do iMasters. A tradução do artigo é feita pela redação iMasters, com autorização do autor, e você pode acompanhar o artigo em inglês no link: https://ma.ttias.be/nginx-cannot-assign-requested-address-for-upstream/








