Automatiza el despliegue de un servidor WireGuard con Ansible: ¡VPN segura en minutos!
¿Te has planteado montar tu propia VPN pero te asusta la configuración manual, la gestión de claves o la seguridad? WireGuard es la reina de las VPN modernas: ligera, rápida, auditada y con un diseño elegante. Hoy vas a aprender cómo automatizar la instalación y la configuración de un servidor WireGuard en Linux con un solo playbook de Ansible. ¡Olvídate de tutoriales interminables y scripts a mano!
¿Qué resuelve este playbook?
- Instala WireGuard en tu servidor Linux (soportado para Debian, Ubuntu y derivados).
- Genera claves privadas y públicas de servidor y cliente.
- Configura el servicio de WireGuard con un túnel seguro y encriptado listo para funcionar.
- Activa el reenvío de IP y ajusta las reglas de firewall (ufw o iptables) para permitir el tráfico de la VPN.
- Genera automáticamente el archivo de configuración del cliente, para que solo tengas que importarlo en el móvil/portátil.
Playbook completo: ansible_wireguard_server.yml
¡Aquí tienes el playbook entero, explicado y listo para copiar!
---
- name: Instalar y configurar WireGuard VPN
hosts: wireguard_servers
become: true
vars:
wg_interface: wg0
wg_port: 51820
wg_network: "10.8.0.0/24"
wg_server_ip: "10.8.0.1"
wg_listen_port: 51820
wg_client_ip: "10.8.0.2"
wg_allowed_ips: "0.0.0.0/0"
wg_clients:
- name: usuario1
ip: "10.8.0.2"
tasks:
- name: Instalar WireGuard y herramientas necesarias
apt:
name:
- wireguard
- qrencode
state: present
update_cache: true
- name: Asegurarse de que el directorio de claves existe
file:
path: /etc/wireguard/keys
state: directory
owner: root
group: root
mode: 0700
- name: Generar clave privada del servidor
command: "wg genkey"
register: wg_server_private_key
args:
creates: /etc/wireguard/keys/server_private.key
- name: Guardar clave privada del servidor
copy:
content: "{{ wg_server_private_key.stdout }}"
dest: /etc/wireguard/keys/server_private.key
owner: root
group: root
mode: 0600
when: wg_server_private_key.stdout is defined
- name: Obtener clave privada del servidor
slurp:
src: /etc/wireguard/keys/server_private.key
register: server_private_key_file
- name: Generar clave pública del servidor
command: "echo '{{ server_private_key_file.content | b64decode }}' | wg pubkey"
register: wg_server_public_key
- name: Generar clave privada del cliente
command: "wg genkey"
register: wg_client_private_key
args:
creates: "/etc/wireguard/keys/{{ wg_clients[0].name }}_private.key"
- name: Guardar clave privada del cliente
copy:
content: "{{ wg_client_private_key.stdout }}"
dest: "/etc/wireguard/keys/{{ wg_clients[0].name }}_private.key"
owner: root
group: root
mode: 0600
when: wg_client_private_key.stdout is defined
- name: Obtener clave privada del cliente
slurp:
src: "/etc/wireguard/keys/{{ wg_clients[0].name }}_private.key"
register: client_private_key_file
- name: Generar clave pública del cliente
command: "echo '{{ client_private_key_file.content | b64decode }}' | wg pubkey"
register: wg_client_public_key
- name: Crear configuración del servidor WireGuard
template:
src: wireguard_server.conf.j2
dest: "/etc/wireguard/{{ wg_interface }}.conf"
owner: root
group: root
mode: 0600
- name: Habilitar el reenvío IP en el sistema
sysctl:
name: net.ipv4.ip_forward
value: "1"
state: present
reload: yes
- name: Permitir tráfico del puerto WireGuard
ufw:
rule: allow
port: "{{ wg_port }}"
proto: udp
- name: Habilitar y arrancar el servicio WireGuard
systemd:
name: "wg-quick@{{ wg_interface }}"
enabled: true
state: started
- name: Crear configuración del cliente WireGuard
template:
src: wireguard_client.conf.j2
dest: "/etc/wireguard/{{ wg_clients[0].name }}.conf"
owner: root
group: root
mode: 0600
- name: Mostrar configuración del cliente (para copiar)
debug:
msg: |
¡Archivo de configuración del cliente generado en /etc/wireguard/{{ wg_clients[0].name }}.conf!
Escanea el siguiente QR desde tu dispositivo móvil para importar el perfil:
{{ lookup('pipe', 'qrencode -t ansiutf8 < /etc/wireguard/' + wg_clients[0].name + '.conf') }}
Plantillas de configuración
Crea estos archivos Jinja2 en el mismo directorio que el playbook (wireguard_server.conf.j2
y wireguard_client.conf.j2
):
wireguard_server.conf.j2
[Interface]
Address = {{ wg_server_ip }}/24
ListenPort = {{ wg_port }}
PrivateKey = {{ server_private_key_file.content | b64decode }}
PostUp = ufw route allow in on {{ wg_interface }} out on eth0; iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
PostDown = ufw route delete allow in on {{ wg_interface }} out on eth0; iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE
[Peer]
PublicKey = {{ wg_client_public_key.stdout }}
AllowedIPs = {{ wg_client_ip }}/32
wireguard_client.conf.j2
[Interface]
PrivateKey = {{ client_private_key_file.content | b64decode }}
Address = {{ wg_client_ip }}/24
DNS = 1.1.1.1
[Peer]
PublicKey = {{ wg_server_public_key.stdout }}
Endpoint = {{ ansible_host }}:{{ wg_port }}
AllowedIPs = {{ wg_allowed_ips }}
PersistentKeepalive = 25
¡Disfruta de tu VPN privada en minutos!
Tras lanzar el playbook, tendrás:
- WireGuard instalado y corriendo en tu servidor.
- Claves y configuraciones generadas y seguras.
- Listo para copiar el archivo del cliente, ¡incluso con un QR para móvil!
Consejos extra y troubleshooting rápido
- Si el puerto UDP no se abre, revisa las
rules de ufw
o ejecutasudo ufw status
. - Comprueba que la IP de eth0 corresponda con la interfaz real de tu servidor (ajusta en las plantillas si usas otra).
- Para varios clientes, amplía la lista
wg_clients
y añade bloques[Peer]
en el server y[Interface]
para cada uno en el cliente. - ¿Problemas de conexión? Usa
journalctl -u wg-quick@wg0
para logs útiles.
¡Ahora puedes presumir de VPN propia y segura, y todo gracias a la magia de Ansible!