Sem IP público? Sem problema
As aventuras de um computeiro merreca e sua Raspberry Pi dentro de casa
Contexto
Por volta de julho de 2019 lá estava eu em casa, fazendo altos nadas no computador quando olhei pra minha estante e vi a Raspberry Pi Zero que tinha comprado um ano antes e que até então só servia mesmo era de peso de papel (nem isso direito, porque ela pesa 9g).
A ideia era simples: hospedar meu site pessoal nela mas, como veremos, o buraco é bem mais embaixo.
Aviso: A internet é um lugar perigoso e hospedar coisas, seja na nuvem ou na sua rasp em casa, tem seus riscos. Tenha cuidado para não colocar dados sensíveis em sistemas caseiros, blablabla…
IPs Publicamente Roteáveis
Com essa ideia na cabeça eu comecei. Liguei a rasp, baixei o Raspbian (uma versão do Debian para Raspberry Pi) e instalei nela. Claro que nessa época eu pensei que precisava ter um teclado e um monitor pra completar a instalação — não precisa.
Mas apesar de ter demorado um pouco mais do que o esperado (uma semana rsrs) pra instalar o Raspbian, consegui. Estava lá minha raspberry linda e maravilhosa com SSH configurado e tudo.
Daqui pra frente é facinho: configura um servidor web e serve as páginas!
— Gabriel , prestes a quebrar a cara
E foi isso mesmo que eu fiz. Configurei um servidor web (se não me engano era Nginx) e coloquei um arquivo HTML para ela servir:
<html>
<body>
Hello world!
</body>
</html>
Agora é só abrir o browser e digitar o endere-
— Gabriel , quebrando a cara
Mas calma, que endereço a gente coloca no browser? Olhando o IP da rasp eu achei 192.168.0.19
. Bom, de dentro de casa funcionaria, porque esse é um IP privado, ou, como eu prefiro, não é publicamente roteável.
IPs publicamente roteáveis, ou só roteáveis, são aqueles para os quais é possível encontrar uma rota independente de onde você esteja na internet. São os tais dos IPs públicos que você só consegue comprando e meio que já acabaram e blablabla, mas isso é assunto para outro post.
Mas calma. Então se meu IP não é publicamente roteável, como diabos eu consigo receber algum conteúdo da internet?
— Gabriel, mais confuso do que nunca
NAT: Network Address Translation
A resposta aqui é que você está atrás de uma NAT. Já notou quando você vai pra lá e pra cá, muda de endereço, muda de cidade, estado e até país, e seu IP continua parecido com 192.168.0.19
? Isso é NAT, uma estratégia para economizar endereços IP.
Imagine que o roteador da sua casa é um prédio e o seu computador é um apartamento desse prédio. O número do apartamento é o seu IP privado, aquele 192.168.0.19
, e o CEP do prédio é o IP do seu roteador. Quando alguém vai mandar uma carta para você ela coloca como destino o CEP e o número do apartamento. Se no destinatário da carta tivesse só o número do seu apartamento (sem o CEP), o carteiro nunca ia achar o lugar, porque não tem como ele saber de qual prédio você está falando.
NAT é útil porque você economiza endereços IP públicos. Mesmo que tenha 20 pessoas na sua casa, vocês só vão “gastar” um IP público do roteador. Na nossa analogia, você não precisa ter um CEP para cada apartamento, e com isso economizamos CEPs.
Mas então os pacotes vêm com dois IPs de destino? O do roteador e o seu IP privado?
— Você, mais confuso que surdo em bingo
Não exatamente. Apesar de isso poder ser uma solução válida para o problema, em geral NAT é implementado usando tradução de IPs locais para portas do roteador (Port-based NAT): o roteador tem várias portas, o que a NAT faz nesse caso é basicamente criar regras do tipo “se chegar um pacote na porta 29534, redirecione para o IP do Gabriel, e se chegar um pacote na porta 3487 redirecione para o IP da Alice”.
Port Forwarding
Então eu tinha um IP público: o do roteador! Isso significa que qualquer pessoa era capaz de chegar até o meu roteador, o problema era da porta pra dentro: configurar o roteador para redirecionar todas as requisições do site para a Raspberry.
Mas como fazer isso?
— Gabriel, já não mais tão desapontado
A palavra-chave aqui é Port Forwarding, ou redirecionamento de portas. Lembra que eu disse que a NAT tem umas regras de “se chegar na porta tal, redirecione pro IP interno tal”? O que vamos fazer é basicamente configurar uma regra dessas manualmente:
“se chegar um pacote na porta 80, redirecione para o IP da rasp”
A grande maioria dos roteadores hoje te permite fazer isso através da interface web, a mesma que você usa pra mudar a senha da Wi-Fi.
Obs: Você provavelmente notou que eu passei meio por cima do assunto portas. Isso porque se eu fosse falar sobre isso esse post ia ficar 3x mais longo, e não é tããão importante assim no momento, mas eu recomendo muito você aprender sobre em algum momento. Para nós, a porta 80 é importante porque é por onde chegam as requisições HTTP (requisições de websites).
DHCP: Dynamic Host Configuration Protocol
Tá bom vai, eu passei lotado por mais um detalhe além da parada das portas. Mas eu prometo que é só mais um. Lembra da regrinha que configuramos no roteador?
“se chegar um pacote na porta 80, redirecione para o IP da rasp”
O problema aqui é: qual é o IP interno da rasp? Ou melhor: os IPs internos são sempre os mesmos? Resposta: o buraco é mais embaixo.
O DHCP é o protocolo que permite distribuir endereços IP dinamicamente. Imagine que você venha na minha casa e se conecte na minha rede. Na grande maioria das vezes você recebe um IP do servidor DHCP que roda no roteador da casa. Isso serve para que IPs possam ser “reciclados”, ou seja, quando você for embora da minha casa, o servidor coleta de volta aquele IP que você estava usando para que outra pessoa no futuro possa usá-lo.
Mas isso é um problema para nós porque o port forwarding não adivinha o IP da rasp, então o que precisamos fazer é configurar o servidor DHCP, bem parecido com a configuração de port forwarding, para reservar um endereço IP para a rasp. Assim, toda a vez que a rasp ligar e se conectar na rede de casa o servidor DHCP vai dar o mesmo IP para ela, e o port forwarding vai funcionar.
IP público vs. IP estático
Já que tocamos no assunto de IPs estáticos e dinâmicos, será que IPs públicos são todos estáticos? Resposta: NÃO!
Do mesmo jeito que IPs privados em geral são administrados por um servidor DHCP, IPs públicos também podem ser. No meu caso o meu provedor de internet tinha um servidor DHCP para toda a região da cidade onde eu morava, e cada roteador recebia seu IP público e dinâmico. Isso me custou mais umas duas semanas pra descobrir…
Ué, mas qual o problema de ser dinâmico? Não basta ser público pra podermos acessar?
— Você, mais confuso que o Gabriel do começo do post
Essa é fácil. Imagine que para acessar o meu site você digita o IP lá no browser: 123.12.9.34
. Agora imagina que na semana seguinte eu solto um novo post e você animadasso pra ler vai lá e puf, o site tá em outro IP. Um saco né? É esse o problema :P
Mas agora, diferente do que aconteceu na minha casa, eu não tinha acesso ao servidor DHCP do provedor para forçar o IP do meu roteador a ser estático, então, depois de mais uma semana quebrando a cabeça eu encontrei uma solução: Dynamic DNS.
Oh meu jesus, mais um termo?
— Você, já não aguentando mais o aluguel que tá esse post
Prometo que estamos no fim.
Dyn DNS
Lembra do nosso exemplo hipotético em que você acessava meu site usando o IP? Agora fala sério, quando você acessa um site, você usa o IP do site? Não. Em geral os sites tem nomes tipo google.com
e ganesh.icmc.usp.br
. Esses nomes chamam domínios: nomes mais amigáveis ao usuário que mapeiam para endereços IP e servem pra você não ter que ficar lembrando os endereços de cada site e serviço que você quer usar, até porque esses IPs podem mudar.
O Domain Name System, esse sistema que converte domínios para IPs, é muito útil para a gente agora. Se o nosso site tivesse um domínio tipo gmcruz.me, poderíamos só mudar o IP que mapeia para esse nome e pronto. Para o usuário final nada mudou.
O Dynamic DNS é o mecanismo que permite alterar registros DNS conforme o IP muda. Por exemplo, podemos fazer um programa que checa se o IP do roteador mudou e, se for o caso, atualiza o registro DNS com o novo IP. Felizmente pra gente isso já está feito e existem vários clientes de DNS dinâmico por aí. O que eu faço a seguir é meio mecânico, então vou deixar só uma lista dos passos com links:
- Pegar um domínio: comprar ou pegar de graça usando Github Developer Pack ou domínios grátis.
- Delegar o gerenciamento do domínio para a CloudFlare (não é obrigatório, é só como eu fiz)
- Configurar o domínio para Dyn DNS na CloudFlare
- Configurar o script para rodar na rasp que atualiza o DNS conforme o IP do roteador muda. Eu usei o ddclient e configurei com a imensa ajuda desse tutorial.
Observações
Depois de umas semanas com tudo funcionando bem eu percebi que não queria expor um site usando a minha raspberry, porque não é muito confiável em termos de segurança, rede, energia, capacidade de processamento, etc. Então eu logo fechei a porta 80 e desliguei o servidor web.
Nossa mano você me fez ler até aqui pra falar que nem usou o rolê?
— Você, puto da vida
Não, não é isso. Eu gostava da ideia de poder mexer na minha rasp de fora de casa, mas com o site isso não era possível, e ela nem fazía um bom trabalho em termos de ser um servidor web. Então o que eu fiz foi abrir a porta 22 em vez da 80, e configurar um servidor SSH para que eu conseguisse acessar e realmente mexer e fazer coisas nela. Meu site hoje é hospedado no Github Pages, que é gratuito e confiável.
Até a próxima :)