Container-Images können jede benötigte OpenVPN-Binärdatei und Konfigurationsdatei enthalten und trotzdem beim ersten Netzwerkaufruf scheitern. Der Fehler nennt /dev/net/tun, weil die Anwendung den Kernel um eine TUN-Schnittstelle gebeten hat und der Container weder den Geräteknoten noch die Fähigkeit besaß, einen zu erstellen. Das sind zwei getrennte Berechtigungen, und wer die eine behebt, lässt die andere genau dort, wo sie war.

Sie zu trennen erfordert je einen Befehl. Die anschließende Fehlermeldung sagt Ihnen, an welcher Grenze Sie tatsächlich standen.

Der Geräteknoten und die Fähigkeit sind zwei Türen

Der Geräteknoten ist ein Dateisystemobjekt, ein Container muss ihn also in seinem eigenen Mount-Namespace sehen. Die Fähigkeit ist eine Berechtigung, der Prozess braucht also CAP_NET_ADMIN in dem Namespace, in dem die Schnittstelle erstellt wird. Das Gerät ohne die Fähigkeit durchzureichen ergibt einen Knoten, der sich öffnet, und ein ioctl, das scheitert. Die Fähigkeit ohne das Gerät zu gewähren lässt die Anwendung überhaupt nichts öffnen, weshalb beide in Beispielen meist zusammen auftauchen.

Dockers devices-Einstellung bildet das Hostgerät in den Container ab, während cap_add die Fähigkeitsmenge anpasst. Ein Bind-Mount desselben Pfads bringt die Datei ins Blickfeld, ohne die Semantik des Gerätezugriffs anzuwenden.

Reproduzieren Sie es außerhalb der Compose-Datei

Prüfen Sie vor dem Bearbeiten des Dienstes, ob der Host das Gerät besitzt und ob ein nackter Container eine Schnittstelle erstellen kann. Der Befehl unten ist bewusst minimal, und sein einziger Zweck ist es, ein Hostproblem von einem Compose-Problem zu trennen. Wenn er scheitert, hilft keine Compose-Änderung.

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'

Ein fehlender Knoten auf dem Host bedeutet, dass das tun-Modul nicht verfügbar ist, was eine Korrektur auf der Hostseite und nicht im Container ist. Ein Knoten, der existiert, sich im Container aber nicht öffnen lässt, deutet auf Gerätezugriff hin, und die Meldung wird permission denied statt no such file sagen. Die Reihenfolge dieser beiden Fehler ist die ganze Diagnose. Notieren Sie, welchen Sie gesehen haben, bevor Sie ein Flag ändern.

Die Fehler nach TUN sind andere Probleme

Sobald die Schnittstelle erscheint, hat der nächste Fehler einen anderen Besitzer. Authentifizierungsfehler bedeuten, dass der Tunnel den Server erreicht hat und die Anmeldedaten abgelehnt wurden, sodass Änderungen an den Fähigkeiten nicht helfen. Ein Tunnel, der aufgebaut wird, während Anwendungen weiterhin scheitern, deutet auf Routen, Weiterleitung, DNS-Auflösung im Container oder das eigene Netzwerklayout des Containers hin. Jedes davon ist eine gewöhnliche Netzwerkfrage, die die TUN-Berechtigung nicht beantworten kann. Den ursprünglichen Test nach jeder Änderung zu wiederholen verhindert, dass die Fehler zu einem Eindruck verschmelzen.

Jede Einstellung aus einem funktionierenden Beispiel zu kopieren ist der Weg, auf dem aus einer minimalen Korrektur eine unlesbare Dienstdefinition wird. Übernehmen Sie nur die, die diese Bereitstellung braucht, und notieren Sie, warum jede da ist.

Prüfen Sie die Schnittstelle im Container

Prüfen Sie die Schnittstelle und die Fähigkeitsmenge von innen im laufenden Container statt vom Host aus. Die Befehle unten zeigen den Geräteknoten, die Fähigkeitsliste und ob überhaupt eine Schnittstelle erstellt werden kann. Führen Sie sie in demselben Container aus, der den Client ausführt, und installieren Sie die Werkzeuge, wenn das Image minimal ist.

ls -l /dev/net/tun
capsh --print | grep -i net_admin
ip link add dev tun9 type tun && ip link show tun9

Eine Fähigkeit, die im bounding set vorhanden, im effective set aber nicht enthalten ist, verhält sich anders als eine, die nie gewährt wurde, und capsh zeigt beide. Wenn der Knoten existiert und die Fähigkeit vorhanden ist, während das Erstellen weiterhin scheitert, erzwingt die Laufzeitumgebung etwas anderes, etwa ein seccomp-Profil oder eine AppArmor-Richtlinie, die den Vorgang einschränkt. Das ist eine dritte Grenze, dokumentiert von der Laufzeitumgebung statt von der Anwendung.

Notieren Sie die Container-Flags, das Image und den genauen Fehler jedes Versuchs. Wer diese Notiz als Nächstes liest, kann sagen, welche Tür geschlossen war, ohne die ganze Untersuchung zu wiederholen.

Ähnliche Artikel