extraccion de DNS/ revision de ACLs

This commit is contained in:
2025-08-22 18:01:14 +02:00
parent bf44ad9c1d
commit 663d6422fc
28 changed files with 755 additions and 154 deletions

View File

@@ -1,168 +1,208 @@
# CoreDNS con Multus: README de Configuración
# CoreDNS dedicado para DNS interno / splithorizon
Este documento explica cómo desplegar un pod de CoreDNS en Kubernetes con **Multus CNI** para conectarlo a dos redes físicas (bridges) distintas, asignándole una dirección IP en cada una, y usando `hostNetwork` para exponer el servicio DNS de forma estándar en el host.
Este directorio contiene los manifiestos para desplegar un **CoreDNS propio** (namespace `coredns`) que sirve como **DNS interno** para resoluciones splithorizon y control de rutas en la VPN (splittunnel).
Con este CoreDNS:
* Los FQDN internos (p. ej. `portal.apolo.c2et.net`) **resuelven a la VIP interna** `192.168.200.10` cuando el cliente usa el DNS interno `192.168.200.11` → el tráfico va por la VPN/LAN.
* Los FQDN “externos” (p. ej. `admin.firewall.c2et.net`) pueden **apuntar a la VIP pública** `192.168.0.100` desde el mismo DNS interno (útil para pruebas) o gestionarse sólo en el DNS público.
* El resto de nombres **se reenvían** a los resolvers del nodo (`/etc/resolv.conf`).
---
## Objetivo
## Estructura
* Desplegar CoreDNS con:
* IP 192.168.1.100/24 en la red **br-admin**
* IP 192.168.200.100/22 en la red **br-srv**
* Utilizar `hostNetwork: true` para que CoreDNS escuche en el puerto 53 real del host
* Añadir un sidecar de herramientas para inspección de red
---
## ¿Por qué Multus?
* Kubernetes estándar solo permite una interfaz por pod (la principal).
* Multus permite añadir interfaces **adicionales**, conectando el pod a varias redes físicas (como bridges de Linux).
* En este caso, usamos Multus para asignar a CoreDNS dos IPs fijas en dos bridges diferentes, actuando como DNS en ambas redes.
---
## Componentes principales
1. **NetworkAttachmentDefinition** para cada bridge físico:
* `br-admin` (192.168.1.0/24)
* `br-srv` (192.168.200.0/22)
2. **ConfigMap** con el `Corefile` (configuración de CoreDNS)
3. **Pod** con:
* `hostNetwork: true`
* Anotación Multus para conectar ambas redes
* Sidecar de utilidades (`busybox`)
---
## Paso a paso
### 1. NetworkAttachmentDefinition
Define una NetworkAttachmentDefinition por red, ejemplo:
`br-admin.yaml`:
```yaml
apiVersion: "k8s.cni.cncf.io/v1"
kind: NetworkAttachmentDefinition
metadata:
name: br-admin
namespace: coredns-multus
spec:
config: '{
"cniVersion": "0.3.1",
"type": "bridge",
"bridge": "br-admin",
"ipam": {
"type": "static",
"addresses": [
{
"address": "192.168.1.100/24",
"gateway": "192.168.1.1"
}
]
}
}'
```
`br-srv.yaml` igual, cambiando nombre y dirección IP.
---
### 2. ConfigMap con Corefile
Ejemplo:
```yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: coredns-config
namespace: coredns-multus
data:
Corefile: |
.:53 {
log
errors
forward . 8.8.8.8
cache 30
}
./coredns
├── configmap-coredns.yaml # Corefile con hosts, forward y cache
├── deploy-coredns.yaml # Deployment (réplicas, probes y mounts)
├── kustomization.yaml # Kustomize para aplicar todo el conjunto
├── namespace.yaml # Namespace dedicado: coredns
└── svc-coredns.yaml # Service LoadBalancer (UDP/TCP 53) → 192.168.200.11
```
---
### 3. Pod con Multus y sidecar de utilidades
## Despliegue
```yaml
apiVersion: v1
kind: Pod
metadata:
name: coredns-multus
namespace: coredns-multus
annotations:
k8s.v1.cni.cncf.io/networks: |
[
{ "name": "br-admin", "namespace": "coredns-multus" },
{ "name": "br-srv", "namespace": "coredns-multus" }
]
spec:
hostNetwork: true
containers:
- name: coredns
image: coredns/coredns:1.11.1
volumeMounts:
- name: config-volume
mountPath: /etc/coredns/Corefile
subPath: Corefile
ports:
- containerPort: 53
protocol: UDP
- containerPort: 53
protocol: TCP
- name: tools
image: busybox
command: [ "sleep", "infinity" ]
volumes:
- name: config-volume
configMap:
name: coredns-config
tolerations:
- operator: "Exists"
dnsPolicy: "Default"
> Requisitos: MetalLB operativo en la red 192.168.200.0/24 para anunciar `192.168.200.11`.
```bash
# Desde ./kubernetes/coredns
kubectl apply -k .
# Verificar
kubectl -n coredns get all
kubectl -n coredns get svc coredns-custom -o wide # Debe mostrar External IP: 192.168.200.11
kubectl -n coredns logs deploy/coredns-custom -f # Comprobar health/errores
```
---
## Comprobación de las interfaces
Desplegar:
```sh
kubectl apply -k . #<-- (hay un kustomization en la carpeta coredns del repositorio)
```
---
## Comprobación de las interfaces
## Configuración (Corefile)
Para ver las interfaces asignadas por Multus:
El Corefile se define en `configmap-coredns.yaml`:
```sh
kubectl -n coredns-multus exec -it coredns-multus -c tools -- ip a
```coredns
.:53 {
log
errors
health
reload
hosts {
# === APOLO (GPS táctico) ===
192.168.200.10 backend.apolo.c2et.net
192.168.200.10 portal.apolo.c2et.net
192.168.200.10 colossus.apolo.c2et.net
192.168.200.13 chat.apolo.c2et.net
192.168.200.13 muc.chat.apolo.c2et.net
192.168.200.12 streaming.apolo.c2et.net
192.168.200.14 meeting.apolo.c2et.net
# === ARGOS (videovigilancia) ===
192.168.200.15 mqtt.argos.interna
192.168.200.16 mediamtx.argos.interna
192.168.200.10 s3.argos.interna
192.168.200.10 minio.argos.interna
192.168.200.10 panel.argos.c2et.net
# === External ===
192.168.0.100 admin.firewall.c2et.net
192.168.0.100 k8s.c2et.net
192.168.0.100 admin.powervault1.c2et.net
192.168.0.100 admin.powervault2.c2et.net
192.168.0.100 ceph.c2et.net
fallthrough
}
forward . /etc/resolv.conf
cache 120
# prometheus 0.0.0.0:9153 # (opcional) exportar métricas
}
```
Deberías ver:
### Puntos clave
* La interfaz principal (del host, por `hostNetwork`)
* Una interfaz extra con IP 192.168.1.100
* Otra interfaz extra con IP 192.168.200.100
* **`hosts`**: mapa de FQDN → IP (A/AAAA estáticos). Añade/edita aquí tus entradas internas.
* **`fallthrough`**: si un nombre no está en `hosts`, la consulta pasa al siguiente plugin.
* **`forward . /etc/resolv.conf`**: reenvía el resto de consultas a los resolvers del nodo.
* **`cache 120`**: cache de respuestas para mejorar latencia.
* **`reload`**: CoreDNS recarga el Corefile cuando cambia el ConfigMap montado.
> Modificar el Corefile ⇒ `kubectl -n coredns apply -f configmap-coredns.yaml` (CoreDNS recarga solo). Si fuera necesario, un `rollout restart` del deployment.
---
## Notas importantes
## Integración con la VPN (splittunnel)
* `hostNetwork: true` expone el puerto 53 real en el host.
* La IP principal será la del host, las secundarias las de Multus.
* Puedes poner el pod en modo Deployment para alta disponibilidad, pero solo una instancia por host con `hostNetwork: true`.
* El sidecar puede eliminarse después de la verificación, no es necesario para producción.
Para que los clientes usen las VIP internas cuando están en la VPN:
1. **Empuja el DNS interno por la VPN**:
* DNS del cliente: `192.168.200.11` (este Service).
* Asegúrate de que la interfaz de la VPN enruta el DNS interno (por ejemplo con `AllowedIPs = 192.168.200.11/32` en WireGuard).
2. **Splithorizon**: este CoreDNS responde con IPs internas (192.168.200.x). Si el cliente no usa este DNS, resolverá contra el público y saldrá por Internet (lo cual está bien si quieres que el Ingress lo bloquee por whitelist).
3. **Ingressnginx** (contexto relacionado):
* Services del controller con `externalTrafficPolicy: Local` para preservar IP origen.
* Anotación de whitelist en los Ingress de apps: sólo redes permitidas (LAN/VPN), por ejemplo:
```yaml
nginx.ingress.kubernetes.io/whitelist-source-range: "192.168.200.0/24,192.168.0.0/24,192.168.4.0/24"
```
* Evitar abrir `10.244.0.0/16`. Si tu gateway VPN es un Pod y el Ingress ve IP de Pod, permitir **sólo su /32** o mover la VPN a `hostNetwork: true` para usar IP estable del nodo.
---
## Operación
### Escalado y HA
* `deploy-coredns.yaml` fija `replicas: 2` con probes de liveness/readiness.
* El Service `LoadBalancer` (UDP/TCP 53) anuncia **192.168.200.11** vía MetalLB.
### Actualizar entradas
1. Edita `configmap-coredns.yaml` (bloque `hosts`).
2. `kubectl -n coredns apply -f configmap-coredns.yaml`.
3. Verifica con consultas (ver abajo).
### Reinicio controlado (si lo precisas)
```bash
kubectl -n coredns rollout restart deploy/coredns-custom
kubectl -n coredns rollout status deploy/coredns-custom
```
### Métricas (opcional)
* Descomenta la línea `prometheus 0.0.0.0:9153` y expón un `ServiceMonitor` si usas Prometheus.
---
## Pruebas y verificación
### Resolución directa contra CoreDNS interno
```bash
# Desde un cliente en VPN/LAN
nslookup portal.apolo.c2et.net 192.168.200.11
nslookup admin.firewall.c2et.net 192.168.200.11
# o con dig
dig +short portal.apolo.c2et.net @192.168.200.11
```
Resultado esperado: `portal.apolo.c2et.net` → `192.168.200.10`.
### Camino por la VIP interna (SNI correcto)
```bash
curl -I https://portal.apolo.c2et.net \
--resolve portal.apolo.c2et.net:443:192.168.200.10
```
### Logs de CoreDNS e Ingress
```bash
# CoreDNS
kubectl -n coredns logs deploy/coredns-custom -f | grep -iE "error|timeout"
# Ingress (para ver IP origen preservada)
kubectl -n ingress-nginx logs -l app.kubernetes.io/name=ingress-nginx --tail=100
```
---
## Mantenimiento y buenas prácticas
* Versiona cambios en `hosts` y acompaña con una nota de por qué se enruta cada FQDN a cada VIP.
* Mantén separadas las entradas **internas** (192.168.200.x) y las **externas** (192.168.0.100) para claridad.
* Si la VPN está en Pods y rota IPs, considera moverla a `hostNetwork: true` o asignarle IP estática (Multus) para whitelistear un **/32** estable en Ingress.
* Revisa periódicamente que MetalLB siga anunciando `192.168.200.11` y que no haya conflictos ARP en la red.
---
## Comandos útiles
```bash
# Aplicar todo
kubectl apply -k .
# Ver estado
kubectl -n coredns get pods -o wide
kubectl -n coredns get svc coredns-custom -o wide
# Probar resolución desde un Pod del clúster
kubectl -n coredns run -it --rm dnsutils --image=ghcr.io/k8s-at-home/dnsutils:latest -- sh -lc \
"dig portal.apolo.c2et.net @192.168.200.11 +short"
```
---
## Notas
* Este CoreDNS **no sustituye** al CoreDNS del clúster para kubeservices; su objetivo es servir **nombres internos de la organización** y controlar el camino de acceso (VPN/LAN vs. Internet).
* Si necesitas TTLs personalizados en respuestas estáticas, puedes extender el bloque `hosts` con opciones (TTL, etc.).