WireGuard VPN self-hosted na VPS

WireGuard é o protocolo VPN mais moderno e eficiente, configuração simples, criptografia de última geração e performance superior ao OpenVPN e IPSec. Self-hosteado na VPS, você cria uma rede privada para acessar serviços internos sem expô-los à internet, conectar múltiplas VPSs ou rotear todo o tráfego de dispositivos remotos.

Instalar e configurar o servidor WireGuard

Setup do servidor WireGuard no Ubuntu:

bash
# Instalar WireGuard:
sudo apt update && sudo apt install -y wireguard

# Gerar par de chaves do servidor:
wg genkey | sudo tee /etc/wireguard/server_private.key | \
  wg pubkey | sudo tee /etc/wireguard/server_public.key
sudo chmod 600 /etc/wireguard/server_private.key

SERVER_PRIVATE=$(sudo cat /etc/wireguard/server_private.key)
SERVER_PUBLIC=$(sudo cat /etc/wireguard/server_public.key)

# Criar configuração do servidor:
sudo tee /etc/wireguard/wg0.conf << EOF
[Interface]
Address    = 10.8.0.1/24
ListenPort = 51820
PrivateKey = $SERVER_PRIVATE

# Habilitar roteamento de tráfego (para VPN de saída total)
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
EOF

# Habilitar IP forwarding:
sudo sysctl -w net.ipv4.ip_forward=1
echo "net.ipv4.ip_forward=1" | sudo tee -a /etc/sysctl.conf

# Liberar porta UDP no UFW:
sudo ufw allow 51820/udp

# Iniciar WireGuard:
sudo systemctl enable wg-quick@wg0
sudo systemctl start wg-quick@wg0
sudo wg show

Adicionar cliente (peer) ao servidor

Configurar um cliente e adicioná-lo ao servidor:

bash
# Na máquina cliente — gerar par de chaves:
wg genkey | tee client_private.key | wg pubkey > client_public.key

CLIENT_PRIVATE=$(cat client_private.key)
CLIENT_PUBLIC=$(cat client_public.key)
SERVER_PUBLIC="CHAVE_PUBLICA_DO_SERVIDOR"

# Criar configuração do cliente:
cat > wg-client.conf << EOF
[Interface]
Address    = 10.8.0.2/32       # IP do cliente na VPN
PrivateKey = $CLIENT_PRIVATE
DNS        = 1.1.1.1           # DNS para usar na VPN

[Peer]
PublicKey  = $SERVER_PUBLIC
Endpoint   = IP_VPS:51820
AllowedIPs = 10.8.0.0/24       # apenas tráfego da rede VPN
# AllowedIPs = 0.0.0.0/0       # rotear TODO o tráfego pela VPS
PersistentKeepalive = 25
EOF

# Adicionar o cliente no servidor:
sudo wg set wg0 peer $CLIENT_PUBLIC \
  allowed-ips 10.8.0.2/32

# Salvar a config para persistir após reboot:
sudo wg-quick save wg0

# No cliente — conectar:
# Linux: sudo wg-quick up ./wg-client.conf
# macOS/Windows: importar wg-client.conf no app WireGuard
# iOS/Android: gerar QR code: qrencode -t ansiutf8 < wg-client.conf

Script para gerenciar clientes WireGuard

Automatizar adição e remoção de peers:

bash
#!/bin/bash
# /opt/scripts/wg-add-client.sh — adicionar novo cliente

CLIENT_NAME="${1:-cliente}"
NEXT_IP="${2:-10.8.0.10}"  # passar IP ou incrementar automaticamente
SERVER_PUBLIC=$(cat /etc/wireguard/server_public.key)
VPS_IP=$(curl -s ifconfig.me)

# Gerar chaves do cliente:
CLIENT_PRIVATE=$(wg genkey)
CLIENT_PUBLIC=$(echo "$CLIENT_PRIVATE" | wg pubkey)

# Criar arquivo de configuração:
cat > "/opt/wireguard/clients/${CLIENT_NAME}.conf" << EOF
[Interface]
Address    = ${NEXT_IP}/32
PrivateKey = $CLIENT_PRIVATE
DNS        = 1.1.1.1

[Peer]
PublicKey  = $SERVER_PUBLIC
Endpoint   = ${VPS_IP}:51820
AllowedIPs = 10.8.0.0/24
PersistentKeepalive = 25
EOF

# Adicionar ao servidor:
sudo wg set wg0 peer "$CLIENT_PUBLIC" allowed-ips "${NEXT_IP}/32"
sudo wg-quick save wg0

echo "Cliente '$CLIENT_NAME' adicionado com IP ${NEXT_IP}"
echo "Config salva em: /opt/wireguard/clients/${CLIENT_NAME}.conf"

