Problema

En entornos de homelab o pequeñas infraestructuras, es frecuente que el mismo servidor aloje varios servicios críticos: asignación de direcciones IP (DHCP), resolución de nombres (DNS), directorio de usuarios (LDAP) y autenticación de red (RADIUS). Cuando se intenta consolidar todo en un nodo Proxmox, aparecen síntomas como:

  • Clientes que no reciben dirección IP o la reciben con parámetros incorrectos.
  • Resolución de nombres que falla intermitentemente.
  • Fallos de autenticación en Wi‑Fi o VPN porque el servidor RADIUS no puede consultar LDAP.
  • Contenedores que pierden conectividad tras reinicios del host.

El patrón es claro: varios servicios comparten puertos, dependencias de red y archivos de configuración que pueden colisionar si no se aislan correctamente. El reto es montar cada servicio de forma que sea fácil de mantener, escalar y, sobre todo, que no interfiera con el resto.

Causa

  1. Puertos en conflicto – DHCP (puerto 67/68), DNS (53), LDAP (389/636) y RADIUS (1812/1813) son servicios de red que, por defecto, escuchan en todas las interfaces del host. Si varios contenedores intentan abrir el mismo puerto, el kernel devuelve “address already in use”.

  2. Redes superpuestas – Proxmox crea puentes (vmbr0, vmbr1, …) y, a veces, los contenedores se conectan a la misma subred que el host. Cuando el host también actúa como router o firewall, el tráfico puede ser enrutado dos veces, provocando pérdida de paquetes.

  3. Persistencia de datos – Los archivos de zona DNS, bases de datos LDAP o configuraciones de RADIUS se guardan en volúmenes temporales si no se define un almacenamiento persistente. Reiniciar el nodo borra la información y los clientes quedan sin servicio.

  4. Orden de arranque – Servicios que dependen de otros (RADIUS → LDAP) pueden iniciar antes de que su backend esté disponible, generando errores de autenticación al arranque del nodo.

Solución

La estrategia más robusta combina aislamiento por contenedor LXC, redes puenteadas dedicadas y volúmenes persistentes. El flujo general es:

  1. Crear una red interna exclusiva para los servicios de infraestructura. Un puente (vmbr10) con una subred privada (ej. 10.10.10.0/24) evita colisiones con la red pública del host.

  2. Desplegar cada servicio en su propio contenedor LXC. Cada contenedor recibe una IP estática dentro de la subred interna y expone solo los puertos necesarios al puente.

  3. Montar volúmenes host en cada contenedor para bases de datos y archivos de configuración. Así, los datos sobreviven a reinicios del contenedor o del nodo Proxmox.

  4. Configurar dependencias mediante systemd‑units que esperen a los sockets de los servicios requeridos antes de iniciar.

  5. Abrir los puertos del host solo en el puente interno. Si se necesita acceso externo (por ejemplo, clientes Wi‑Fi que usan RADIUS), se crea una regla NAT que redirija el tráfico del host a la IP del contenedor correspondiente.

Paso a paso

1. Definir la red interna

# Crear el puente vmbr10 sin conexión a la red física
pvesh create /nodes/$(hostname)/network -iface vmbr10 -type bridge -autostart 1 -bridge_ports none -bridge_vlan_aware 0
# Asignar la subred 10.10.10.0/24
pvesh set /nodes/$(hostname)/network/vmbr10 -address 10.10.10.1/24

2. Crear contenedores LXC

# Plantilla Debian 12 (o la que prefieras)
pct create 101 local:vztmpl/debian-12-standard_12.0-1_amd64.tar.gz -net0 name=eth0,bridge=vmbr10,ip=10.10.10.101/24,gw=10.10.10.1 -storage local-lvm -rootfs local-lvm:8 -unprivileged 1
pct create 102 local:vztmpl/debian-12-standard_12.0-1_amd64.tar.gz -net0 name=eth0,bridge=vmbr10,ip=10.10.10.102/24,gw=10.10.10.1 -storage local-lvm -rootfs local-lvm:8 -unprivileged 1
pct create 103 local:vztmpl/debian-12-standard_12.0-1_amd64.tar.gz -net0 name=eth0,bridge=vmbr10,ip=10.10.10.103/24,gw=10.10.10.1 -storage local-lvm -rootfs local-lvm:8 -unprivileged 1
pct create 104 local:vztmpl/debian-12-standard_12.0-1_amd64.tar.gz -net0 name=eth0,bridge=vmbr10,ip=10.10.10.104/24,gw=10.10.10.1 -storage local-lvm -rootfs local-lvm:8 -unprivileged 1

