FreeBind face à After= : lier un socket systemd à une adresse VPN
FreeBind permet à systemd de posséder l’écouteur avant que l’adresse VPN existe ; After= ne fait qu’ordonner les tâches. Comparez-les, puis testez l’ordre et la disponibilité.
Au démarrage, une unité socket qui lie une adresse VPN fixe peut échouer avant que le tunnel ne l’ait attribuée, et le service derrière elle ne démarre jamais. Deux commutateurs ressemblent à des correctifs et résolvent des moitiés différentes de ce problème. FreeBind permet à systemd de créer l’écouteur alors que l’adresse est encore absente. After= ne fait qu’ordonner les tâches : il change quand les choses démarrent sans faire arriver l’adresse plus tôt.
Deux problèmes différents, deux commutateurs différents
Le premier problème est un échec de liaison : le noyau refuse d’écouter sur une adresse que l’hôte ne possède pas, donc l’unité socket échoue immédiatement et le service n’est jamais activé. Le second problème est un échec de disponibilité : l’adresse finit par exister, mais quelque chose tente de l’utiliser avant que le tunnel ne transporte du trafic. FreeBind traite le premier et ne fait rien pour le second. Les directives d’ordre ne traitent ni l’un ni l’autre directement, car elles décident seulement de ce qui démarre et dans quel ordre. Nommer l’échec que vous avez réellement est toute la décision.
Confirmez lequel des deux vous avez dans le journal, et non dans la description du service. Un échec de liaison nomme une adresse et signale qu’elle ne peut pas être attribuée. Un échec de disponibilité apparaît généralement plus tard, sous forme de délai dépassé ou de connexion refusée vue de l’autre côté, avec une unité socket parfaitement saine dans les journaux.
FreeBind : l’écouteur existe avant l’adresse
FreeBind dit au noyau d’autoriser une liaison à une adresse non locale, afin que systemd puisse créer le socket d’écoute au démarrage et le remettre à l’application chaque fois que celle-ci démarre. C’est le sens de l’activation par socket, et la raison pour laquelle le socket peut survivre au service derrière lui.
[Socket]
ListenStream=
ListenStream=10.8.0.1:8443
FreeBind=yes
L’affectation vide efface les entrées d’écoute héritées de l’unité du fournisseur avant que la nouvelle ne soit ajoutée, ce qui empêche un écouteur générique restant de répondre sur toutes les interfaces. Remplacez l’adresse et le port par les vôtres et vérifiez l’unité effective, pas seulement le fichier drop-in. Utilisez un drop-in sous le nom de l’unité au lieu de modifier un fichier de paquet sur place, car la prochaine mise à jour du paquet écrasera la modification et ne laissera aucune trace de l’intention. Appliquez-le ensuite via la procédure de rechargement et de redémarrage attendue par l’unité socket.
La référence des sockets systemd documente le comportement IPv4 et IPv6 derrière cette option, et le détail important est qu’elle s’applique à la liaison et non au routage. Rien n’y attribue d’adresse ni ne démarre de VPN. FreeBind est une autorisation accordée à l’écouteur, non un remplacement de l’interface.
After= et Wants= : l’ordre n’est pas la disponibilité
L’ordre et l’exigence sont des axes distincts, et les confondre produit des unités qui démarrent dans le bon ordre et échouent quand même. After=vpn-client.service signifie seulement que, si les deux tâches sont démarrées, celle-ci attend que l’autre soit démarrée. Il n’entraîne pas le VPN et n’attend pas que le VPN finisse de se connecter.
Les directives d’exigence comme Wants= et Requires= gèrent l’activation et diffèrent par ce qui se passe quand la dépendance échoue : l’une continue, l’autre s’arrête. Aucune des deux ne sait ce que signifie un tunnel connecté. Un processus VPN peut être actif sans adresse attribuée, ou avec une adresse attribuée et sans route vers le pair, et les deux états satisfont la dépendance. Si l’application a besoin que l’adresse existe, modélisez cette condition explicitement au lieu de traiter le démarrage du processus comme une preuve de disponibilité.
Vérifiez ce que l’unité déclare réellement avec systemctl cat et systemctl show -p After -p Wants -p Requires. Des drop-in provenant de trois répertoires différents peuvent ajouter des directives que vous n’avez jamais écrites, et l’unité effective est la seule chose que systemd lit.
Ce que network-online.target ne fait pas
Une unité ordonnée après network-online.target attend que le gestionnaire de réseau déclare le réseau utilisable, ce qui est un point de synchronisation au démarrage et non une condition continue. Elle ne dit rien sur le fait qu’un tunnel précis soit monté, et elle ne se déclenchera pas de nouveau lorsqu’un VPN se reconnecte au milieu de l’après-midi. La traiter comme un moniteur de reconnexion est la mauvaise lecture la plus courante de cette cible.
Le projet systemd documente directement cette distinction, et la conséquence pratique est que tout ce qui a besoin d’une adresse de tunnel doit posséder la dépendance lui-même. Une unité qui attend network-online puis lie une adresse de tunnel n’est correcte que lorsque le tunnel monte d’abord par hasard, ce qui est une coïncidence et non une conception.
Testez le cycle de vie que vous avez réellement choisi
Testez un démarrage propre, une requête après l’apparition de l’adresse, et le comportement après que le VPN tombe et revient. Ces trois cas séparent un écouteur fonctionnel d’un service fonctionnel.
systemd-analyze verify myapp.socket
systemctl cat myapp.socket
ss -ltn "sport = :8443"
La première commande attrape les erreurs du fichier d’unité avant un redémarrage, la deuxième montre l’unité fusionnée, et la troisième prouve si l’écouteur existe et sur quelle adresse. Un écouteur sur une adresse générique là où vous attendiez une adresse de tunnel est exactement le résidu que le ListenStream vide devait supprimer. Répétez la troisième commande après une reconnexion du VPN pour voir si l’adresse a bougé.
Choisissez le cycle de vie délibérément : soit un écouteur lié librement qui attend le retour d’une adresse stable, soit un service qui s’arrête avec le tunnel et redémarre à la reprise. Ce sont des conceptions différentes et elles échouent de manières différentes. Gardez ensuite la politique d’accès liée aux sources et aux chemins que vous vouliez, car lier une adresse de destination n’exige pas que les paquets acceptés soient arrivés par une interface de confiance.