LXD exposa un dispositiu de caràcters de l'amfitrió a un contenidor afegint un node de dispositiu, no ensenyant el convidat a crear-ne un. Si el contenidor no té /dev/net/tun, l'amfitrió pot tenir el dispositiu i el convidat pot continuar sense poder obrir-lo. L'entrada unix-char és la meitat d'aquest camí pel cantó del gestor, i és deliberadament més estreta que un contenidor privilegiat. Per això el node de l'amfitrió i el node del contenidor mereixen comprovacions separades.

El mecanisme és prou curt per tenir-lo a la vista: LXD resol un camí de l'amfitrió, crea un node corresponent dins de la instància i afegeix el dispositiu al cgroup de dispositius del contenidor. Després, el procés del convidat necessita el seu propi permís i la seva capacitat per fer servir el node per a qualsevol cosa.

Què canvia realment l'entrada unix-char

Un dispositiu unix-char diu a LXD que exposi un dispositiu de caràcters de l'amfitrió en un camí triat dins del contenidor. L'entrada té tres parts que importen: l'etiqueta del dispositiu que fa servir el gestor, el camí source a l'amfitrió i el path que veu el convidat. Només les dues últimes descriuen el dispositiu en si. Una errata en qualsevol de les dues produeix un node en un lloc que el client no obre mai.

A l'amfitrió, el dispositiu normalment és /dev/net/tun. Dins del contenidor podeu mantenir el mateix camí o triar-ne un altre, però el camí ha de coincidir amb el que espera el client VPN. Mantenir /dev/net/tun evita un segon problema de configuració, perquè la majoria de clients obren aquest camí sense preguntar.

El gestor aplica l'entrada quan la instància s'inicia o quan el dispositiu es connecta en calent. No copia cap controlador dins del convidat ni crea una interfície de túnel. Fa visible el node i permet l'accés a través del grup de control de dispositius del contenidor.

Declareu el dispositiu a la instància, no dins del convidat

Afegiu l'entrada des del context d'administració de LXD, indicant la instància i una etiqueta que pugueu reconèixer més tard. Per a un contenidor anomenat vpnbox, l'ordre és:

lxc config device add vpnbox tun unix-char source=/dev/net/tun path=/dev/net/tun
lxc config device show vpnbox

L'etiqueta tun és local a la configuració de la instància. No és un nom d'interfície i no ha de coincidir amb res del convidat. Si un perfil ja proporciona el mateix dispositiu, afegir una segona entrada crea un conflicte en lloc d'una redundància, així que reviseu primer la configuració efectiva.

Editar fitxers dins del contenidor és la capa equivocada. Un mknod en un script d'inici pot semblar que funciona en un contenidor privilegiat, i després desaparèixer en recrear-lo o fallar en un de menys privilegiat. El gestor és propietari del conjunt de dispositius de la instància; deixeu que també ho sigui del node.

Ajusteu la propietat i el mode al procés del convidat

L'entrada unix-char pot definir uid, gid i mode per al node dins del contenidor. Feu-los servir per coincidir amb el compte que executa el client VPN, en lloc d'obrir el dispositiu a tots els usuaris o de passar el contenidor a mode privilegiat.

Visibilitat no és el mateix que permís. Un node propietat de root amb mode 600 és visible per al servei que s'executa com a usuari sense privilegis i continua sense poder-se obrir per part seu. Comproveu primer el compte del convidat, després assigneu la propietat a aquest compte i manteniu el mode no més ampli del que el client necessita.

El procés també necessita la capacitat de configurar una interfície de túnel, normalment CAP_NET_ADMIN a l'espai de noms de xarxa del contenidor. Passar el dispositiu no atorga aquesta capacitat, i atorgar la capacitat no forneix el dispositiu; són requisits independents.

Sapigueu què no atorga l'entrada

Un node visible no és una VPN que funcioni. El paquet del client encara s'ha d'instal·lar, el perfil encara ha de ser vàlid i el servei encara s'ha d'iniciar. L'autenticació, les rutes i el DNS continuen sent feina del client, i una fallada allà no és prova que l'entrada del dispositiu sigui incorrecta.

systemd pot afegir una altra restricció. Una unitat amb DeviceAllow o una política de dispositius endurida pot denegar l'accés a un node que el gestor de contenidors ha proporcionat. Reviseu la política de dispositius de la unitat quan el node existeix però el servei informa d'un error de permís, i canvieu aquesta política en lloc d'ampliar el contenidor.

La connexió en calent és opcional i explícita. Una entrada amb required=false necessita un camí d'origen i pot aparèixer o desaparèixer a mesura que canvia el dispositiu de l'amfitrió. Aquest cicle de vida va bé per a maquinari que apareix i desapareix; per a un dispositiu TUN que la VPN necessita en l'arrencada, una entrada opcional pot deixar el servei començant abans que existeixi el seu requisit previ.

Verifiqueu visibilitat, obertura i interfície en aquest ordre

Primer confirmeu el node dins del contenidor previst. El camí, els números major i menor i la propietat han de coincidir amb el dispositiu de l'amfitrió i amb l'entrada que heu afegit. Un node absent vol dir que el gestor no ha aplicat l'entrada, o l'ha aplicada a una altra instància.

lxc exec vpnbox -- ls -l /dev/net/tun
lxc exec vpnbox -- sh -c 'test -c /dev/net/tun && echo char-device-ok'

Després confirmeu que el compte del servei el pot obrir. Una prova curta amb aquest compte separa un problema de propietat d'un problema de servei. Finalment, inicieu el client i confirmeu que apareix una interfície de túnel; només aquest tercer pas demostra tot el camí, perquè els dos primers poden passar mentre el perfil o la capacitat del client encara són incorrectes.

Anoteu la instància, l'etiqueta del dispositiu, l'origen a l'amfitrió, el camí al convidat i el compte propietari quan s'aprovi el canvi. Aquests cinc valors són el que una recreació, migració o canvi de perfil posterior ha de preservar, i són molt més fàcils de comparar que un error de permís sense context.

Articles relacionats