J'ai un serveur OpenVPN configuré pour accepter 32 clients. Un script est lancé lors de la connexion / déconnexion du client afin d'effectuer de la configuration particulière. Ces scripts lancent eux-mêmes des commandes. En réalité, je n'ai pas un serveur, mais 8 (la justification est exposée ici) : 2 protocoles IP (v4 et v6) x 2 adresses IP x 2 protocoles de transmission (UDP et TCP).
Je constate que les OpenVPN les plus utilisés (UDP v4) crashent : leur état dans systemd est « failure ». De prime abord, il n'y a rien dans le journal. Je constate que cela se produit suite à une coupure partielle ou totale de mon accès à Internet. Un jour, j'arrive enfin à choper une erreur dans le journal : « openvpn_execve: unable to fork: Resource temporarily unavailable (errno=11) Exiting due to fatal error ».
Cette erreur est la conséquence de l'atteinte du nombre maximal de processus qu'un utilisateur peut avoir simultanément (ulimit -p
). Dans une unit systemd, cela est représenté sous cette forme :
$ sudo systemctl show openvpn@.service | grep -i NPROC
LimitNPROC=10
LimitNPROCSoft=10
Mes VPN sont tous exécutés avec les droits de l'utilisateur « openvpn ». J'ai donc 8 processus (les 8 instances OpenVPN). Il reste une marge de deux processus. Or, un utilisateur qui se connecte les occupe puisqu'un script est lancé (9) et que ce script lance lui-même plusieurs commandes de manière séquentielle (10). Je peux donc avoir un seul utilisateur qui se connecte en même temps : au-delà, la limite est atteinte et OpenVPN se ferme suite à cette erreur qu'il estime être fatale. Or, lors du rétablissement de ma connexion à Internet, plus d'un utilisateur tente de se reconnecter automatiquement en même temps, ce qui explique que la limite est plus fréquemment atteinte à ces moments-là. C'est un problème connu des devs OpenVPN.
Pour résoudre ça, je pourrais changer la valeur de « LimitNPROC » dans l'unit systemd d'OpenVPN, mais je vais se retrouver avec une valeur sur-dimensionnée donc aucun contrôle effectif du nombre de processus. Je pourrais augmenter la valeur de « LimitNPROC » tout en limitant le nombre de tâches au sein d'une même unit systemd, c'est-à-dire au sein d'une même instance OpenVPN, car ce nombre-ci est connu : j'ai 32 clients OpenVPN au maximum par instance, et cela repose sur une limite physique : le nombre d'IPv4 disponible. Pour mettre cela en pratique, j'ai ajouté et modifié ce qui suit dans /etc/systemd/system/openvpn.service
(qui est le fichier /lib/systemd/system/openvpn@.service
dupliqué) :
LimitNPROC=3897
LimitNPROCSoft=3897
TasksAccounting=yes
TasksMax=30
Pour que cela fonctionne, il faudra d'abord annihiler le générateur d'units systemd livré par le paquet OpenVPN.