Gros casse-tête du soir.
On a un OpenVPN fonctionnel, qui gère IPv4, IPv6, TCP et UDP. Le tout avec deux instances c'est-à-dire deux processus OpenVPN distincts. Voir https://wiki.arn-fai.net/technique:vpn . Pour une raison sur laquelle je reviendrais plus tard, on décide d'éclater IPv4 et IPv6. On se retrouve donc avec 4 processus OpenVPN (udp v4, udp v6, tcpv4, tcpv6). Pour une autre raison, on a besoin de dupliquer ça, pour se bind() sur deux IP. On se retrouve donc avec 8 processus OpenVPN, 4 par IP, 2 udp v4, 2 udpv6, 2 tcpv4, 2 tcpv6.
On remarque un truc curieux : quand les 8 VPN sont en cours d'exécution, il n'est pas possible de se connecter à l'un d'eux : on obtient un AUTH_FAILED. Notre script lancé à la connexion d'un client (avec la directive « client-connect » d'OpenVPN) sort avec un code de retour = 2. On lance le script manuellement, avec les droits de l'utilisateur openvpn, ofc : ça fonctionne. On ajoute des affichages de debug et on constate que le script échoue sur la condition suivante :
if ! echo "$common_name" | grep '^[a-zA-Z][a-zA-Z0-9_-]*$'; then
log notice "Bad common name $common_name"
return 1
fi
On remarque que le echo fonctionne. C'est donc le « | grep » qui foire.
On remarque aussi qu'il suffit de n'avoir que 7 processus OpenVPN, n'importe lesquels et ça fonctionne. C'est vraiment le 8e processus qui fait foirer l'ensemble.
On remarque que si l'on ne réduit pas les privilèges, c'est-à-dire qu'on laisse OpenVPN s'exécuter en root, alors on n'a aucun problème.
Johndescs et b4n émettent l'hypothèse qu'une limite quelconque a été dépassée. J'avions aussi compris mais ulimit retourne « unlimited ». Du coup, quelle limite a été dépassée ? On remarque que les processus OpenVPN sont tous exécutés dans une même slice systemd. Ils sont les seuls à l'être. Si l'on change d'init ou que l'on lance nos 8 OpenVPN depuis le shell, on constate que nos 8 procesus OpenVPN cohabitent sans problèmes.
On regarde la templated unit systemd fournie dans le package OpenVPN (/lib/systemd/system/openvpn@.service ) :
LimitNPROC=10
Ho bah ça alors. On compte : 8 processus OpenVPN, 1 script, 1 echo, ça fait bien 10. Le shell ne peut donc pas se forker pour écraser son code par celui de grep.
Il suffit d'augmenter cette limite et c'est tout bon. \o/
Ensuite, on lit la doc' : https://www.freedesktop.org/software/systemd/man/systemd.exec.html#LimitCPU= . « LimitNPROC » est l'équivalent de « ulimit -u ». Il ne s'agit donc pas d'une limite par slice ou quoi que ce soit, juste une bonne vieille limite par utilisateur.
Je trouve vraiment dommage de n'avoir aucune indication dans les logs qu'une limite a été dépassée. Ça rend houleux le debug… :(
ÉDIT DU 26/10/2016 À 01H55 : « LimitNPROC » apparaît dans l'unit systemd OpenVPN livré dans le paquet de Debian Stretch, pas celui de Debian Jessie. FIN DE L'ÉDIT.