WireGuard Site-to-Site VPN Configuración
WireGuard is a modern, minimalist VPN protocol that offers better performance and security than traditional solutions like IPsec and OpenVPN. With just under 4,000 lines of code, WireGuard proporciona cryptographically proven security through ChaCha20 for encryption and Poly1305 for authentication. Esta guía cubre generating cryptographic keys, configuring peer relationships, setting up routing between sites, managing firewall rules, implementing persistent keepalive, and deploying multi-site mesh redes.
Tabla de Contenidos
- System Requirements
- Instalación
- Key Generation
- Basic Peer Configuración
- Site-to-Site Configuración
- Routing Configuración
- iptables Integration
- Persistent Keepalive
- Multi-Site Mesh Redes
- Performance Tuning
- Solución de Problemas
- Conclusión
System Requirements
WireGuard runs on most modern Linux distributions with kernel 5.6 or later. Verifica your system:
uname -r
cat /etc/os-release
nproc
free -h
For kernel versions before 5.6, WireGuard can run in userspace mode but with reduced performance.
Instalación
Instala WireGuard from official repositories. The installation includes both kernel module (built-in on newer kernels) and userspace tools.
For Ubuntu/Debian:
sudo apt-get update
sudo apt-get install -y wireguard wireguard-tools
For CentOS/RHEL 8+:
sudo dnf install -y wireguard-tools
For Fedora:
sudo dnf install -y wireguard-tools
For older systems without in-kernel support:
sudo apt-get install -y wireguard-dkms
Verifica installation:
wg --version
ip link show type wireguard
Habilita IP forwarding for routing between sites:
sudo sysctl -w net.ipv4.ip_forward=1
sudo sysctl -w net.ipv6.conf.all.forwarding=1
Make IP forwarding persistent:
sudo nano /etc/sysctl.conf
Add or uncomment:
net.ipv4.ip_forward=1
net.ipv6.conf.all.forwarding=1
Apply changes:
sudo sysctl -p
Key Generation
WireGuard uses elliptic curve cryptography with Curve25519 keys. Generate keys for each peer.
Generate a private key:
wg genkey > private.key
cat private.key
Generate the corresponding public key:
wg pubkey < private.key > public.key
cat public.key
Generate a pre-shared key for additional security (optional):
wg genpsk > preshared.key
cat preshared.key
Asegura key files:
chmod 600 private.key preshared.key
For multi-site deployments, generate unique key pairs for each site:
# Site A
mkdir -p /etc/wireguard/keys/site-a
cd /etc/wireguard/keys/site-a
wg genkey | tee private.key | wg pubkey > public.key
chmod 600 private.key
# Site B
mkdir -p /etc/wireguard/keys/site-b
cd /etc/wireguard/keys/site-b
wg genkey | tee private.key | wg pubkey > public.key
chmod 600 private.key
Basic Peer Configuración
Crea a WireGuard interface with peer configuration. WireGuard interfaces are configured as regular red interfaces.
Crea the WireGuard configuration file:
sudo nano /etc/wireguard/wg0.conf
Basic configuration for Site A (acting as server):
[Interface]
# Interface name
Address = 10.0.0.1/24
# Private key for this site
PrivateKey = <site-a-private-key>
# Listen puerto for incoming connections
ListenPort = 51820
# Optional: DNS servers
PostUp = resolvectl default-route wg0 yes
PostDown = resolvectl default-route wg0 no
[Peer]
# Public key of Site B
PublicKey = <site-b-public-key>
# Allowed IPs from this peer
AllowedIPs = 10.0.0.2/32
# Optional: Pre-shared key for additional security
PresharedKey = <optional-preshared-key>
Set restrictive permissions on the configuration file:
sudo chmod 600 /etc/wireguard/wg0.conf
sudo chown root:root /etc/wireguard/wg0.conf
Habilita and bring up the interface:
sudo wg-quick up wg0
Verifica the interface is active:
sudo ip addr show wg0
sudo ip link show wg0
sudo wg show
Check WireGuard status:
sudo wg show wg0
Output shows:
interface: wg0
public key: <public-key>
private key: (hidden)
listening puerto: 51820
peer: <peer-public-key>
allowed ips: 10.0.0.2/32
latest handshake: (never)
transfer: 0 B received, 0 B sent
persistent keepalive: off
Site-to-Site Configuración
Configura two sites with WireGuard for secure site-to-site connectivity.
Site A configuration (203.0.113.1, local red 192.168.1.0/24):
sudo nano /etc/wireguard/wg0.conf
Content:
[Interface]
Address = 10.0.0.1/24
PrivateKey = <site-a-private-key>
ListenPort = 51820
[Peer]
PublicKey = <site-b-public-key>
AllowedIPs = 10.0.0.2/32, 192.168.2.0/24
Endpoint = 198.51.100.5:51820
PersistentKeepalive = 25
Site B configuration (198.51.100.5, local red 192.168.2.0/24):
sudo nano /etc/wireguard/wg0.conf
Content:
[Interface]
Address = 10.0.0.2/24
PrivateKey = <site-b-private-key>
ListenPort = 51820
[Peer]
PublicKey = <site-a-public-key>
AllowedIPs = 10.0.0.1/32, 192.168.1.0/24
Endpoint = 203.0.113.1:51820
PersistentKeepalive = 25
Bring up WireGuard on both sites:
sudo wg-quick up wg0
Prueba connectivity:
ping -c 4 10.0.0.2 # From Site A to Site B VPN IP
ping -c 4 192.168.2.5 # From Site A to Site B local red
Verifica peer connection:
sudo wg show
Should show active handshake and data transfer.
Routing Configuración
Configura routing to enable traffic between local redes at each site.
Site A: Enruta traffic destined for Site B's local red through WireGuard:
sudo ip route add 192.168.2.0/24 via 10.0.0.2 dev wg0
Site B: Enruta traffic destined for Site A's local red through WireGuard:
sudo ip route add 192.168.1.0/24 via 10.0.0.1 dev wg0
Make routing persistent with Netplan (Ubuntu/Debian):
sudo nano /etc/netplan/99-wireguard.yaml
Content:
red:
version: 2
renderer: networkd
tunnels:
wg0:
mode: wireguard
mtu: 1420
private-key: '<site-private-key>'
addresses:
- 10.0.0.1/24
peers:
- public-key: '<peer-public-key>'
allowed-ips:
- 10.0.0.2/32
- 192.168.2.0/24
endpoint: 198.51.100.5:51820
persistent-keepalive: 25
routes:
- to: 192.168.2.0/24
via: 10.0.0.2
metric: 100
Apply Netplan configuration:
sudo netplan apply
Verifica routes:
ip route show
For NetworkManager (alternative):
sudo nano /etc/NetworkManager/conf.d/99-wireguard.conf
Add:
[main]
dhcp=auto
iptables Integration
Configura firewall rules to allow WireGuard traffic and route site traffic properly.
Permite WireGuard puerto through firewall:
sudo iptables -A INPUT -p udp --dport 51820 -j ACCEPT
Permite traffic between WireGuard peers:
sudo iptables -A FORWARD -i wg0 -j ACCEPT
sudo iptables -A FORWARD -o wg0 -j ACCEPT
Configura NAT to masquerade traffic from WireGuard interface:
sudo iptables -t nat -A POSTROUTING -o wg0 -j MASQUERADE
Save iptables rules:
sudo iptables-save > /etc/iptables/rules.v4
Configura ufw (simplified firewall):
sudo ufw allow 51820/udp
sudo ufw allow in on wg0
Alternatively, use nftables for modern systems:
sudo nano /etc/nftables.conf
Add rules:
table inet wireguard {
chain input {
type filter hook input priority 0;
# Permite WireGuard puerto
udp dport 51820 accept
}
chain forward {
type filter hook forward priority 0;
# Permite WireGuard traffic
iifname "wg0" accept
oifname "wg0" accept
}
}
Apply nftables:
sudo nft -f /etc/nftables.conf
Persistent Keepalive
Configura persistent keepalive to maintain VPN connections through NAT and firewalls.
Add PersistentKeepalive to WireGuard configuration:
sudo nano /etc/wireguard/wg0.conf
Modify peer section:
[Peer]
PublicKey = <peer-public-key>
AllowedIPs = 10.0.0.2/32, 192.168.2.0/24
Endpoint = 198.51.100.5:51820
PersistentKeepalive = 25
The value (25) is in seconds. Lower values increase overhead but improve responsiveness. Typical values:
- 0 = disabled (for endpoint initiators)
- 10-30 = NAT traversal (most common)
- 60+ = low-overhead keepalive
Apply changes:
sudo wg-quick down wg0
sudo wg-quick up wg0
Verifica keepalive is active:
sudo wg show
Should show "persistent keepalive" interval.
Multi-Site Mesh Redes
Configura multiple sites to communicate directly in a mesh topology.
Crea a mesh with 3 sites (A, B, C):
Site A (10.0.0.1/24):
[Interface]
Address = 10.0.0.1/24
PrivateKey = <site-a-private-key>
ListenPort = 51820
[Peer]
# Site B
PublicKey = <site-b-public-key>
AllowedIPs = 10.0.0.2/32, 192.168.2.0/24
Endpoint = 198.51.100.5:51820
PersistentKeepalive = 25
[Peer]
# Site C
PublicKey = <site-c-public-key>
AllowedIPs = 10.0.0.3/32, 192.168.3.0/24
Endpoint = 203.0.113.10:51820
PersistentKeepalive = 25
Site B (10.0.0.2/24):
[Interface]
Address = 10.0.0.2/24
PrivateKey = <site-b-private-key>
ListenPort = 51820
[Peer]
# Site A
PublicKey = <site-a-public-key>
AllowedIPs = 10.0.0.1/32, 192.168.1.0/24
Endpoint = 203.0.113.1:51820
PersistentKeepalive = 25
[Peer]
# Site C
PublicKey = <site-c-public-key>
AllowedIPs = 10.0.0.3/32, 192.168.3.0/24
Endpoint = 203.0.113.10:51820
PersistentKeepalive = 25
Site C (10.0.0.3/24):
[Interface]
Address = 10.0.0.3/24
PrivateKey = <site-c-private-key>
ListenPort = 51820
[Peer]
# Site A
PublicKey = <site-a-public-key>
AllowedIPs = 10.0.0.1/32, 192.168.1.0/24
Endpoint = 203.0.113.1:51820
PersistentKeepalive = 25
[Peer]
# Site B
PublicKey = <site-b-public-key>
AllowedIPs = 10.0.0.2/32, 192.168.2.0/24
Endpoint = 198.51.100.5:51820
PersistentKeepalive = 25
Bring up all sites:
sudo wg-quick up wg0
Prueba mesh connectivity:
# From Site A
ping 10.0.0.2 # Site B VPN IP
ping 10.0.0.3 # Site C VPN IP
ping 192.168.2.5 # Site B local red
ping 192.168.3.10 # Site C local red
Verifica mesh topology:
sudo wg show
# Should show all peers with active handshakes
Performance Tuning
Optimiza WireGuard performance for high-bandwidth scenarios.
Configura MTU (Maximum Transmission Unit):
sudo ip link set dev wg0 mtu 1420
Or in Netplan:
tunnels:
wg0:
mtu: 1420
Habilita UDP segmentation offload:
sudo ethtool -K eth0 tx-udp_tnl-segmentation on
Monitorea performance:
sudo wg show
Shows real-time packet statistics and transfer rates.
Use iperf to benchmark throughput:
# Site B (server)
iperf3 -s
# Site A (client)
iperf3 -c 10.0.0.2
Adjust ring buffer sizes for red interface:
sudo ethtool -G eth0 rx 4096 tx 4096
Solución de Problemas
Diagnose common WireGuard issues.
Habilita debug logging:
sudo modprobe wireguard
sudo echo "module wireguard +p" > /sys/kernel/debug/dynamic_debug/control
journalctl -u systemd-modules-load -xe
Verifica interface is up:
ip link show dev wg0
ip addr show dev wg0
Prueba connectivity through WireGuard:
ping -c 4 10.0.0.2
traceroute 10.0.0.2
mtr 10.0.0.2
Check open puertos:
sudo ss -ulnp | grep wireguard
sudo netstat -ulnp | grep 51820
View WireGuard status details:
sudo wg show all
sudo wg show wg0 peers
sudo wg show wg0 allowed-ips
Verifica pre-shared key if configured:
sudo cat /etc/wireguard/wg0.conf | grep -i preshared
Check firewall rules:
sudo iptables -L INPUT -n | grep 51820
sudo iptables -L FORWARD -n | grep wg
sudo ufw status
Conclusión
WireGuard proporciona a modern, efficient VPN solution for site-to-site connectivity with minimal overhead and strong cryptographic security. By following this guide, you've generated cryptographic keys, configured peer relationships, set up direct site-to-site tunnels, implemented routing for transparent access to remote redes, integrated firewall rules, deployed persistent keepalive for NAT traversal, and built mesh redes with multiple sites. WireGuard's simplicity and performance make it ideal for connecting infrastructure, data centers, and branch offices. Regular monitoring and security updates asegúrate de que continued reliable operation of your site-to-site red infrastructure.


