Dia 20: VPN — WireGuard e OpenVPN, Túneis Site-to-Site

As redes privadas virtuais (VPN) permitem ligar redes ou utilizadores remotos através de ligações encriptadas sobre Internet. Neste vigésimo dia da série Linux 30 Dias, exploramos WireGuard e OpenVPN — as duas tecnologias dominantes — com foco em túneis site-to-site, a configuração mais usada para interligar filiais, data centers e infraestruturas cloud.

Neste artigo

Introdução — VPN site-to-site vs road warrior

Existem dois modelos fundamentais de VPN. O modelo road warrior liga um utilizador remoto (laptop, telemóvel) a uma rede corporativa — o cliente inicia a ligação a partir de qualquer ponto da Internet e recebe um IP dentro da rede privada. O modelo site-to-site liga duas redes inteiras entre si: o escritório do Porto e o escritório de Lisboa comunicam como se partilhassem o mesmo switch, sem qualquer intervenção do utilizador final.

No site-to-site, dois gateways (routers Linux ou appliances) estabelecem um túnel permanente. Cada lado tem uma rede local (ex: 10.0.1.0/24 e 10.0.2.0/24) e os pacotes são encaminhados entre elas através do túnel encriptado. Os utilizadores de cada lado nem precisam de saber que a VPN existe — acedem aos recursos da outra rede por IPs internos.

ℹ Info: O road warrior usa certificados/credenciais por utilizador e o cliente liga-se sob demanda. O site-to-site usa chaves partilhadas entre gateways e o túnel está sempre activo. Esta diferença arquitectural determina a configuração de routing, firewall e monitorização.

WireGuard e OpenVPN são as duas implementações dominantes em Linux. WireGuard é minimalista, rápida e usa criptografia moderna (Curve25519, ChaCha20-Poly1305). OpenVPN é mais maduro, flexível e baseia-se em TLS com uma PKI X.509 completa. Ambos suportam os dois modelos — a escolha depende dos requisitos de performance, compatibilidade e complexidade de gestão.

WireGuard — instalação, chaves e site-to-site

WireGuard está incluído no kernel Linux desde a versão 5.6 (2020). Em Debian/Ubuntu basta instalar o pacote wireguard-tools que fornece wg e wg-quick:

# Debian/Ubuntu
apt install -y wireguard-tools

# CentOS/RHEL/Fedora
dnf install -y wireguard-tools

# Verificar módulo kernel
modprobe wireguard
lsmod | grep wireguard

WireGuard usa pares de chaves Curve25519. Cada peer gera a sua chave privada e deriva a chave pública correspondente. As chaves privadas nunca saem do host:

# Gerar chaves (nó A — escritório Porto)
umask 077
wg genkey > /etc/wireguard/privatekey
wg pubkey < /etc/wireguard/privatekey > /etc/wireguard/publickey

# Anotar a chave pública (partilhar com o peer)
cat /etc/wireguard/publickey
# Exemplo: aB3cD4eF5gH6iJ7kL8mN9oP0qR1sT2uV3wX4yZ5aBc=

# Repetir no nó B — escritório Lisboa
wg genkey > /etc/wireguard/privatekey
wg pubkey < /etc/wireguard/privatekey > /etc/wireguard/publickey

A configuração do túnel site-to-site vive em /etc/wireguard/wg0.conf. O nó A (Porto, IP público 203.0.113.10, rede interna 10.0.1.0/24):

# /etc/wireguard/wg0.conf — Nó A (Porto)
[Interface]
PrivateKey = <chave_privada_do_nó_A>
Address = 10.10.0.1/24
ListenPort = 51820
# Permitir tráfego entre as redes internas
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

[Peer]
# Nó B (Lisboa)
PublicKey = <chave_pública_do_nó_B>
AllowedIPs = 10.10.0.2/32, 10.0.2.0/24
Endpoint = 198.51.100.20:51820
PersistentKeepalive = 25

O nó B (Lisboa, IP público 198.51.100.20, rede interna 10.0.2.0/24) espelha a configuração:

# /etc/wireguard/wg0.conf — Nó B (Lisboa)
[Interface]
PrivateKey = <chave_privada_do_nó_B>
Address = 10.10.0.2/24
ListenPort = 51820
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

[Peer]
# Nó A (Porto)
PublicKey = <chave_pública_do_nó_A>
AllowedIPs = 10.10.0.1/32, 10.0.1.0/24
Endpoint = 203.0.113.10:51820
PersistentKeepalive = 25

Activar o túnel em ambos os nós e confirmar o estado:

# Activar interface
wg-quick up wg0

