OpenVPN dans Docker ne peut pas ouvrir /dev/net/tun : ce qui manque
Un nœud TUN et la capacité réseau sont deux autorisations distinctes. Ouvrez les deux, puis lisez l’erreur suivante selon ses propres termes au lieu de répéter la même correction.
Les images de conteneur peuvent embarquer tous les binaires et fichiers de configuration OpenVPN dont elles ont besoin et échouer malgré tout au premier appel réseau. L’erreur nomme /dev/net/tun parce que l’application a demandé au noyau une interface TUN et que le conteneur n’avait ni le nœud de périphérique ni la capacité d’en créer un. Ce sont deux autorisations distinctes, et corriger l’une laisse l’autre exactement là où elle était.
Les séparer demande une commande pour chacune. Le message d’erreur qui suit vous dit à quelle frontière vous vous trouviez réellement.
Le nœud de périphérique et la capacité sont deux portes
Le nœud de périphérique est un objet du système de fichiers, donc un conteneur doit le voir dans son propre espace de noms de montage. La capacité est une autorisation, donc le processus a besoin de CAP_NET_ADMIN dans l’espace de noms où l’interface sera créée. Transmettre le périphérique sans la capacité vous donne un nœud qui s’ouvre et un ioctl qui échoue. Accorder la capacité sans le périphérique laisse l’application incapable d’ouvrir quoi que ce soit, et c’est pourquoi les deux apparaissent généralement ensemble dans les exemples.
Le réglage devices de Docker projette le périphérique de l’hôte dans le conteneur, tandis que cap_add ajuste l’ensemble des capacités. Un bind mount du même chemin met le fichier en vue sans appliquer la sémantique d’accès au périphérique.
Reproduisez-le en dehors du fichier Compose
Avant de modifier le service, vérifiez que l’hôte possède le périphérique et qu’un conteneur nu peut créer une interface. La commande ci-dessous est volontairement minimale, et son seul but est de séparer un problème d’hôte d’un problème de compose. Si elle échoue, aucun changement de compose n’aidera.
ls -l /dev/net/tun
docker run --rm --cap-add NET_ADMIN --device /dev/net/tun:/dev/net/tun alpine sh -c 'apk add -q iproute2 && ip tuntap add dev tun9 mode tun && ip link show tun9'
Un nœud absent sur l’hôte signifie que le module tun n’est pas disponible, ce qui est une correction côté hôte et non côté conteneur. Un nœud qui existe mais ne s’ouvre pas dans le conteneur indique un accès au périphérique, et le message dira permission denied plutôt que no such file. L’ordre de ces deux échecs constitue tout le diagnostic. Notez lequel vous avez vu avant de changer un indicateur.
Les erreurs après TUN sont d’autres problèmes
Dès que l’interface apparaît, l’échec suivant a un autre propriétaire. Les erreurs d’authentification signifient que le tunnel a atteint le serveur et que les identifiants ont été refusés, donc les changements de capacité n’aideront pas. Un tunnel qui s’établit alors que les applications échouent encore pointe vers les routes, le transfert, la résolution DNS dans le conteneur ou la disposition réseau du conteneur lui-même. Chacun de ces points est une question réseau ordinaire à laquelle l’autorisation TUN ne peut pas répondre. Répéter le test d’origine après chaque changement évite que les échecs ne fusionnent en une seule impression.
Copier chaque réglage d’un exemple qui fonctionne est la façon dont une correction minimale devient une définition de service illisible. Ne reprenez que ceux dont ce déploiement a besoin et notez pourquoi chacun est présent.
Vérifiez l’interface à l’intérieur du conteneur
Vérifiez l’interface et l’ensemble des capacités depuis l’intérieur du conteneur en cours d’exécution plutôt que depuis l’hôte. Les commandes ci-dessous montrent le nœud de périphérique, la liste des capacités et si une interface peut être créée. Exécutez-les dans le même conteneur que celui qui exécute le client, et installez les outils si l’image est minimale.
ls -l /dev/net/tun
capsh --print | grep -i net_admin
ip link add dev tun9 type tun && ip link show tun9
Une capacité présente dans le bounding set mais absente de l’effective set se comporte différemment d’une capacité qui n’a jamais été accordée, et capsh montre les deux. Si le nœud existe et que la capacité est là alors que la création échoue encore, l’environnement d’exécution impose autre chose, comme un profil seccomp ou une politique AppArmor qui restreint l’opération. C’est une troisième frontière, documentée par l’environnement d’exécution plutôt que par l’application.
Notez les indicateurs du conteneur, l’image et l’erreur exacte de chaque tentative. La prochaine personne qui lira cette note pourra dire quelle porte était fermée sans répéter toute l’enquête.