# Gerar QR code para mobile:
qrencode -t ansiutf8 < "/opt/wireguard/clients/${CLIENT_NAME}.conf"

VPN site-to-site entre duas VPSs

Conectar duas VPSs em redes privadas diferentes:

bash
# Cenário: VPS-A (São Paulo) ↔ VPS-B (Frankfurt)
# Objetivo: serviços na VPS-A acessam banco na VPS-B via rede privada

# Na VPS-A (servidor/cliente):
# wg0.conf — adicionar peer VPS-B:
[Peer]
PublicKey  = CHAVE_PUBLICA_VPS_B
Endpoint   = IP_VPS_B:51820
AllowedIPs = 10.8.0.2/32, 192.168.2.0/24  # IP da VPN + rede privada da VPS-B

# Na VPS-B (servidor/cliente):
# wg0.conf — adicionar peer VPS-A:
[Peer]
PublicKey  = CHAVE_PUBLICA_VPS_A
Endpoint   = IP_VPS_A:51820
AllowedIPs = 10.8.0.1/32, 192.168.1.0/24  # IP da VPN + rede privada da VPS-A

# Verificar conectividade após setup:
# Na VPS-A:
ping 10.8.0.2              # ping para o endpoint WireGuard da VPS-B
psql -h 10.8.0.2 -U postgres meu_banco  # acessar banco na VPS-B

# Monitorar status da conexão:
sudo wg show wg0
sudo wg show wg0 latest-handshakes

Instalar WireGuard com interface web (wg-easy)

Painel web para gerenciar clientes WireGuard com Docker:

yaml
# wg-easy: painel web para WireGuard via Docker
# docker-compose.yml:
services:
  wg-easy:
    image: ghcr.io/wg-easy/wg-easy:latest
    cap_add:
      - NET_ADMIN
      - SYS_MODULE
    sysctls:
      - net.ipv4.conf.all.src_valid_mark=1
      - net.ipv4.ip_forward=1
    ports:
      - "51820:51820/udp"        # WireGuard
      - "127.0.0.1:51821:51821"  # UI web
    environment:
      WG_HOST: IP_OU_DOMINIO_DA_VPS
      PASSWORD_HASH: "${WG_PASSWORD_HASH}"    # bcrypt hash
      WG_DEFAULT_ADDRESS: "10.8.0.x"
      WG_DEFAULT_DNS: "1.1.1.1"
    volumes:
      - wg_data:/etc/wireguard
    restart: always

volumes:
  wg_data:

# Gerar hash da senha:
# docker run ghcr.io/wg-easy/wg-easy wgpw SUASENHA
# Acessar UI em: https://vpn.seudominio.com.br (com Nginx na frente)

Não quer configurar manualmente?

Implante o VPS em menos de 5 minutos com a Runstack. Infraestrutura da OPEN Datacenter, com servidores em São Paulo.

Perguntas frequentes

WireGuard: protocolo moderno, muito mais rápido que OpenVPN, kernel nativo no Linux desde 5.6. OpenVPN: mais antigo, mais compatível com firewalls corporativos (porta 443 TCP), mas mais pesado. Tailscale: usa WireGuard por baixo, mas gerenciado (gratuito até 100 dispositivos), zero configuração de servidor, ideal para equipes pequenas. Self-hosted com controle total: WireGuard puro. Facilidade sem servidor: Tailscale.

Sim, ao usar AllowedIPs = 0.0.0.0/0 (full tunnel), todo o tráfego passa pela VPS. A velocidade máxima fica limitada pelo upload/download da VPS. WireGuard em si adiciona overhead mínimo (~5%). Para acesso apenas à rede privada (AllowedIPs = 10.8.0.0/24): zero impacto na velocidade da internet do cliente.

WireGuard suporta múltiplos peers, cada peer recebe um IP diferente na faixa da VPN (10.8.0.2, 10.8.0.3, etc.). Todos se conectam simultaneamente ao mesmo servidor. No servidor: cada peer tem um bloco [Peer] em wg0.conf com sua chave pública e AllowedIPs individuais. Use o script wg-add-client.sh ou o painel wg-easy para facilitar.

Sim, o parâmetro PersistentKeepalive = 25 mantém a conexão UDP ativa mesmo por trás de NAT, enviando um pacote keepalive a cada 25 segundos. Para clientes atrás de NAT estrito: pode ser necessário usar NAT traversal ou configurar port forwarding. Tailscale resolve isso automaticamente com DERP relays.

sudo wg show exibe: peers configurados, handshake mais recente (latest handshake), bytes transferidos e endpoint atual. Se "latest handshake" for mais de 2-3 minutos: o cliente está desconectado. wg show wg0 latest-handshakes mostra timestamp do último handshake para cada peer.