# Verificar estado do túnel
wg show
# interface: wg0
#   listening port: 51820
# peer: <chave_pública_do_peer>
#   endpoint: 198.51.100.20:51820
#   allowed ips: 10.10.0.2/32, 10.0.2.0/24
#   latest handshake: 4 seconds ago
#   transfer: 1.2 KiB received, 3.4 KiB sent

# Testar conectividade entre redes
ping 10.0.2.1  # do Porto para Lisboa

# Persistir arranque
systemctl enable wg-quick@wg0

ℹ Info: O campo AllowedIPs define quais redes são aceitáveis pelo peer. Incluir 10.0.2.0/24 no peer do nó A garante que o WireGuard aceita tráfego dessa rede e encaminha pacotes para o túnel. É o equivalente ao remote-network do OpenVPN.

OpenVPN — PKI easy-rsa, servidor e cliente

OpenVPN é mais antigo (2001) e usa TLS/X.509 para autenticação. Requer uma PKI (Public Key Infrastructure) com uma CA, certificados de servidor e certificados de cliente. O pacote easy-rsa automatiza a gestão da PKI.

# Instalar OpenVPN e easy-rsa
apt install -y openvpn easy-rsa

# Inicializar PKI no servidor
make-cadir /etc/openvpn/easy-rsa
cd /etc/openvpn/easy-rsa
./easyrsa init-pki
./easyrsa build-ca nopass
# Common Name: kbase-VPN-CA

# Gerar certificado e chave do servidor
./easyrsa gen-req server nopass
./easyrsa sign-req server server

# Gerar parâmetros Diffie-Hellman
./easyrsa gen-dh

# Gerar certificado de cliente (para road warrior)
./easyrsa gen-req cliente1 nopass
./easyrsa sign-req client cliente1

# Gerar chave estática TLS (proteção contra DoS)
openvpn --genkey secret /etc/openvpn/ta.key

A configuração do servidor OpenVPN (/etc/openvpn/server.conf) para um cenário site-to-site onde o servidor é o nó A (Porto):

# /etc/openvpn/server.conf — Nó A (Porto)
port 1194
proto udp
dev tun

# Certificados
ca /etc/openvpn/easy-rsa/pki/ca.crt
cert /etc/openvpn/easy-rsa/pki/issued/server.crt
key /etc/openvpn/easy-rsa/pki/private/server.key
dh /etc/openvpn/easy-rsa/pki/dh.pem
tls-auth /etc/openvpn/ta.key 0

# Rede do túnel
server 10.20.0.0 255.255.255.0

# Rotas — Push da rede remota para o cliente
push "route 10.0.1.0 255.255.255.0"

# Rota local do túnel para a rede do cliente (site-to-site)
client-config-dir /etc/openvpn/ccd
route 10.0.2.0 255.255.255.0

# Manter ligação
keepalive 10 120
cipher AES-256-GCM
auth SHA256
user nobody
group nogroup
persist-key
persist-tun
status /var/log/openvpn-status.log
verb 3

No site-to-site com OpenVPN, o lado cliente (nó B — Lisboa) precisa de uma configuração específica em ccd (client-config-dir) para atribuir um IP fixo e definir a rede por trás do cliente:

# /etc/openvpn/ccd/cliente-lisboa
ifconfig-push 10.20.0.2 10.20.0.1
iroute 10.0.2.0 255.255.255.0

O ficheiro de configuração do cliente OpenVPN no nó B (Lisboa):

# /etc/openvpn/client.conf — Nó B (Lisboa)
client
dev tun
proto udp
remote 203.0.113.10 1194
resolv-retry infinite
nobind
persist-key
persist-tun

ca ca.crt
cert cliente-lisboa.crt
key cliente-lisboa.key
tls-auth ta.key 1
cipher AES-256-GCM
auth SHA256
verb 3
# Activar serviço em ambos os lados
systemctl enable openvpn@server   # nó A
systemctl start openvpn@server

systemctl enable openvpn@client    # nó B
systemctl start openvpn@client

# Verificar
systemctl status openvpn@server
ip addr show tun0

Túneis Site-to-Site — configuração, routing e MTU

O site-to-site exige três componentes em cada lado: o túnel encriptado, o routing entre redes internas e o IP forwarding activo. Sem IP forwarding, o kernel descarta pacotes que chegam por uma interface e devem seguir por outra.

# Activar IP forwarding (ambos os nós)
echo "net.ipv4.ip_forward = 1" >> /etc/sysctl.conf
sysctl -p

# Confirmar
cat /proc/sys/net/ipv4/ip_forward
# 1

