LXD espone un dispositivo a caratteri dell'host a un container aggiungendo un nodo di dispositivo, non insegnando all'ospite a crearne uno. Se il container non ha /dev/net/tun, l'host può avere il dispositivo e l'ospite può comunque non riuscire ad aprirlo. La voce unix-char è la metà di questo percorso lato gestore, ed è deliberatamente più stretta di un container privilegiato. Per questo il nodo dell'host e il nodo del container meritano verifiche separate.

Il meccanismo è abbastanza breve da tenere a vista: LXD risolve un percorso dell'host, crea un nodo corrispondente dentro l'istanza e aggiunge il dispositivo al cgroup dei dispositivi del container. Poi il processo ospite ha bisogno del proprio permesso e della propria capacità per usare il nodo in qualunque modo.

Cosa cambia davvero la voce unix-char

Un dispositivo unix-char dice a LXD di esporre un dispositivo a caratteri dell'host su un percorso scelto dentro il container. La voce ha tre parti che contano: l'etichetta del dispositivo usata dal gestore, il percorso source sull'host e il path che vede l'ospite. Solo gli ultimi due descrivono il dispositivo stesso. Un errore di battitura in uno dei due produce un nodo in un punto che il client non apre mai.

Sull'host il dispositivo è di solito /dev/net/tun. Dentro il container potete mantenere lo stesso percorso o sceglierne un altro, ma il percorso deve corrispondere a quello che il client VPN si aspetta. Mantenere /dev/net/tun evita un secondo problema di configurazione, perché la maggior parte dei client apre quel percorso senza chiedere.

Il gestore applica la voce all'avvio dell'istanza o al collegamento a caldo del dispositivo. Non copia un driver nell'ospite e non crea un'interfaccia tunnel. Rende visibile il nodo e consente l'accesso tramite il gruppo di controllo dei dispositivi del container.

Dichiarate il dispositivo sull'istanza, non dentro l'ospite

Aggiungete la voce dal contesto di amministrazione di LXD, indicando l'istanza e un'etichetta che riconoscerete più tardi. Per un container chiamato vpnbox il comando è:

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

L'etichetta tun è locale alla configurazione dell'istanza. Non è un nome di interfaccia e non deve corrispondere a nulla nell'ospite. Se un profilo fornisce già lo stesso dispositivo, aggiungere una seconda voce crea un conflitto anziché una ridondanza, quindi esaminate prima la configurazione effettiva.

Modificare file dentro il container è lo strato sbagliato. Un mknod in uno script di avvio può sembrare funzionare su un container privilegiato, poi sparire alla ricreazione o fallire su uno meno privilegiato. Il gestore possiede l'insieme di dispositivi dell'istanza; lasciategli possedere anche il nodo.

Allineate proprietà e modo al processo ospite

La voce unix-char può impostare uid, gid e mode per il nodo dentro il container. Usateli per corrispondere all'account che esegue il client VPN, invece di aprire il dispositivo a tutti gli utenti o di passare il container in modalità privilegiata.

La visibilità non è la stessa cosa del permesso. Un nodo di proprietà di root con modo 600 è visibile al servizio eseguito come utente non privilegiato e resta non apribile da esso. Controllate prima l'account ospite, poi assegnate la proprietà a quell'account e mantenete il modo non più ampio di quanto serve al client.

Il processo ha anche bisogno di la capacità di configurare un'interfaccia tunnel, di solito CAP_NET_ADMIN nello spazio dei nomi di rete del container. Passare il dispositivo non concede quella capacità, e concedere la capacità non fornisce il dispositivo; sono requisiti indipendenti.

Sappiate cosa non concede la voce

Un nodo visibile non è una VPN funzionante. Il pacchetto client va ancora installato, il profilo deve ancora essere valido e il servizio deve ancora avviarsi. Autenticazione, rotte e DNS restano compito del client, e un guasto lì non è prova che la voce del dispositivo sia sbagliata.

systemd può aggiungere un'altra restrizione. Un'unità con DeviceAllow o una politica dei dispositivi rafforzata può negare l'accesso a un nodo fornito dal gestore dei container. Controllate la politica dei dispositivi dell'unità quando il nodo esiste ma il servizio segnala un errore di permesso, e cambiate quella politica invece di ampliare il container.

Il collegamento a caldo è opzionale ed esplicito. Una voce con required=false richiede un percorso sorgente e può comparire o scomparire al variare del dispositivo dell'host. Quel ciclo di vita si adatta a hardware che va e viene; per un dispositivo TUN che la VPN richiede all'avvio, una voce opzionale può lasciare che il servizio parta prima che il suo prerequisito esista.

Verificate visibilità, apertura e interfaccia in quest'ordine

Per prima cosa confermate il nodo dentro il container previsto. Il percorso, i numeri maggiore e minore e la proprietà devono corrispondere al dispositivo dell'host e alla voce che avete aggiunto. Un nodo assente significa che il gestore non ha applicato la voce, o l'ha applicata a un'altra istanza.

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

Poi confermate che l'account del servizio possa aprirlo. Un test breve con quell'account separa un problema di proprietà da un problema di servizio. Infine avviate il client e confermate che compaia un'interfaccia tunnel; solo quel terzo passo dimostra l'intero percorso, perché i primi due possono passare mentre il profilo o la capacità del client sono ancora sbagliati.

Annotate l'istanza, l'etichetta del dispositivo, l'origine sull'host, il percorso nell'ospite e l'account proprietario quando la modifica viene approvata. Quei cinque valori sono ciò che una ricreazione, migrazione o modifica di profilo successiva deve preservare, e sono molto più facili da confrontare di un errore di permesso senza contesto.

Articoli correlati