164 lines
4.7 KiB
Markdown
164 lines
4.7 KiB
Markdown
# 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-tcp.yaml # Service tipo clusterIP
|
|
│ └── service-udp.yaml # Service tipo LoadBalancer
|
|
├── 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`):
|
|
|
|
```bash
|
|
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
|
|
|
|
En el despliegue actual se utilizan **dos `Service` separados** para exponer WireGuard:
|
|
|
|
1. **Service para la interfaz web (TCP)**
|
|
|
|
* Tipo: `ClusterIP`
|
|
* Protocolo: `TCP`
|
|
* Puerto del contenedor: `51821`
|
|
* Exposición externa: mediante `Ingress` (nginx) con dominio HTTPS → `https://wireguard.c2et.net/`
|
|
|
|
2. **Service para WireGuard (UDP)**
|
|
|
|
* Tipo: `LoadBalancer` (MetalLB)
|
|
* Protocolo: `UDP`
|
|
* Puerto del contenedor: `51819`
|
|
* Puerto externo: asignado por MetalLB en la IP del balanceador.
|
|
|
|
### Esquema de acceso
|
|
|
|
* **Tráfico TCP** (Panel Web): entra por el `Ingress` Controller (nginx), con TLS gestionado por `cert-manager`.
|
|
* **Tráfico UDP** (VPN WireGuard): entra directamente a través de la IP asignada por MetalLB, sin pasar por `Ingress`.
|
|
|
|
---
|
|
|
|
## 🚀 Reenvío de tráfico y NAT
|
|
|
|
WireGuard entrega a los clientes direcciones como `192.168.254.x`, pero por defecto no tendrían acceso a otras redes como:
|
|
|
|
* Red de administración: `192.168.0.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:
|
|
|
|
```yaml
|
|
iptables -t nat -A POSTROUTING -s 192.168.254.0/24 -d 192.168.0.0/24 -j MASQUERADE
|
|
iptables -t nat -A POSTROUTING -s 192.168.254.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:
|
|
|
|
```yaml
|
|
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`:
|
|
|
|
```bash
|
|
iptables -t nat -A POSTROUTING -s 192.168.254.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:
|
|
|
|
```bash
|
|
kubectl apply -k .
|
|
```
|
|
|
|
---
|
|
|
|
## ✨ Resultado
|
|
|
|
Una vez desplegado y con el reenvío del router correctamente configurado, puedes acceder a la interfaz web en:
|
|
|
|
```
|
|
https://wireguard.c2et.net
|
|
```
|
|
|
|
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)
|
|
|
|
---
|
|
|