FreeBind frente a After=: enlazar un socket de systemd a una dirección VPN
FreeBind permite que systemd posea el oyente antes de que exista la dirección VPN; After= solo ordena tareas. Compárelos y luego pruebe el orden y la disponibilidad.
Al arrancar, una unidad de socket que enlaza una dirección VPN fija puede fallar antes de que el túnel se la haya asignado, y el servicio que hay detrás nunca arranca. Dos interruptores parecen soluciones y resuelven mitades distintas de ese problema. FreeBind permite que systemd cree el oyente mientras la dirección aún falta. After= solo ordena tareas, así que cambia cuándo empiezan las cosas sin hacer que la dirección llegue antes.
Dos problemas distintos, dos interruptores distintos
El primer problema es un fallo de enlace: el núcleo rechaza escuchar en una dirección que el host no posee, así que la unidad de socket falla de inmediato y el servicio nunca se activa. El segundo problema es un fallo de disponibilidad: la dirección existe al final, pero algo intenta usarla antes de que el túnel transporte tráfico. FreeBind aborda el primero y no hace nada por el segundo. Las directivas de orden no abordan ninguno directamente, porque solo deciden qué empieza y en qué secuencia. Nombrar el fallo que realmente tiene es toda la decisión.
Confirme cuál de los dos tiene en el registro, no en la descripción del servicio. Un fallo de enlace nombra una dirección e informa de que no se puede asignar. Un fallo de disponibilidad suele aparecer más tarde, como un tiempo de espera agotado o una conexión rechazada vista desde el otro lado, con una unidad de socket perfectamente sana en los registros.
FreeBind: el oyente existe antes que la dirección
FreeBind indica al núcleo que permita un enlace a una dirección no local, de modo que systemd puede crear el socket de escucha al arrancar y entregarlo a la aplicación siempre que esta se inicie. Ese es el sentido de la activación por socket y la razón por la que el socket puede sobrevivir al servicio que hay detrás.
[Socket]
ListenStream=
ListenStream=10.8.0.1:8443
FreeBind=yes
La asignación vacía borra las entradas de escucha heredadas de la unidad del proveedor antes de añadir la nueva, lo que evita que un oyente comodín sobrante responda en todas las interfaces. Sustituya la dirección y el puerto por los suyos y verifique la unidad efectiva, no solo el archivo drop-in. Use un drop-in con el nombre de la unidad en lugar de editar un archivo del paquete en su sitio, porque la siguiente actualización del paquete sobrescribirá la edición y no dejará rastro de la intención. Después aplíquelo mediante el procedimiento de recarga y reinicio que la unidad de socket espera.
La referencia de sockets de systemd documenta el comportamiento IPv4 e IPv6 detrás de esa opción, y el detalle importante es que se aplica al enlace y no al enrutamiento. Nada en ella asigna una dirección ni inicia una VPN. FreeBind es un permiso concedido al oyente, no un sustituto de la interfaz.
After= y Wants=: el orden no es disponibilidad
Orden y requisito son ejes separados, y confundirlos produce unidades que arrancan en el orden correcto y aun así fallan. After=vpn-client.service solo significa que, si ambas tareas se inician, esta espera a que la otra se haya iniciado. No arrastra la VPN y no espera a que la VPN termine de conectarse.
Las directivas de requisito como Wants= y Requires= gestionan la activación y difieren en qué ocurre cuando la dependencia falla: una continúa y la otra se detiene. Ninguna de las dos sabe qué significa un túnel conectado. Un proceso VPN puede estar activo sin dirección asignada, o con dirección asignada y sin ruta hacia el par, y ambos estados satisfacen la dependencia. Si la aplicación necesita que la dirección exista, modele esa condición de forma explícita en lugar de tratar el arranque del proceso como prueba de disponibilidad.
Compruebe qué declara realmente la unidad con systemctl cat y systemctl show -p After -p Wants -p Requires. Los drop-in de tres directorios distintos pueden añadir directivas que usted nunca escribió, y la unidad efectiva es lo único que systemd lee.
Qué no hace network-online.target
Una unidad ordenada después de network-online.target espera a que el gestor de red declare la red utilizable, lo que es un punto de sincronización del arranque y no una condición continua. No dice nada sobre si un túnel concreto está activo, y no se disparará de nuevo cuando una VPN se reconecte a media tarde. Tratarlo como un monitor de reconexión es la mala lectura más común de ese objetivo.
El proyecto systemd documenta esa distinción directamente, y la consecuencia práctica es que todo lo que necesite una dirección de túnel debe poseer la dependencia por sí mismo. Una unidad que espera network-online y luego enlaza una dirección de túnel solo es correcta cuando el túnel resulta subir primero, lo que es una casualidad y no un diseño.
Pruebe el ciclo de vida que realmente eligió
Pruebe un arranque limpio, una petición después de que aparezca la dirección y el comportamiento después de que la VPN caiga y vuelva. Esos tres casos separan un oyente funcional de un servicio funcional.
systemd-analyze verify myapp.socket
systemctl cat myapp.socket
ss -ltn "sport = :8443"
El primer comando detecta errores del archivo de unidad antes de un reinicio, el segundo muestra la unidad fusionada y el tercero demuestra si el oyente existe y en qué dirección. Un oyente en una dirección comodín donde esperaba una dirección de túnel es exactamente el resto que el ListenStream vacío debía eliminar. Repita el tercer comando tras una reconexión de la VPN para ver si la dirección se movió.
Elija el ciclo de vida a propósito: o un oyente enlazado libremente que espera el regreso de una dirección estable, o un servicio que se detiene con el túnel y arranca de nuevo al recuperarse. Son diseños distintos y fallan de formas distintas. Después mantenga la política de acceso ligada a las fuentes y rutas que pretendía, porque enlazar una dirección de destino no exige que los paquetes aceptados hayan llegado por una interfaz de confianza.