Minha rede em casa tem vários componentes interessantes. Tenho um NAS que mantém vários arquivos pessoais, tenho 3 Raspberry Pis que fazem diversas coisas diferentes (um Raspberry Pi 1, um 2, e outro do mais recente, o 3 – fui comprando conforme saiam). Tenho um Receiver da Yamaha que tem um browser embutido. Entre diversos outros devices. Mas, toda vez que estava fora de casa, não conseguia acessar nada. Resolvi que tinha que montar uma VPN.
O problema de montar uma VPN é que você precisa de um servidor. E servidores são caros, eles tem que ficar ligados o tempo todo, e qualquer máquina vai demandar muita energia. A não ser que ela rode ARM e esteja num chip super enxuto, que é exatamente o que um Rasperry Pi faz. E eu já tenho 3 ligados. Bora usar um deles.
Fui pesquisar o que utilizar na VPN e descobri que o OpenVpn é um software livre (GPL) e interessante. Mas não é simples de instalar. Procurei os manuais de instalação e outros artigos, e ele tem diversas dependências. Colocar ele em um dos meus Pis seria um problema, não queria ter que lidar com os diversos problemas de dependências entre os diversos componentes que já rodam neles, e não quero aumentar a superfície de ataque. Felizmente, um desses Pis já está rodando Docker, porque no passado eu já quis rodar uma app em Python, e já tinha tido o mesmo pensamento de manter tudo mais simples, seguro e fácil de instalar e recuperar. Tudo é mais fácil com Docker. Estou usando a implementação do pessoal da Hypriot pra Docker, que funciona super bem. Eu só precisava agora achar uma forma de rodar o OpenVpn.
Achei o repo do Kyle Manna (kylemanna/docker-openvpn) que encapsula o OpenVpn em um contêiner Docker. Você acha a imagem do que ele construiu no Docker Hub em kylemanna/openvpn. É um trabalho muito bem feito, e poderia ser a base do que eu queria fazer. Forkei o projeto e fiz algumas alterações, e tudo simplesmente funcinou.
A principal alteração foi substituir a base da imagem. Ele tornou isso muito fácil, já que usa Alpine Linux (um Linux muito pequeno), e o pessoal do Hypriot também tem uma imagem de Alpine pra rodar em ARM no Docker Hub chamada hypriot/rpi-alpine-scratch. Você vê o commit onde troco a imagem de base no Github. Além disso, eu fiz outras pequenas alterações. Por exemplo, não exigindo uma senha na criação das chaves do servidor, acrescentando no Readme o teste que fiz num cliente de Windows, e removendo os testes do Travis, que não suporta ARM. Você pode ver todas elas no compare do Github aqui. A maior parte das instruções está no Readme do projeto. O resultado foi parar no Docker Hub, em giggio/openvpn-arm.
Aqui você vê ele rodando no meu Pi (clique para ampliar):
O resultado foi muito satisfatório. Encaminhei a porta 1194 do meu firewall para o Pi, e tudo simplesmente funcionou. O meu firewall, pra ajudar, suporta um DNS dinâmico, então consigo achar a vpn usando um nome, em vez de IP, que muda toda hora e é impossível de lembrar. Pra configurar tudo, bastou seguir as instruções que o próprio Kyle já tinha criado no Readme do projeto.
O OpenVpn tem clientes para Windows, Linux e Mac, e também pra Android. Testei no Windows e no Android, e tudo rodou perfeitamente. Consigo acessar todos os serviços que tenho em casa.
Quem disse que montar uma VPN é difícil? Com Docker, não é.
Giovanni Bassi
Arquiteto e desenvolvedor, agilista, escalador, provocador. É fundador e CSA da Lambda3. Programa porque gosta. Acredita que pessoas autogerenciadas funcionam melhor e por acreditar que heterarquia é mais eficiente que hierarquia. Foi reconhecido Microsoft MVP há mais de dez anos, dos mais de vinte que atua no mercado. Já palestrou sobre .NET, Rust, microsserviços, JavaScript, TypeScript, Ruby, Node.js, Frontend e Backend, Agile, etc, no Brasil, e no exterior. Liderou grupos de usuários em assuntos como arquitetura de software, Docker, e .NET.