DEV Community

Lucas Cruz dos Reis
Lucas Cruz dos Reis

Posted on

Como criar VPNs caseiras

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.
Tentativa de esquematizar uma VPN

Ó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:

Esquemático de funcionamento de VPN

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:

  1. Criar as chaves (pública e privada) tanto no cliente como no servidor
  2. Adicionar as configurações substituindo os locais de chave pública e privada
  3. Iniciar o serviço no servidor, subindo uma nova interface de rede
  4. 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
Enter fullscreen mode Exit fullscreen mode

E em seguida executar o recarregamento dos parâmetros de kernel:

sysctl -p
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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)