Muitas vezes para evitar problemas de rotas, disponibilidade de conteúdo ou se conectar em uma intranet se faz necessário o uso de VPNs. Normalmente isso é feito a partir de soluções proprietárias, entretanto também é possível criar uma VPN manualmente, utilizando uma máquina que esteja exposta na internet. Isso é o que eu tentarei mostrar nesse artigo.
Atenção 0
Por mais que seja um sistema de infraestrutura caseiro é bastante difícil fazer com o que o custo do sistema seja zero, devido ao requisito de se ter exposição na internet. A maneira mais fácil de se fazer isso é utilizando soluções de cloud que terão um custo atrelado.
Atenção 1
Não recomendo a utilização desse tipo de solução em operações do tipo Black Ops, devido à relação numismática que existe entre a implementação e o implementador.
O que é uma VPN
Bom, afinal de contas o que seria uma VPN? Uma VPN é uma estrutura de rede utilizada primariamente para ligar redes à redes. Em situações comuns serve essencialmente pra acessar serviços que não estão expostos para fora de uma intranet.
Óbvio que esse não é único uso que se pode fazer de uma VPN, uma vez que quando ocorre a saída de um pacote de uma das estremidades da comunicação o endereçamento do pacote muda (mascaramento), fazendo com que pareça que o endereço de origem do pacote é o do gateway da rede de saída.
O leitor mais atento pode se perguntar qual a diferença entre uma VPN e outras tecnologias comuns à língua de redes tais como NAT (Network Address Translation) e Proxy. O que ocorre é que tanto a tecnologia de NAT como Proxy tratam-se de camadas transparentes de indireção de fluxo, ou seja qualquer adversário que desejar realizar ataques visando a identificação de tráfego, tais como spoofing ou sniffing, o que não pode ocorrer de maneira tradicional quando se utiliza VPNs visto que todo o tráfego é posto sob a égide de um esquema criptográfico. Dessa maneira uma VPN teria um funcionamento mais parecido com o seguinte:
Afim de criar uma VPN caseira vou utilizar um servidor que tenha um IP fixo que eu possa acessá-lo a partir da web. Para tanto vou utilizar um servidor virtual EC2 da AWS, e uma máquina virtual sob NAT na minha rede local, e conectá-las a partir do Wireguard.
O que é o Wireguard?
O Wireguard é um conjunto de utilitários de VPN que pode ser instalado na maioria das distribuições Linux, operando na camada 3 do modelo OSI (camada de rede), tem implementações tanto no kernel space, como no user space.
Porque o Wireguard?
Existem outros utilitários que servem aos mesmos propósitos do Wireguard, tal como o OpenVPN, e por mais que o Wireguard não seja considerado "production-ready" eu considero mais simples de ser configurado e mais fácil de ser utilizado em operações rápidas.
Como Funciona
Na sequência vamos ter duas máquinas cliente e servidor, entretanto também usarei os termos peer e peer de forwarding.
A sequência de passos (em alto nível)que deve ser seguida afim de estabelecer um túnel de VPN entre duas máquinas é a seguinte:
- Criar as chaves (pública e privada) tanto no cliente como no servidor
- Adicionar as configurações substituindo os locais de chave pública e privada
- Iniciar o serviço no servidor, subindo uma nova interface de rede
- Iniciar o serviço no cliente, subindo uma nova interface de rede e fechando o túnel
Enough talk, show me the Cipher
Bom, a primeira coisa que deve ser feito é verificar se o servidor tem as configurações requeridas para se fazer o mascaramento de pacotes. No arquivo /etc/sysctl.conf verificar se existe a seguinte definição:
net.ipv4.ip_forward = 1
E em seguida executar o recarregamento dos parâmetros de kernel:
sysctl -p
Então deve-se executar tanto no peer como no peer de forwading os seguintes comandos para gerar as chaves pública e privada:
umask 077 # A permissão de acesso deve ser restrita apenas ao root
wg genkey > privatekey # gera chave privada
wg pubkey < privatekey > publickey # gera chave pública
# move as duas chaves para o diretório do wireguard
# para facilitar a configuração
mv privatekey publickey /etc/wireguard
Feito isso basta criar os dois arquivos de configuração (recomendo utilizar o padrão nome_interface_a_ser_criada.conf), começando pelo arquivo de configuração do servidor:
# cat /etc/wireguard/wg0.conf
# Nessa seção são definidas todas as configurações da interface de rede
[Interface]
Address = 10.10.42.1/24
SaveConfig = true
PostUp = iptables -A FORWARD -i %i -j ACCEPT; iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
PostDown = iptables -D FORWARD -i %i -j ACCEPT; iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE
ListenPort = 51820
# Chave privada do servidor
PrivateKey = PRIVATE_KEY_SERVER
# Nas seções de peer (podendo ser mais de uma)
# são feitas as configurações do cliente
[Peer]
# Chave pública do cliente
PublicKey = PUBLIC_KEY_CLIENTE
# Lista de IPs que o cliente pode receber
AllowedIPs = 10.10.42.2/32
Foram muitas informações inseridas no arquivo anterior mas eu gostaria de dar um destaque especial em algumas variáveis:
- Address: Endereço da interface de rede que subirá (no caso a wg0)para fazer o mascaramento de IP
- PostUp, PostDown: são duas seções que executam comandos antes e depois que a interface de rede é criada e destruída respectivamente, podem ser muito úteis para configurar regras de filtro de pacotes como no exemplo acima
- ListenPort: Porta UDP que será aberta para o estabelecimento de túneis de VPN
- AllowedIPs: Lista de IPs que o cliente pode atribuir a si mesmo estabelecendo a conexão.
Já no cliente a configuração, sim é preciso fazer uma configuração para cada um dos clientes, é bem mais simples:
[Interface]
# Chave pública do cliente
PrivateKey = CLIENT_PRIVATE_KEY
Address = 10.10.42.2/24
[Peer]
PublicKey = YOUR_SERVER_PUBLIC_KEY
AllowedIPs = 0.0.0.0/0
Endpoint = SERVER_PUBLIC_IP:51820
PersistentKeepalive = 20
No cliente a diferença mais notável é as seções de Endpoint e PersistentKeepalive:
- Endpoint: Indica em qual IP ou URI seguido da porta UDP o peer de forwarding deve ser acessado, a maneira mais simples de se configurar essa seção é utilizando um IP fixo
- PersistentKeepalive: Indica o intervalo de tempo em que um pacote de KeepAlive será enviado para servidor (no caso do exemplo 20 segundos), necessário caso o cliente tenha o seu IP mascarado por um NAT
Por fim, basta subir as duas interfaces de rede tanto no cliente como no servidor com o comando:
systemctl start wg-quick@nome_da_interface
Et voilà, a interface foi criada e todo o tráfego do cliente está sendo mascarado pelo servidor. Para testar o funcionamento basta executar uma resolução de IP e verificar que o IP de saída é o mesmo IP público do servidor:
$ curl ifconfig.me
PUBLIC_SERVER_IP
Show me the money
Vale a pena pensar qual o custo de se fazer esse tipo de coisa em uma cloud. Utilizando um servidor EC2 nano temos um custo/hora de 0.0058 dólares, ou seja o custo/mês é de 4.176, não é caro mas se for deixado ligado 24 horas por dia pode ser comparável a soluções de VPN que existem no mercado.
A grande vantagem de se fazer esse tipo de manipulação é que não existe necessidade de se deixar obrigatoriamente 24 horas e desse jeito é possível chegar a valores bem irrisórios ao longo de um mês.
Everybody wants to rule The World
Em resumo, criar uma VPN caseira pode se mostrar uma boa alternativa à soluções proprietárias, especialmente se o usuário gostaria de controlar os seus custos. Como um amigo meu gostava de falar:
"O que as pessoas procuram é facilidade, mas o que elas realmente querem é controle."
Criar uma VPN caseira é uma forma de se atingir esse controle.
Referências
What is VPN
Difference between VPN, NAT and proxy
Wireguard Home
Ubuntu Wiki Wireguard
Debian Wiki Wireguard
Manual do wg-quick
Top comments (0)