VPN WireGuard com pfSense + RestAPI

Introdução

Os peer são os clientes, eles se conectam na rede do servidor que no caso é o pfSense. Quando um peer se conecta na VPN, é criado uma interface dentro da máquina, vamos supor que a VPN tem como base a rede 192.168.0.0/24, quando um cliente se conectar ele pegará o IP 192.168.0.2/24, ela não pegará o IP com final .1 porque provavelmente o mesmo já está sendo utilizado pelo servidor (na maioria das vezes). Junto com essa rede é criado uma rota para ela, isso significa que qualquer tráfego em direção para a rede 192.168.0.0/24 será enviado para o gateway (que nesse caso e na maioria dos casos é o Firewall), resumindo, todo o tráfego da VPN vai em direção para o Firewall, como ele é o "mestre" da rede, ele sabe onde cada cliente (peer) está, ou seja, se o peer A quiser enviar requisição para o peer B, o peer A enviará requisição para o Firewall e o Firewall enviará para o peer B. Qualquer outro tráfego que não for em direção para a rede 192.168.0.0/24 será enviado para a internet nesse caso.


Porque não foi utilizado OpenVPN

  1. O OpenVPN não é muito escalável;

  2. WireGuard ganha em segurança, desempenho e simplicidade.


Instalando os pacotes necessários

Para instalar os pacotes necessários vá em "System", depois em "Package Manager" e por fim vá para "Available Packages", após isso pesquise WireGuard e instale o pacote, depois de instalar pesquise por RestAPI e instale também.


Como configurar

Após efetuar o setup do pfSense, vamos em "Status" e logo após em "WireGuard"

Essa será a seção principal onde iremos mexer, aqui iremos configurar o WireGuard (opções relacionadas a protocolo), Servidor e os peers


Configurando o protocolo WireGuard

Temos duas seções aqui, a "General Settings" e a "User Interface Settings", a primeira é referente ao protocolo a segunda é referente de como as informações aparecem na tela.

General Settings

  1. Primeiro precisamos habilitar o WireGuard, isso habilita as funções necessárias do WireGuard para funcionar no pfSense;

  2. Keep Configuration, essa opção basicamente vai salvar as configurações no sistema;

  3. Endpoint Hostname Resolve Interval, essa opção diz ao pfSense de quanto em quantos segundos ele irá tentar alcançar o peer, caso ele não consiga alcançar ele irá remover da lista de peer ativos, e marcará como peer inativo;

  4. Interface Group Membership, podemos ter vários túneis WireGuard, ou seja, várias VPNs, podemos agrupar esses túneis e criar um grupo, por exemplo, podemos ter 1 túnel para RH, outro túnel para o setor Financeiro, podemos agrupar os dois num grupo chamado WG_EMPRESA_A, após isso podemos selecionar esse grupo nessa opção, com isso, as regras que eu aplicar no WG_EMPRESA_A, vai ser aplicado para os dois túneis.

User Interface Settings

  1. Hide Secrets, essa opção é usada quando geramos um par de chaves (veremos mais pra frente) pela interface gráfica, se essa opção estiver habilitada ao ser gerada, ela irá "esconder" o valor, não iremos conseguir ver ao menos que usemos o inspecionar elemento;

  2. Hide Peers, essa opção ao ser habilitada desabilita a visualização dos peers conectados a VPN.

Resumindo: Nessa parte habilitamos o protocolo WireGuard na VPN e desabilitamos o Hide Secrets (pois precisaremos ver com facilidade o par de chaves). As demais opções podem ser mantidas com o valor Default


Configurando o servidor

Para configurar um servidor (ele será o mestre de todos os peers que estão conectados a ele), precisamos acessar a aba de "Tunnels".

Aqui temos 3 seções: Tunnel Configuration, Interface Configuration e Peer Configuration

Tunnel Configuration

Nessa parte será configurado as opções do túnel.

  1. Primeiro precisamos habilitar o túnel para ele ser usado;

  2. Description, essa é apenas a descrição

  3. Listen Port, essa opção qual porta o pfSense usará para abrir, por exemplo se digitarmos a porta 51821, essa porta será listada como listener no pfSense, os peers tentarão se conectar nessa porta para fechar a conexão

  4. Interface Keys, essa será uma parte extensa e muito importante, basicamente a relação de confiança do WireGuard não é baseada com usuário/senha ou certificado (como é feito no OpenVPN, no OpenVPN a autenticação é feita com uma das duas opções acima), no WireGuard a confiança é feita com Keys (ou se preferir pode chamar de token), enfim, o Servidor tem duas chaves, uma chave privada e uma chave privada (criptografia assimétrica), a chave pública foi derivada da chave privada, ou seja, foi o Servidor quem gerou essa chave, ou seja, o peer irá pegar essa chave pública (passaremos essa chave para o arquivo de configuração usado para logar na VPN) e confirmar que essa chave foi gerada pelo Servidor, com isso ele comprova que o Servidor é quem ele diz que é, o cliente também terá um par de chaves mas veremos isso mais para frente;

Interface Configuration

  1. Assignment, essa opção é usada para abrir um túnel a uma interface específica;

  2. Firewall Rules, caso tenhamos um grupo com túneis e adicionemos esse Servidor no grupo, as regras aplicadas ao grupo serão aplicada a esse novo Servidor;

  3. Interface Address, essa configuração define a rede a qual o túnel vai ser criado;

Peer Configuration

Quando novos peers forem conectando na VPN, eles irão aparecer nessa seção, aqui você poderá remover o peer da VPN, editar ou bloquear um peer.

Conclusão

Após preencher as informações o túnel será criado, ou seja, o pfSense está pronto para receber novas conexões de novos peers, a VPN está pronta.