No WireGuard, o routing é automático: AllowedIPs define as redes que cada peer anuncia e aceita. O wg-quick adiciona as rotas automaticamente. No OpenVPN, o servidor precisa das directivas route (encaminhamento do lado do servidor) e iroute (encaminhamento interno do cliente) para que cada rede saiba da outra.

A firewall precisa de permitir tráfego UDP nos portos de escuta e forwarding entre interfaces:

# WireGuard — abrir porto UDP 51820
iptables -A INPUT -p udp --dport 51820 -j ACCEPT

# OpenVPN — abrir porto UDP 1194
iptables -A INPUT -p udp --dport 1194 -j ACCEPT

# Permitir forwarding entre túnel e LAN
iptables -A FORWARD -i wg0 -o eth0 -j ACCEPT
iptables -A FORWARD -i eth0 -o wg0 -m state --state RELATED,ESTABLISHED -j ACCEPT

O MTU é crítico em túneis. A encapsulação adiciona overhead: WireGuard usa ~80 bytes, OpenVPN com UDP/TLS ~70-90 bytes. Se o MTU for demasiado alto, os pacotes fragmentam e a performance cai drasticamente. Recomenda-se reduzir o MTU para 1420 (WireGuard) ou 1400 (OpenVPN) em ligações sobre Internet:

# WireGuard — definir MTU em wg0.conf
[Interface]
...
MTU = 1420

# OpenVPN — definir MSS e fragment
mssfix 1360
fragment 1400
mtu-test  # descobrir MTU óptimo automaticamente

# Verificar MTU em uso
ip link show wg0
# wg0: <POINTOPOINT,NOARP,UP,LOWER_UP> mtu 1420

# Testar com ping sem fragmentação
ping -M do -s 1392 10.0.2.1

⚠ Atenção: Se os clientes não conseguem aceder a recursos da rede remota mas o túnel está activo, verifique três pontos: (1) IP forwarding activo, (2) regras de FORWARD na firewall, (3) rotas nas máquinas internas apontando para o gateway VPN. O túnel só transporta pacotes que chegam à interface — se as máquinas locais não sabem que o gateway VPN existe, o tráfego nunca chega ao túnel.

Erros Comuns — diagnóstico e soluções

A tabela seguinte resume os problemas mais frequentes em túneis VPN site-to-site e as soluções correspondentes:

Problema Causa provável Solução
Sem handshake WireGuard Endpoint errado, firewall bloqueia UDP ou chaves trocadas Verificar wg show, confirmar PublicKey do peer e abrir porto 51820/udp
Handshake OK mas sem ping AllowedIPs não inclui rede remota ou IP forwarding inactivo Adicionar 10.0.2.0/24 a AllowedIPs; activar net.ipv4.ip_forward=1
OpenVPN: TLS error Certificados expirados, CA errada ou tls-auth assimétrico Verificar datas com openssl x509 -enddate; confirmar que cliente usa ta.key 1 e servidor ta.key 0
Tráfego lento ou intermitente MTU demasiado alto causa fragmentação Reduzir MTU para 1420 (WireGuard) ou 1400 (OpenVPN); usar mssfix no OpenVPN
Túnel cai periodicamente NAT stateful fecha ligações inactivas; sem keepalive WireGuard: PersistentKeepalive = 25; OpenVPN: keepalive 10 120
Cliente não recebe rota da rede remota Falta push "route" ou iroute no CCD Adicionar push "route 10.0.1.0 255.255.255.0" no server.conf e iroute 10.0.2.0 255.255.255.0 no CCD
Asymmetric routing Tráfego sai pelo túnel mas regressa por outra rota Verificar rotas com ip route get <ip> em ambos os sentidos; garantir NAT ou rota estática de regresso

O diagnóstico sistemático começa por confirmar que o túnel está estabelecido (wg show ou openvpn-status.log), depois testa-se a camada de routing com tcpdump nas interfaces túnel e LAN, e por último avalia-se a firewall com iptables -L -v -n. Na maioria dos casos, o problema é de routing ou firewall — raramente de criptografia.

WireGuard e OpenVPN coexistem perfeitamente na mesma máquina — é comum ter WireGuard para site-to-site (mais rápido, menos overhead) e OpenVPN para road warriors (mais flexível, melhor suporte de clientes móveis). Para aprofundar firewalls e encaminhamento de tráfego VPN, consulte o Dia 9: Firewalls — iptables, nftables, UFW, firewalld. Para integrar o servidor de correio acessível remotamente via VPN, veja o Dia 19: Postfix e Dovecot — Mail Server SMTP/IMAP.

No próximo dia exploramos monitorização e alerta com Prometheus, Grafana e alertmanager — a base da observabilidade em infraestruturas Linux modernas.