WireGuard no Ubuntu Server: VPN ponto a ponto passo a passo
WireGuard substitui o IPSec e o OpenVPN em cenários ponto a ponto com uma vantagem simples: o código-fonte do módulo tem cerca de 4.000 linhas, contra dezenas de milhares do IPSec, e roda dentro do kernel Linux desde a versão 5.6. Menos código auditável significa menos superfície de ataque e handshake medido em milissegundos, não segundos.
Por que trocar IPSec ou OpenVPN por WireGuard
IPSec exige negociar phase 1 e phase 2, escolher proposals de criptografia compatíveis entre os dois lados e lidar com NAT-T quando há tradução de endereço no caminho — um túnel site-to-site em FortiGate ou pfSense facilmente passa de 40 linhas de configuração só na parte de segurança. OpenVPN roda em espaço de usuário, depende de TLS e de uma CA própria, e paga o preço de desempenho por isso.
WireGuard usa um único par de chaves Curve25519 por peer, criptografia ChaCha20-Poly1305 fixa (sem negociação de cifras) e um arquivo de configuração que cabe em menos de 20 linhas. Roda em espaço de kernel, o que reduz troca de contexto e explica os ganhos de throughput relatados em comparações com IPSec e OpenVPN em hardware equivalente. A troca não é só estética: menos parâmetros para configurar errado é menos motivo de troubleshooting às 2h da manhã.
Pré-requisitos
Um servidor Ubuntu Server 22.04, 24.04 ou 26.04 LTS com IP público ou alcançável pela rede do cliente, acesso sudo, e uma máquina cliente Linux para o par da ponta. Os comandos abaixo usam 10.10.0.0/24 como sub-rede do túnel e a porta UDP 51820, padrão do WireGuard — troque se já usar essa faixa em outro lugar.
Configurando o servidor
1. Instale o WireGuard
sudo apt update && sudo apt install -y wireguard
O pacote inclui as ferramentas wg e wg-quick. Em kernels acima de 5.6 (padrão desde o Ubuntu 20.04) o módulo já vem embutido; não é preciso compilar nada à parte.
2. Gere o par de chaves do servidor
cd /etc/wireguard umask 077 wg genkey | tee server_private.key | wg pubkey > server_public.key
O umask 077 garante que a chave privada nasça com permissão 600 — sem ele, qualquer usuário local consegue ler o arquivo e assumir a identidade do servidor no túnel.
3. Crie o arquivo de interface (wg0.conf)
sudo nano /etc/wireguard/wg0.conf
[Interface] PrivateKey = <conteúdo de server_private.key> Address = 10.10.0.1/24 ListenPort = 51820 SaveConfig = false PostUp = iptables -A FORWARD -i wg0 -j ACCEPT; iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE PostDown = iptables -D FORWARD -i wg0 -j ACCEPT; iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE
Confirme o nome da interface de saída com ip route get 1.1.1.1 antes de colar — se não for eth0, ajuste as duas linhas de PostUp/PostDown. Essas regras fazem NAT (masquerade) do tráfego que sai do túnel pela interface pública; sem elas o cliente conecta mas não navega, porque o pacote sai do servidor com IP de origem 10.10.0.x, que não é roteável na internet.
4. Habilite o encaminhamento de pacotes IPv4
echo 'net.ipv4.ip_forward=1' | sudo tee -a /etc/sysctl.conf sudo sysctl -p
Por padrão o kernel Linux não repassa pacotes entre interfaces — ele só processa tráfego destinado a si mesmo. Sem essa linha, o servidor recebe os pacotes do cliente e os descarta em vez de encaminhá-los para a internet.
5. Libere a porta no firewall
sudo ufw allow 51820/udp sudo ufw allow OpenSSH sudo ufw enable
WireGuard usa UDP, não TCP: é um protocolo sem estado de conexão, então dispensa o handshake em três vias e evita head-of-line blocking quando um pacote se perde. Se o servidor estiver em nuvem (AWS, GCP, Hetzner, Oracle Cloud), libere a mesma porta UDP também no security group ou firewall da plataforma — o ufw sozinho não é suficiente nesses provedores.
6. Suba a interface e habilite no boot
sudo wg-quick up wg0 sudo systemctl enable wg-quick@wg0
7. Confirme que a interface está ativa
sudo wg show
Sem peers configurados ainda, o comando mostra apenas a chave pública e a porta de escuta do servidor.
Configurando o cliente
8. Gere o par de chaves no cliente
wg genkey | tee client_private.key | wg pubkey > client_public.key
9. Crie o wg0.conf do cliente
[Interface] PrivateKey = <conteúdo de client_private.key> Address = 10.10.0.2/24 DNS = 1.1.1.1 [Peer] PublicKey = <conteúdo de server_public.key> Endpoint = SEU_IP_PUBLICO:51820 AllowedIPs = 0.0.0.0/0 PersistentKeepalive = 25
AllowedIPs = 0.0.0.0/0 manda todo o tráfego do cliente pelo túnel (full tunnel) — para rotear só a rede interna, troque por algo como 10.10.0.0/24, 192.168.1.0/24. O PersistentKeepalive é obrigatório quando o cliente está atrás de NAT ou CGNAT: sem pacotes periódicos, o mapeamento de porta no roteador expira e o servidor não consegue mais iniciar contato quando precisar.
10. Adicione o peer no servidor
Edite novamente /etc/wireguard/wg0.conf no servidor e acrescente ao final:
[Peer] PublicKey = <conteúdo de client_public.key> AllowedIPs = 10.10.0.2/32
Aplique a mudança sem derrubar o túnel existente:
sudo wg syncconf wg0 <(wg-quick strip wg0)
11. Suba o túnel no cliente e teste
sudo wg-quick up wg0 ping 10.10.0.1
Rode sudo wg show nos dois lados e confira o campo latest handshake — se aparecer um tempo recente (segundos atrás), o túnel está estabelecido. Se ficar em branco, o problema está antes do WireGuard: firewall de borda, NAT ou porta errada.
Erros mais comuns
Handshake nunca aparece: quase sempre é a porta UDP 51820 bloqueada antes de chegar à interface — firewall do provedor cloud, roteador do cliente ou ISP com CGNAT sem port forward. Teste com nc -u -z -v IP_SERVIDOR 51820 a partir do cliente.
Túnel conecta mas sem internet: confira se net.ipv4.ip_forward está em 1 (sysctl net.ipv4.ip_forward) e se o nome da interface nas regras de PostUp bate com a interface real de saída do servidor.
Conexão cai depois de um tempo: cliente atrás de NAT sem PersistentKeepalive configurado, ou valor alto demais — 25 segundos é o padrão recomendado pela documentação do WireGuard.
Perguntas frequentes
WireGuard é mais seguro que OpenVPN?
Usa primitivas criptográficas mais modernas (ChaCha20-Poly1305, Curve25519) e uma base de código muito menor, o que facilita auditoria. OpenVPN é maduro e testado em campo há mais tempo, mas carrega mais superfície de configuração — e mais chance de erro humano.
Preciso de IP público ou funciona atrás de CGNAT?
Pelo menos uma ponta precisa ser alcançável (IP público ou NAT com port forward). Se ambas as pontas estiverem atrás de CGNAT, é preciso um terceiro ponto com IP público fazendo de intermediário.
Dá para rodar múltiplos túneis no mesmo servidor?
Sim — crie interfaces adicionais (wg1.conf, wg2.conf) com sub-redes e portas diferentes, cada uma com seu próprio systemctl enable wg-quick@wgN.
Qual a diferença entre AllowedIPs 0.0.0.0/0 e uma faixa específica?0.0.0.0/0 força todo o tráfego do cliente pelo túnel (full tunnel), útil para navegação segura em Wi-Fi público. Uma faixa específica (split tunnel) manda só o tráfego daquela rede pelo túnel e o resto sai direto pela internet local — mais rápido para uso diário de acesso a servidores internos.
WireGuard substitui o FortiGate ou o pfSense na borda?
Não — ele resolve o túnel VPN, não inspeção de tráfego, IPS ou políticas de firewall completas. Em ambientes com firewall dedicado, o mais comum é manter o WireGuard para acesso remoto ponto a ponto e o firewall de borda para o resto.
Conclusão
Um túnel WireGuard funcional sai do zero em onze comandos, sem lidar com proposals de fase 1/2 nem certificado de CA. Para acesso remoto de administrador, conexão entre filiais pequenas ou VPN pessoal em servidor doméstico, é hoje a opção com menor custo de manutenção. Para site-to-site corporativo com política de segurança centralizada, IPSec num firewall dedicado como FortiGate continua fazendo mais sentido — as duas tecnologias resolvem problemas diferentes, e vale ter as duas no repertório.