Asignamos:

  • 101 → DHCP
  • 102 → DNS
  • 103 → LDAP
  • 104 → RADIUS

3. Montar volúmenes persistentes

# Crear directorios en el host
mkdir -p /srv/dhcp /srv/dns /srv/ldap /srv/radius

# Vincularlos a los contenedores
pct set 101 -mp0 /srv/dhcp,mp=/etc/dhcp
pct set 102 -mp0 /srv/dns,mp=/etc/bind
pct set 103 -mp0 /srv/ldap,mp=/etc/ldap
pct set 104 -mp0 /srv/radius,mp=/etc/raddb

4. Instalar y configurar cada servicio

Dentro de cada contenedor, instalar el paquete correspondiente (isc-dhcp-server, bind9, slapd, freeradius). Configurar los archivos apuntando a la IP estática asignada y, en el caso de RADIUS, indicar el DN y la contraseña del LDAP.

Ejemplo de dhcpd.conf (contenedor 101):

subnet 10.10.10.0 netmask 255.255.255.0 {
    range 10.10.10.150 10.10.10.200;
    option routers 10.10.10.1;
    option domain-name-servers 10.10.10.102;
    option domain-name "lan.local";
}

En el contenedor LDAP, crear la base dc=lan,dc=local y añadir usuarios que RADIUS consumirá.

5. Orquestar dependencias con systemd

En el contenedor RADIUS (/etc/systemd/system/radius.service):

[Unit]
Description=FreeRADIUS daemon
After=network.target slapd.service
Wants=slapd.service

[Service]
ExecStart=/usr/sbin/radiusd -X
Restart=on-failure

[Install]
WantedBy=multi-user.target

Esto garantiza que RADIUS solo arranca cuando LDAP está activo.

6. Exponer puertos al exterior (opcional)

# Redirigir tráfico del host al contenedor RADIUS
iptables -t nat -A PREROUTING -p udp --dport 1812 -j DNAT --to-destination 10.10.10.104:1812
iptables -t nat -A POSTROUTING -s 10.10.10.0/24 -j MASQUERADE

Repite la regla para los puertos 67/68 (DHCP) y 53 (DNS) si necesitas que clientes fuera de la subred interna los usen.

Cuándo aplicar esta solución

  • Entornos mixtos donde varios servicios de red deben coexistir en un mismo nodo físico.
  • Pequeñas empresas o homelabs que buscan reducir hardware sin sacrificar aislamiento.
  • Escenarios de alta disponibilidad donde cada contenedor puede migrarse a otro nodo Proxmox sin perder configuración.

No es apropiado cuando:

  • La carga de cada servicio supera la capacidad de un solo nodo (p.ej., cientos de miles de usuarios LDAP).
  • Se requiere integración con sistemas Windows AD que demandan controladores de dominio dedicados.

Código

# Creación del puente interno
pvesh create /nodes/$(hostname)/network -iface vmbr10 -type bridge -autostart 1 -bridge_ports none -bridge_vlan_aware 0
pvesh set /nodes/$(hostname)/network/vmbr10 -address 10.10.10.1/24

# Contenedores LXC
pct create 101 local:vztmpl/debian-12-standard_12.0-1_amd64.tar.gz -net0 name=eth0,bridge=vmbr10,ip=10.10.10.101/24,gw=10.10.10.1 -storage local-lvm -rootfs local-lvm:8 -unprivileged 1
pct create 102 local:vztmpl/debian-12-standard_12.0-1_amd64.tar.gz -net0 name=eth0,bridge=vmbr10,ip=10.10.10.102/24,gw=10.10.10.1 -storage local-lvm -rootfs local-lvm:8 -unprivileged 1
pct create 103 local:vztmpl/debian-12-standard_12.0-1_amd64.tar.gz -net0 name=eth0,bridge=vmbr10,ip=10.10.10.103/24,gw=10.10.10.1 -storage local-lvm -rootfs local-lvm:8 -unprivileged 1
pct create 104 local:vztmpl/debian-12-standard_12.0-1_amd64.tar.gz -net0 name=eth0,bridge=vmbr10,ip=10.10.10.104/24,gw=10.10.10.1 -