O que isto constrói
Uma instância executando WireGuard, entregando a cada cliente um endereço IPv4 privado, um endereço IPv6 roteado do seu próprio /48 e um resolvedor que vive dentro do túnel para que consultas DNS nunca tomem um caminho diferente do resto do tráfego. O firewall é drop por padrão em ambas as direções. O encaminhamento é habilitado apenas para a interface do túnel, e somente de saída.
Testado em um R-4 no AMS-01 com Debian 13. WireGuard é de fluxo único e do lado do kernel, então mais núcleos não compram nada até você empurrar vários gigabits através dele. O que importa muito mais é o local: escolha o mais próximo de onde você realmente está, porque cada milissegundo que você adiciona aqui você adiciona a cada pacote.
Antes de começar
- Uma instância implantada e root via SSH.
- O add-on IPv6 /48 habilitado no painel. O /64 incluído funciona para um único cliente, mas sub-redes por cliente fora de um único /64 significa fazer proxy de descoberta de vizinhos, e isso é um hobby em vez de uma configuração.
- Um hostname apontando para a instância. Tudo abaixo usa
vpn.example.com. - Cada endereço
2001:db8:aqui é espaço de documentação. Substitua o prefixo pelo mostrado na página da sua instância.
1. Pacotes e configurações do kernel
apt update && apt full-upgrade -y
apt install -y wireguard-tools nftables unbound qrencode
ip -br linkEsse último comando imprime o nome da sua interface voltada para fora. Nas nossas imagens KVM é ens3; se o seu for diferente, substitua em todos os lugares abaixo. Agora o kernel:
cat > /etc/sysctl.d/99-wireguard.conf <<EOF
net.ipv4.ip_forward = 1
net.ipv6.conf.all.forwarding = 1
net.ipv6.conf.ens3.accept_ra = 2
net.ipv4.conf.all.rp_filter = 1
EOF
sysctl --systemA linha accept_ra = 2 é a que as pessoas esquecem. Ativar o encaminhamento IPv6 faz o kernel parar de aceitar anúncios de roteador, a rota padrão desaparece em dez minutos e a máquina fica invisível em v6 enquanto ainda responde em v4. Definir para dois mantém a aceitação de anúncios em um host de encaminhamento.
2. Chaves
install -d -m 700 /etc/wireguard
umask 077
wg genkey | tee /etc/wireguard/server.key | wg pubkey > /etc/wireguard/server.pub
wg genkey | tee /etc/wireguard/laptop.key | wg pubkey > /etc/wireguard/laptop.pub
wg genpsk > /etc/wireguard/laptop.pskA chave pré-compartilhada não é opcional nesta construção. Não custa nada, é uma linha em cada configuração e é a diferença entre um túnel que é meramente seguro hoje e um que permanece seguro contra um adversário gravando tráfego agora para descriptografar depois.
3. A interface do servidor
Escreva /etc/wireguard/wg0.conf, colando o conteúdo das chaves onde marcado:
[Interface]
Address = 10.7.0.1/24, 2001:db8:1a2b:7::1/64
ListenPort = 51820
PrivateKey = <contents of /etc/wireguard/server.key>
MTU = 1420
[Peer]
# laptop
PublicKey = <contents of /etc/wireguard/laptop.pub>
PresharedKey = <contents of /etc/wireguard/laptop.psk>
AllowedIPs = 10.7.0.2/32, 2001:db8:1a2b:7::2/128No lado do servidor AllowedIPs é uma tabela de roteamento, não uma lista de permissões. Dê a cada peer exatamente os endereços que ele possui e nada mais amplo, ou dois clientes vão brigar pela mesma rota e o perdedor simplesmente parará de receber pacotes.
chmod 600 /etc/wireguard/wg0.conf4. Um resolvedor dentro do túnel
Apontar clientes para um resolvedor público desfaz boa parte do objetivo. Unbound já está instalado; dê a ele /etc/unbound/unbound.conf.d/tunnel.conf:
server:
interface: 10.7.0.1
interface: 2001:db8:1a2b:7::1
access-control: 10.7.0.0/24 allow
access-control: 2001:db8:1a2b:7::/64 allow
do-ip6: yes
prefetch: yes
hide-identity: yes
hide-version: yes
qname-minimisation: yesUnbound falhará ao iniciar antes que o túnel exista, porque esses endereços ainda não estão ativos. Sequencie isso corretamente em vez de lutar contra:
systemctl edit unbound[Unit]
[email protected]
[email protected]5. O firewall
Substitua /etc/nftables.conf inteiramente:
flush ruleset
table inet filter {
chain input {
type filter hook input priority filter; policy drop;
ct state established,related accept
ct state invalid drop
iif lo accept
ip protocol icmp accept
ip6 nexthdr icmpv6 accept
tcp dport 22 accept
udp dport 51820 accept
iifname "wg0" udp dport 53 accept
iifname "wg0" tcp dport 53 accept
}
chain forward {
type filter hook forward priority filter; policy drop;
ct state established,related accept
iifname "wg0" oifname "ens3" accept
iifname "wg0" oifname "wg0" drop
}
chain output {
type filter hook output priority filter; policy accept;
}
}
table ip nat {
chain postrouting {
type nat hook postrouting priority srcnat; policy accept;
ip saddr 10.7.0.0/24 oifname "ens3" masquerade
}
}Observe o que está ausente: não há tabela NAT para IPv6. Clientes saem com seu próprio endereço do seu /48, que é exatamente o motivo de pegar o /48 em primeiro lugar. A linha iifname "wg0" oifname "wg0" drop impede que peers se alcancem, o que você quer a menos que esteja deliberadamente construindo uma malha.
systemctl enable --now nftables
nft list ruleset | head -206. Inicie
systemctl enable --now wg-quick@wg0
systemctl restart unbound
wg show wg07. O cliente
[Interface]
PrivateKey = <contents of /etc/wireguard/laptop.key>
Address = 10.7.0.2/24, 2001:db8:1a2b:7::2/64
DNS = 10.7.0.1
MTU = 1420
[Peer]
PublicKey = <contents of /etc/wireguard/server.pub>
PresharedKey = <contents of /etc/wireguard/laptop.psk>
Endpoint = vpn.example.com:51820
AllowedIPs = 0.0.0.0/0, ::/0
PersistentKeepalive = 25Para um telefone, transforme isso em um código QR no servidor e fotografe o terminal:
qrencode -t ansiutf8 < /root/laptop.confEm um cliente Debian ou Ubuntu, a linha DNS = precisa que openresolv esteja instalado, senão wg-quick imprime um aviso e silenciosamente deixa seu resolvedor antigo no lugar. Essa é a causa mais comum de um túnel que funciona perfeitamente e vaza toda consulta.
Verifique
Quatro verificações, em ordem. Qualquer coisa que falhar indica em qual etapa voltar.
# on the server, after connecting the client
wg show wg0 latest-handshakes
wg show wg0 transferUm timestamp de handshake dentro dos últimos dois minutos e contadores diferentes de zero em ambas as direções significam que a criptografia e o roteamento estão ambos bem.
# on the client
ping -c3 10.7.0.1
ping -c3 2001:db8:1a2b:7::1
dig @10.7.0.1 paragonvps.com AAAA +shortO terceiro comando prova que o resolvedor do túnel está respondendo. Se expirar, o unbound iniciou antes do wg0 existir; reinicie-o.
A última verificação é a única que prova que seu tráfego sai de onde você pensa que sai, e precisa de uma segunda máquina. Qualquer outra instância na frota serve, em qualquer cidade:
# on the second instance
nc -lv 9101
# on the client, tunnel up
curl -m5 -4 http://second.example.com:9101/
curl -m5 -6 http://second.example.com:9101/O ouvinte imprime o endereço de origem de cada conexão. Sua tentativa v4 deve chegar do servidor WireGuard, porque foi mascarada. A tentativa v6 deve chegar do endereço de túnel do próprio cliente dentro do seu /48, intacta, que é o que roteado significa e com proxy não.
Quando dá errado
| Sintoma | Causa | Correção |
|---|---|---|
| Handshake bem-sucedido, nenhum tráfego passa | Encaminhamento desligado, ou a cadeia forward descarta | sysctl net.ipv4.ip_forward, depois releia a cadeia forward |
| Solicitações pequenas OK, downloads grandes travam | MTU e descoberta de caminho | Reduza ambas as configurações para MTU = 1380 e tente novamente |
| IPv6 morre cerca de dez minutos após o boot | Encaminhamento matou anúncios de roteador | accept_ra = 2 na interface de saída |
| DNS resolve fora do túnel | Cliente ignorou DNS = | Instale openresolv no cliente |
| Tudo sumiu após reinicialização | Unidades nunca habilitadas | systemctl enable wg-quick@wg0 nftables unbound |
A partir daqui, os próximos passos sensatos são um segundo endpoint em outra região e uma pilha de monitoramento que te diga quando um deles parar de responder. Ambos estão cobertos em outro lugar em os guias; a página de rede explica o que a borda faz com seu tráfego antes de chegar até você.