Há quase um ano, implementamos uma feature da RFC seguindo à risca a especificação — e ela derrubou a produção. Fizemos rollback, investigamos a fundo e encontramos o problema. Spoiler: não era o DNS. Éramos nós esquecendo que portas são um recurso finito.
Precisa de proxies móveis?Crie um proxy agora mesmo!
Adicionamos suporte completo a SOCKS5 UDP ASSOCIATE (RFC 1928) nos servidores proxy do iProxy.online. Alguns dias depois, o DNS parou de resolver, túneis começaram a cair e serviços aleatórios ficavam com timeout. Fizemos rollback e começamos a investigar. A causa raiz era esgotamento de portas efêmeras no Linux — milhares de UDP associations, cada uma segurando uma porta dedicada, drenaram o pool inteiro do sistema. A correção foram dois ajustes de configuração. Encontrar o problema levou bem mais tempo.
O SOCKS5, definido na RFC 1928, suporta três comandos: CONNECT (tunelamento TCP), BIND (aceitar conexões TCP de entrada) e UDP ASSOCIATE (relay de datagramas UDP). A maioria dos provedores de proxy implementa apenas o CONNECT. O UDP ASSOCIATE é o mais difícil — e o que importa para aplicações em tempo real como VoIP, jogos online, DNS-over-UDP e QUIC.
Funciona assim:
O cliente abre uma conexão TCP de controle com o servidor SOCKS5.
O cliente envia uma requisição UDP ASSOCIATE por essa conexão TCP.
O servidor aloca um socket UDP dedicado em uma porta efêmera e responde com o endereço e número da porta.
O cliente envia datagramas UDP para essa porta de relay. O servidor encaminha para o destino e retransmite as respostas de volta.
A associação permanece ativa até que a conexão TCP de controle seja fechada ou o timeout da sessão expire.
Cada associação UDP ocupa uma porta efêmera separada no servidor. Esse é o detalhe crítico.
E aqui está a armadilha. UDP não tem conexão. Não existe FIN, não existe RST. Como saber que o cliente terminou para liberar a porta?
Aguardar o fechamento da conexão TCP de controle — o sinal previsto na RFC. Mas clientes podem manter essa conexão aberta indefinidamente.
Timeout por inatividade. Se nenhum datagrama chega por X segundos, você encerra. Mas se o timeout for alto demais, os sockets se acumulam.
Configuramos timeouts generosos e não limitamos quantas associações um único cliente podia abrir. Resultado: os sockets foram se acumulando.
No iProxy.online operamos infraestrutura de proxy móvel em mais de 100 países e 600+ operadoras — incluindo Claro, Vivo, TIM e Oi no Brasil — transformando celulares Android reais em servidores proxy. Se o conceito é novo para você, nosso guia sobre como montar uma rede de proxy 4G detalha toda a arquitetura. Nossos servidores SOCKS5 de backend lidam com dezenas de milhares de conexões simultâneas.
Há cerca de um ano, decidimos implementar suporte completo a UDP ASSOCIATE — nos tornar verdadeiramente conformes com a RFC e habilitar casos de uso que a maioria dos concorrentes não atende: proxy para VoIP, tráfego de jogos, protocolos baseados em QUIC. A implementação estava correta. Os testes passaram. Colocamos em produção.
Construir infraestrutura de proxy nessa escala significa que cada decisão de protocolo tem consequências reais. No iProxy.online, cada dispositivo Android opera como um servidor proxy móvel independente — SOCKS5, HTTP e agora UDP completo — gerenciado por um dashboard único ou pelo bot do Telegram. Se quiser ver como o sistema funciona antes de ler como o quebramos, comece um teste grátis de 48 horas — sem necessidade de cartão de crédito.
Alguns dias depois, os servidores de produção começaram a apresentar sintomas estranhos, aparentemente sem relação entre si:
A falha não foi gradual — foi um penhasco. Tudo funcionava normalmente por horas, depois múltiplos serviços falhavam simultaneamente no mesmo host. Fizemos rollback do UDP ASSOCIATE e começamos a investigar.
Nosso instinto inicial estava errado. Verificamos ataques DDoS, vazamentos de memória, saturação de I/O de disco e carga de CPU — tudo normal. Health checks no nível de aplicação estavam verdes até o momento exato em que tudo morreu.
A descoberta veio de métricas de baixo nível que a maioria das equipes nunca monitora:
node_sockstat_UDP_inuse estava subindo para dezenas de milhares. Em um servidor saudável, esse número fica na casa das centenas. O nosso ultrapassou 20 mil.
Contadores de ICMP Type 3 Code 3 (port unreachable) dispararam. É o kernel dizendo "não consigo alocar uma porta de origem para esse pacote UDP de saída."
Uma verificação manual rápida confirmou:
ss -u state all | wc -l
# 28.431
cat /proc/net/sockstat
# UDP: inuse 28419
O range de portas efêmeras no Linux é, por padrão, 32768–60999 — aproximadamente 28 mil portas. Havíamos consumido quase todas.
A conta é simples. O Linux tem um pool finito de portas efêmeras — cerca de 28 mil por padrão. Cada UDP ASSOCIATE consome uma. Centenas de associações simultâneas mais limpeza lenta é igual a pool esgotado.
Quando as portas efêmeras acabam, qualquer coisa no servidor que precise abrir um novo socket UDP falha. Incluindo o DNS — cada consulta DNS de saída precisa de uma porta efêmera como origem para enviar a requisição à porta 53. A resolução de nomes morre, e de repente tudo no servidor está quebrado por motivos que não têm absolutamente nada a ver com DNS.
O efeito cascata em detalhe:
Alocação de portas → cada UDP ASSOCIATE chama bind() com porta 0, pedindo ao kernel a próxima porta efêmera disponível.
Acúmulo de portas → a porta permanece aberta até o TCP fechar ou o timeout de inatividade expirar. Timeouts generosos fazem portas se acumularem mais rápido do que são liberadas.
Exaustão do pool → com milhares de associações segurando portas, o pool inteiro é drenado. bind() começa a retornar EADDRINUSE para cada novo socket.
Falha sistêmica → consultas DNS falham (systemd-resolved também precisa de portas efêmeras). Handshakes WireGuard falham. NTP falha. Syslog-over-UDP falha silenciosamente. Aí a falha DNS causa uma cascata secundária — qualquer coisa que resolva hostnames para de funcionar, incluindo health checks, conexões de banco de dados e agentes de monitoramento. O servidor parece "fora do ar" mesmo com CPU, memória e disco normais.
Health checks HTTP passavam — o endpoint estava respondendo. CPU, memória, disco, throughput todos normais. Métricas no nível de processo não mostravam nada incomum. O processo SOCKS5 estava saudável. Era o pool de portas do kernel que estava esgotado, e nada em um dashboard Grafana padrão monitora isso.
As únicas métricas que pegaram o problema foram as que tínhamos adicionado quase como extra: contadores de socket no nível de kernel e taxas de erro ICMP.
Resolvemos com dois ajustes. Levou mais tempo para debugar do que para corrigir.
1. Redução drástica dos timeouts de inatividade. Diminuímos o timeout de inatividade das associações UDP de minutos para segundos. Se nenhum datagrama passa pela porta de relay por um intervalo curto, a associação é encerrada e a porta é liberada. A maioria das sessões UDP legítimas (consultas DNS, NTP) completa em bem menos de um segundo. Sessões de longa duração (VoIP, jogos) mantêm a associação ativa pelo tráfego contínuo, então não são afetadas.
2. Limites de associações simultâneas por cliente. Limitamos quantas associações UDP simultâneas um único cliente pode manter. Isso impede que um único usuário — ou cliente mal configurado — monopolize o pool de portas. O limite é generoso o suficiente para uso legítimo, mas impede o acúmulo descontrolado.
Juntos, esses ajustes trouxeram o UDP_inuse de 28 mil de volta para algumas centenas. Relançamos o UDP ASSOCIATE com os novos limites e tem estado estável desde então.
A correção em si foi direta — o mais difícil foi construir suporte a SOCKS5 UDP ASSOCIATE capaz de lidar com dezenas de milhares de sessões simultâneas sem drenar recursos do sistema. Se você precisa de um proxy móvel com relay UDP completo e gerenciamento de ciclo de vida já integrado, o iProxy.online roda em dispositivos Android reais com mais de 600 operadoras, com rotação de IP, controle por dispositivo e planos a partir de US$ 6/mês. Ideal para quem quer criar proxy móvel com escala profissional.
Se você opera qualquer coisa que abre sockets UDP em escala — servidores proxy SOCKS5, servidores de jogos, infraestrutura VoIP, relays QUIC — adicione estas métricas ao seu stack:
node_sockstat_UDP_inuse (node_exporter). Sockets UDP abertos em tempo real. Um servidor normal fica em algumas centenas. Se você usa Prometheus, a métrica já está lá — só precisa de um painel e um alerta. Sugerimos alertar acima de 5.000.
node_netstat_Icmp_OutDestUnreachs (ICMP Type 3 Code 3, port unreachable). Picos indicam que o kernel está respondendo a pacotes UDP chegando em portas onde ninguém está ouvindo. Alguns por minuto é ruído. Milhares por segundo é incêndio.
ss -u state all | wc -l — verificação rápida durante um incidente.
cat /proc/net/sockstat — o clássico one-liner sem dependências.
Essas métricas não estão na maioria dos dashboards padrão. Deveriam estar. Para mais dicas sobre como manter a saúde da sua infraestrutura de proxy, veja nosso guia sobre como otimizar velocidade e estabilidade de proxy.
Portas são um recurso finito — faça o planejamento de capacidade. Fazemos planejamento de CPU, RAM, disco e banda. Ninguém faz planejamento de portas efêmeras. Em um servidor lidando com dezenas de milhares de conexões, ~28 mil portas não é muito. Dá para expandir o range com sysctl -w net.ipv4.ip_local_port_range="1024 65535", mas mesmo 64 mil é finito quando cada associação segura uma porta indefinidamente.
RFCs dizem O QUÊ, não COMO. A RFC 1928 foi escrita em 1996, quando um servidor "ocupado" lidava com centenas de conexões. Ela descreve a mecânica do protocolo perfeitamente. Não diz nada sobre gerenciamento de ciclo de vida de portas, limites de recursos ou degradação graciosa. Se você está implementando qualquer protocolo em escala, leia a RFC para garantir conformidade e projete seu próprio gerenciamento de recursos por cima.
Métricas de kernel revelam o que métricas de aplicação não veem. Health checks, scrapers Prometheus e pings HTTP todos nos diziam que os servidores estavam saudáveis. O kernel sabia a verdade. Se o seu monitoramento não inclui estatísticas de socket e contadores ICMP, você tem um ponto cego para toda uma classe de falhas por exaustão de recursos. Tivemos uma lacuna de observabilidade semelhante com falhas silenciosas de TLS 1.3 em nossa frota de dispositivos Android — causa raiz diferente, mesma lição.
UDP exige gerenciamento explícito de ciclo de vida. TCP tem ciclo de vida embutido — conexões abrem, transferem dados e fecham com um handshake definido. Portas são reutilizadas após TIME_WAIT. UDP não tem nada disso. Um socket fica aberto até que algo explicitamente o feche. Em arquiteturas de relay, você precisa construir seu próprio gerenciamento de ciclo de vida ou aceitar consumo ilimitado de recursos.
Este problema não é exclusivo de proxy. Qualquer infraestrutura que aloca sockets UDP com base em requisições de usuários pode bater na mesma parede:
Se você opera algum desses em escala — ou mantém um farm de proxy móvel — verifique seus números de sockstat hoje. Você pode estar mais perto do precipício do que imagina.
Implementamos SOCKS5 UDP ASSOCIATE corretamente — conforme a RFC, testado, em produção. E causou uma falha sistêmica que nosso monitoramento padrão não conseguiu enxergar.
A lição que agora tratamos como regra inviolável: qualquer feature que aloca recursos no nível de kernel — portas, file descriptors, entradas de conntrack — precisa de gerenciamento explícito de ciclo de vida e planejamento de capacidade desde o primeiro dia. Não como correção depois da primeira queda.
Portas são como oxigênio. Você só percebe quando acabam.
Este é um incidente real de produção do iProxy.online. Construímos infraestrutura de proxy móvel que transforma celulares Android em servidores proxy SOCKS5 e HTTP, operando em mais de 100 países e 600+ operadoras. Suporte completo a UDP ASSOCIATE incluso — agora com gerenciamento adequado de recursos. Criar proxy móvel com iProxy →
SOCKS5 UDP ASSOCIATE é um dos três comandos definidos na RFC 1928. Ele permite que clientes façam relay de datagramas UDP através de um proxy SOCKS5, estabelecendo um socket UDP dedicado para cada associação. Diferente do CONNECT (tunelamento TCP), o UDP ASSOCIATE lida com tráfego sem conexão — usado para DNS, VoIP, jogos online e protocolos QUIC.
O Linux usa por padrão o range 32768–60999, totalizando aproximadamente 28 mil portas. Verifique o range atual com cat /proc/sys/net/ipv4/ip_local_port_range e expanda com sysctl -w net.ipv4.ip_local_port_range="1024 65535" para até ~64 mil portas. Mesmo o range expandido é finito em cargas pesadas de relay UDP.
Toda consulta DNS de saída precisa de uma porta efêmera de origem para enviar um pacote UDP à porta 53. Quando todas as portas efêmeras estão consumidas por outros sockets UDP, o kernel não consegue alocar novas, e a resolução DNS falha em todo o sistema — mesmo que o servidor DNS em si esteja perfeitamente funcional.
Acompanhe node_sockstat_UDP_inuse no Prometheus/node_exporter para contagem de sockets UDP em tempo real. Use ss -u state all | wc -l ou cat /proc/net/sockstat para verificações manuais. Configure alertas para picos de ICMP Type 3 Code 3 (port unreachable) via node_netstat_Icmp_OutDestUnreachs.
Sim. O iProxy.online suporta SOCKS5 UDP ASSOCIATE completo, além de CONNECT e proxy HTTP. Após o incidente descrito aqui, adicionamos limites por cliente e timeouts agressivos de inatividade para prevenir esgotamento de portas, mantendo o relay UDP totalmente funcional para VoIP, jogos e tráfego QUIC.
Seja operando servidores TURN, infraestrutura de jogos ou uma rede de proxy móvel, o gerenciamento de portas efêmeras importa. iProxy.online oferece SOCKS5 pronto para produção com UDP ASSOCIATE, controle via dashboard e API, e configuração em menos de cinco minutos em qualquer celular Android. Teste grátis por 48 horas — valide com sua carga de trabalho real.