4.4 KiB
WireGuard en Kubernetes (wg-easy)
Este despliegue proporciona acceso VPN mediante WireGuard dentro de un clúster Kubernetes, utilizando la imagen wg-easy, expuesto por un Service tipo NodePort y gestionado con reglas de iptables en el host.
🔐 ¿Qué es WireGuard?
WireGuard es un protocolo de VPN moderno, rápido y seguro, que utiliza criptografía de última generación para establecer túneles cifrados entre dispositivos.
Este despliegue usa wg-easy, una interfaz web y API para administrar fácilmente instancias de WireGuard.
⚖️ Estructura del despliegue
.
├── daemonset
│ └── iptables-daemonset.yaml # Reglas de NAT
├── deployments
│ └── deployment.yaml # Despliegue de wg-easy
├── ingress
│ └── ingress.yaml # (opcional)
├── pvc
│ └── pvc.yaml # Configuración persistente
├── services
│ └── service.yaml # Service tipo NodePort
├── secret.yaml # HASH de contraseña para interfaz web
├── namespace.yaml
└── kustomization.yaml
🚫 Seguridad y acceso
Contraseña
Para acceder a la interfaz web protegida de wg-easy, se define un Secret con un hash de contraseña.
Puedes generar el hash con htpasswd (instalado con apache2-utils):
apt install apache2-utils
htpasswd -nBC 10 "admin"
Copia el resultado (sin el admin:) en el archivo secret.yaml como PASSWORD_HASH.
📁 Volúmenes
La configuración de WireGuard se guarda en /etc/wireguard dentro del contenedor. Esto se monta con un PersistentVolumeClaim para que los peers se conserven aunque se reinicie el pod.
🛂 Puertos y exposición
El Service es tipo NodePort, lo que significa:
-
Puerto del contenedor WireGuard:
51820/UDP -
Puerto de la interfaz web:
51821/TCP -
Puerto
NodePortexpuesto:- UDP:
31820(WireGuard) - TCP:
31821(Interfaz Web)
- UDP:
Los NodePort deben estar en el rango 30000–32767 (por defecto en Kubernetes).
El router debe redirigir estos puertos al nodo donde corre wg-easy.
Ejemplo de reenvío:
31820/UDP→ nodotartaro, puerto3182031821/TCP→ nodotartaro, puerto31821
🚀 Reenvío de tráfico y NAT
WireGuard entrega a los clientes direcciones como 192.168.200.x, pero por defecto no tendrían acceso a otras redes como:
- Red de administración:
192.168.1.0/24 - Red de pods (Flannel):
10.42.0.0/16 - Red Multus (ejemplo):
192.168.201.0/24
Para ello, se despliega un DaemonSet que aplica reglas iptables directamente en el host físico:
iptables -t nat -A POSTROUTING -s 192.168.200.0/24 -d 192.168.1.0/24 -j MASQUERADE
iptables -t nat -A POSTROUTING -s 192.168.200.0/24 -d 10.42.0.0/16 -j MASQUERADE
Con esto, los paquetes generados por los clientes WireGuard se traducen a la IP del host, y así acceden a otras redes internas.
🛠️ Acceso a redes aisladas con Multus
Si se desea permitir acceso a una red definida por un NetworkAttachmentDefinition (NAD) con Multus, como por ejemplo:
apiVersion: "k8s.cni.cncf.io/v1"
kind: NetworkAttachmentDefinition
metadata:
name: br-servicios
namespace: default
spec:
config: '{
"cniVersion": "0.3.1",
"type": "bridge",
"bridge": "br-servicios",
"ipam": {
"type": "host-local",
"subnet": "192.168.201.0/24",
"rangeStart": "192.168.201.100",
"rangeEnd": "192.168.201.199"
}
}'
Entonces basta con añadir una regla más en el DaemonSet:
iptables -t nat -A POSTROUTING -s 192.168.200.0/24 -d 192.168.201.0/24 -j MASQUERADE
No es necesario conectar el contenedor de wg-easy directamente a esta red: el tráfico se enruta y NATea desde el host físico.
🔄 Reaplicar cambios
Siempre que modifiques el DaemonSet o el Deployment, puedes aplicar los cambios con:
kubectl apply -k .
✨ Resultado
Una vez desplegado y con el reenvío del router correctamente configurado, puedes acceder a la interfaz web en:
https://manabo.org:31821
Y configurar tus clientes WireGuard escaneando el QR generado, o descargando el archivo de configuración.
Los clientes podrán acceder a:
192.168.1.0/24(red local)10.42.0.0/16(pods del clúster)192.168.201.0/24(red multus, si se añade la regla correspondiente)