Há pouco mais de dois anos saí da Vero (provedor de internet), onde eu tinha um IP público funcional, para a TIM Ultrafibra. O motivo que me levou a trocar de provedor foi simples: a TIM oferecia velocidades monstruosas e eu tinha equipamento para suportá-las.
Na Vero eu já me dava por satisfeito com meu 1 Gb, mas eu queria os 2.5 Gb da TIM. Então fui lá e troquei.
Minha triste surpresa foi ver que a TIM não oferecia IP público — e nem dava espaço para negociar. Depois de tentativas extremamente fracassadas, decidi arrumar outro jeito de expor alguns serviços de streaming.
Ainda bem que tenho uma experiência decente com redes, o que me poupou de muita dor de cabeça. Mas eu ainda precisaria de mais conhecimento se quisesse o sistema funcionando de forma plena.
Quando se usa CGNAT — o famoso IP compartilhado —, a experiência no quesito streaming (upload) costuma ser bem ruim, por dois problemas da rede:
- MTU mal configurado.
- Portas UDP reciclando em velocidades extremas.
Há outros motivos por aí, mas esses dois são os principais que tornam a experiência terrível. É por isso que muitos tentam negociar IPs públicos com seus provedores, e é a mesma razão das famosas dores de cabeça em jogos FPS.
Vamos ao que tentei e ao que funcionou.
Primeiras tentativas: Cloudflare e Tailscale
A primeira solução que me veio à cabeça foi expor os serviços pela Cloudflare, via Tunnel, ou pela Tailscale. Não cheguei a testar a Tailscale.
A Cloudflare funcionou perfeitamente bem: era rápida, robusta, e tinha um keep-alive excelente para negociar diante das mudanças bruscas do UDP. Mas tinha um problema — o mesmo compartilhado com a Tailscale (por isso nem tentei): pelas políticas dessas empresas, você não pode servir streaming. Se quisesse, teria que usar os servidores deles, ou seja, pagando. O risco é alto: podem te banir dos serviços sem maiores explicações.
Eu tenho diversos serviços rodando via Cloudflare e não podia correr esse risco. Migrar para o Tailscale Funnel era inviável pelo mesmo motivo da Cloudflare. E eu não queria manter uma rede fechada estilo WireGuard, em que só eu teria acesso: meus primos e parentes não são muito tech, e isso custaria tempo de configuração. Eu queria simplesmente mandar um domínio e eles acessarem.
O que fazer?
Pangolin: bom, mas só bom
Lembrei do Pangolin. Talvez, se eu pegasse uma VPS bem baratinha e rodasse o Pangolin nela, eu conseguisse "emular" os serviços oferecidos pelo Cloudflare Tunnel em nível semelhante.
A imagem do container do Pangolin seria perfeita: rodaria com Docker e já vinha com Traefik, Gerbil e CrowdSec. Era só subir, configurar os domínios, instalar o Newt nas máquinas locais e pronto. Eu estaria fazendo streaming daqui de casa, atrás de CGNAT e exposto. Meu problema deveria estar resolvido.
Deixei rodando por uns dois meses, mas a lentidão estava me irritando. Eu ainda não havia explorado os reais motivos, até que enfim não tive escolha. O serviço estava bom — mas só bom. E eu queria excelente.
Minha primeira ação foi fazer testes básicos: verificar rotas, DNS, MTU, etc. Interessante que, apesar de esse não ser o coração do problema, resolvi alguns outros problemas no caminho. Ou seja, tinha uma leve influência também.
Mas logs e testes mais precisos mostraram algo que eu já suspeitava: UDP e ping/keep-alive. O UDP reciclava de forma extremamente agressiva, em intervalos curtíssimos, e para streaming isso era o horror puro. Imagine tentar carregar vídeo, player, range request, WebSocket de chat... tudo isso precisa fluir bem.
Um novo problema que exigiria criatividade para resolver. A decisão foi parar de tentar fazer o túnel UDP se comportar bem em um CGNAT agressivo e trocar o miolo da arquitetura por um túnel TCP persistente. Mas como? Eu não sabia. Então deixei meio que em stand-by. Afinal, eu estava sem tempo para brincar com meus streamings, e eles já estavam de pé — mesmo que de forma inadequada.
E passaram-se algumas semanas.
O acaso: FRP
Eu estava na dashboard do Unraid e comecei a olhar os apps que tinham na loja. Então, por puro acaso, vi algo que me chamou atenção: FRP. Sinceramente, eu nunca tinha usado, e para mim não passava de mais um serviço de proxy qualquer. Dei uma olhada na imagem só por curiosidade — sabe quando você olha mas não vê (lê)? Eu nem estava pensando mais na exposição dos meus streamings, e algo me chamou atenção: o "F" no começo de FRP, que significa Fast.
Fiquei mais curioso. Por que ela seria diferente? Por que fast?
Estudando um pouco, a explicação foi simples.
O FRP (Fast Reverse Proxy) foi criado justamente para expor serviços locais que estão atrás de NAT/firewall, usando um servidor público como relay. A arquitetura é:
frps= servidor FRP no VPS com IP público.frpc= cliente FRP na máquina local, atrás do NAT/CGNAT.
Com isso, a máquina local abre uma conexão de saída para o VPS. O VPS passa a expor portas públicas (temporárias ou internas), que depois são usadas pelo Traefik como backends HTTP.
O Pangolin (Newt/Gerbil) usa uma arquitetura mais completa: Traefik + identidade + túneis WireGuard/Gerbil/Newt. É ótimo como "plataforma", mas adiciona mais peças móveis. A própria documentação do Pangolin descreve o Gerbil como gerenciador de túneis WireGuard e o Newt como cliente de borda.
O FRP foi feito exatamente para expor serviço local atrás de NAT/firewall usando um servidor público como relay, e suporta TCP, UDP, HTTP e HTTPS.
No meu caso, a vantagem era essa. As situações eram:
- FRP = conexão TCP persistente saindo da rede local → VPS público → Traefik.
- Pangolin = túnel/overlay mais sofisticado → mais dependente do comportamento do túnel.
A solução era melhor não porque o FRP é "superior" ao Pangolin em tudo, mas porque ele resolve o gargalo real: parar de brigar com UDP em um CGNAT ruim.
A arquitetura final
Usuário externo
↓ HTTPS
Traefik no VPS (Pangolin)
↓ HTTP interno para a porta do FRP
frps no VPS (Pangolin)
↓ túnel TCP persistente
frpc na máquina local
↓
Serviço local de mídia
Na VPS que já tinha o Pangolin, basicamente instalei e configurei o frps (servidor) junto com um token. Cada máquina que seria cliente recebeu o frpc (cliente) com o token do servidor.
A configuração era até simples: você vincula o IP/porta, coloca o token, valida e liga.
Mas havia uma pegadinha: foi necessário fazer algo um pouco diferente no Traefik que já tínhamos no servidor. Em vez de recriar os recursos pela UI do Pangolin, usei o File Provider dinâmico. O resultado foi espantoso — o ganho prático veio na hora.
Antes, o acesso via Newt/Pangolin sofria com TTFB alto e instabilidade causada pelo CGNAT. Depois da troca para FRP, os serviços passaram a responder imediatamente e com muita estabilidade.
Por que funcionou
A mudança funcionou porque o problema não era apenas "proxy lento". Era arquitetura.
O Cloudflare Tunnel era rápido, mas inadequado como solução principal para streaming self-hosted pesado dentro das políticas corretas. O Newt/Pangolin era elegante para expor serviços privados, mas o CGNAT agressivo estava prejudicando a estabilidade do caminho UDP. O FRP resolveu o ponto exato: criou um túnel TCP persistente entre as máquinas locais e o VPS público.
O Traefik continuou fazendo o que faz bem: receber HTTPS, aplicar regras por domínio e encaminhar para os backends internos. O FRP ficou com o transporte. Cada ferramenta no seu papel certo.
Em breve farei um pequeno tutorial de como isso foi configurado e como você pode fazer na sua rede.
Até mais.
Did this resonate?
Related documents
- 001
- 002
- 003
- 004
- 005