Configurando o peer (cliente)

Para configurar um peer, precisamos acessar a aba de "Peers".

Aqui temos duas seções: Peer Configuration, Address Configuration.

Peer Configuration

  1. Primeiro habilitamos o peer;

  2. Tunnel, aqui selecionamos o Servidor que criamos na etapa anterior;

  3. Description, apenas a descrição para identificar o peer, sugiro colocar a identificação do peer;

  4. Dynamic Endpoint, essa opção é usada para definir qual será o IP e a porta que o peer usará para se conectar no Servidor, isso pode ser útil para aumentar a segurança, esse peer só aceitará conexões vindas do HOST:PORTA definida caso a opção Dynamic Endpoint for desabilitado.

  1. Caso a opção esteja marcada, qualquer host com qualquer porta de origem poderá tentar se conectar como esse peer;

  2. Keep Alive, essa opção é usada para verificar de quanto em quantos segundos o peer deverá ser verificado para saber se ele está on-line ou não;

  3. Public Key, essa chave pegaremos via linha de comando no peer, basicamente o peer precisará criar um par de chaves, uma pública e uma privada, a chave pública será colocada nessa opção, pois assim o peer vai ter a chave privada, com isso o peer consegue comprovar para o Servidor que a chave pública é dele e ele é quem ele diz realmente ser.

  4. Pre-shared Key (Opcional), essa é uma outra opção para autenticar, porém essa autentica ambos os lados, por exemplo se gerarmos uma chave aqui, precisaremos adicionar essa chave no arquivo de configuração que o peer usará para logar, assim o Servidor e o Peer se autenticarão.

Address Configuration

  1. Allowed IPs, essa configuração é muito importante, basicamente no WireGuard, no arquivo de configuração dele podemos definir qual o endereço IP que o peer vai pegar ao ser conectado na rede, porém sem uma etapa a mais de segurança o peer pode aplicar ataques como hijacking de IP ou ARP, Gateway Spoofing e outras coisas. Essa opção basicamente.

Conclusão

Após preencher as informações e salvar, passamos para a parte de configurar os clientes para que eles se autentiquem, mas antes de configurarmos o cliente vamos ver a parte de Status.


Status

Podemos monitorar monitorar o status do Servidor e dos peers na aba "Status".


Configurar o cliente

Agora que temos a infraestrutura pronta no pfSense, vamos configurar o cliente no peer.

~# apt install wireguard
~# wg genkey | tee privatekey | wg pubkey > publickey

O primeiro comando instala o WireGuard na máquina, já o segundo gera a chave publica e a chave privada. Após ter o conjunto de chaves vamos criar um arquivo dentro do diretório /etc/wireguard/, o nome do arquivo dependerá do nome da interface que você quer criar quando o peer logar na VPN, ou seja se você criar um arquivo chamado bananal.conf quando o usuário se conectar na VPN será criado uma interface chamada bananal. O arquivo deve conter o seguinte conteúdo:

[Interface]
PrivateKey = <CHAVE PRIVADA OBTIDA COM O COMANDO ACIMA, ESSA CHAVE SERÁ USADA PARA O SERVIDOR VALIDAR O CLIENTE>
Address = X.X.X.Y/BARRAMENTO <NO Y COLOCAMOS O IP DA MÁQUINA, O MESMO IP DEVERÁ SER DEFINIDO NA PARTE DE ALLOWED IP NAS CONFIGURAÇÕES DO PEER>

[Peer]
PublicKey = KEY <A CHAVE PÚBLICA OBTIDA QUANDO CONFIGURAMOS O Servidor, ESSA CHAVE SERÁ USADA PARA VALIDAR O SERVIDOR>
Endpoint = X.X.X.X:PORT <IP E PORTA do pfSense>
AllowedIPs = X.X.X.X/BARRAMENTO <AS REDES QUE SERÃO ACESSÍVEIS ATRAVÉS DA VPN>

Com o arquivo pronto rodamos o seguinte comando:

~# wg up <NOME DO ARQUIVO.CONF>

Após isso podemos validar se o peer está conectado na aba de "Status" do pfSense.


API

Para podermos acessar a API primeiro precisamos habilita-lá.

Primeiro habilitamos o RestAPI, após isso podemos selecionar por qual interface a API será acessível, por exemplo se selecionarmos a interface "Localhost' na opção "Allowed Interfaces", a API só será acessível internamente. Após essas configurações selecionamos o meio de autenticação da API, no nosso caso a opção JWT tornará o uso da API mais simples. Também podemos definir Access List de acesso na aba "Access List", mas isso para nós não é necessário. Após definir as opções marcadas em vermelho podemos deixar as outras opções com o valor padrão.

Após isso a API ficará acessível.

Como consultar a API

A API é vasta, vamos exemplificar apenas como adicionar uma nova configuração de Peer:

curl -k -X POST https://X.X.X.X/api/v2/vpn/wireguard/peer \ 
-H "Authorization: Bearer <TOKEN>" \ 
-H "Content-Type: application/json" 
\ -d '{   
	"enabled": true,   
	"tun": "tun_wgX",   
	"endpoint": null,   
	"port": "51820",   
	"descr": "WkX",   
	"persistentkeepalive": 65535,   
	"publickey": "Qi2M836Bx1Crjnacb4OQrHyM7vl4BA9RtmjDzff5FBM=",   
	"allowedips": [     
		{      
			 "address": "X.X.X.X",       
			 "mask": 32     
		 }   
	 ] 
	 }`

As opções são basicamente as mesmas que quando configuramos via GUI. Para obter o token JWT use essa API:

curl -k -u 'USER:PASSWORD' -XPOST https://X.X.X.X/api/v2/auth/jwt

Last updated