O contedor LXD non pode abrir /dev/net/tun? Revise a entrada unix-char
LXD debe pasar o dispositivo TUN do host ao contedor antes de que un cliente VPN poida usalo. Vexa que engade unix-char, que non, e como comprobalo.
LXD expón un dispositivo de caracteres do host a un contedor engadindo un nodo de dispositivo, non ensinando ao convidado a crear un. Se o contedor non ten /dev/net/tun, o host pode ter o dispositivo e o convidado aínda así non poder abrirlo. A entrada unix-char é a metade dese camiño do lado do xestor, e é deliberadamente máis estreita que un contedor privilexiado. Por iso o nodo do host e o nodo do contedor merecen comprobacións separadas.
O mecanismo é curto abondo para mantelo á vista: LXD resolve unha ruta do host, crea un nodo correspondente dentro da instancia e engade o dispositivo ao cgroup de dispositivos do contedor. Despois, o proceso do convidado necesita o seu propio permiso e a súa propia capacidade para usar o nodo en algo.
Que cambia realmente a entrada unix-char
Un dispositivo unix-char indica a LXD que expoña un dispositivo de caracteres do host nunha ruta elixida dentro do contedor. A entrada ten tres partes que importan: a etiqueta do dispositivo que usa o xestor, a ruta source no host e o path que ve o convidado. Só as dúas últimas describen o dispositivo en si. Un erro tipográfico en calquera delas produce un nodo nun lugar que o cliente nunca abre.
No host, o dispositivo adoita ser /dev/net/tun. Dentro do contedor pode manter a mesma ruta ou elixir outra, pero a ruta debe coincidir co que espera o cliente VPN. Manter /dev/net/tun evita un segundo problema de configuración, porque a maioría dos clientes abren esa ruta sen preguntar.
O xestor aplica a entrada cando a instancia arrinca ou cando o dispositivo se conecta en quente. Non copia un controlador dentro do convidado nin crea unha interface de túnel. Fai visible o nodo e permite o acceso a través do grupo de control de dispositivos do contedor.
Declare o dispositivo na instancia, non dentro do convidado
Engada a entrada desde o contexto de administración de LXD, indicando a instancia e unha etiqueta que poida recoñecer despois. Para un contedor chamado vpnbox, o comando é:
lxc config device add vpnbox tun unix-char source=/dev/net/tun path=/dev/net/tun
lxc config device show vpnbox
A etiqueta tun é local á configuración da instancia. Non é un nome de interface e non ten que coincidir con nada do convidado. Se un perfil xa fornece o mesmo dispositivo, engadir unha segunda entrada crea un conflito en lugar dunha redundancia, así que revise primeiro a configuración efectiva.
Editar ficheiros dentro do contedor é a capa equivocada. Un mknod nun script de arrinque pode parecer que funciona nun contedor privilexiado, e logo desaparecer ao recrealo ou fallar nun menos privilexiado. O xestor é dono do conxunto de dispositivos da instancia; deixe que tamén o sexa do nodo.
Axuste a propiedade e o modo ao proceso do convidado
A entrada unix-char pode definir uid, gid e mode para o nodo dentro do contedor. Úseos para coincidir coa conta que executa o cliente VPN, en lugar de abrir o dispositivo a todos os usuarios ou pasar o contedor a modo privilexiado.
Visibilidade non é o mesmo que permiso. Un nodo propiedade de root con modo 600 é visible para o servizo que se executa como usuario sen privilexios e aínda así non pode abrilo. Comprobe primeiro a conta do convidado, logo asigne a propiedade a esa conta e manteña o modo non máis amplo do que o cliente necesita.
O proceso tamén necesita a capacidade de configurar unha interface de túnel, normalmente CAP_NET_ADMIN no espazo de nomes de rede do contedor. Pasar o dispositivo non outorga esa capacidade, e outorgar a capacidade non fornece o dispositivo; son requisitos independentes.
Saiba que non outorga a entrada
Un nodo visible non é unha VPN que funcione. O paquete do cliente aínda hai que instalalo, o perfil aínda ten que ser válido e o servizo aínda ten que arrincar. A autenticación, as rutas e o DNS seguen sendo traballo do cliente, e un fallo aí non é proba de que a entrada do dispositivo estea mal.
systemd pode engadir outra restrición. Unha unit con DeviceAllow ou unha política de dispositivos endurecida pode denegar o acceso a un nodo que o xestor de contedores forneceu. Revise a política de dispositivos da unit cando o nodo existe pero o servizo informa dun erro de permiso, e cambie esa política en lugar de ampliar o contedor.
A conexión en quente é opcional e explícita. Unha entrada con required=false necesita unha ruta de orixe e pode aparecer ou desaparecer a medida que cambia o dispositivo do host. Ese ciclo de vida encaixa con hardware que vai e vén; para un dispositivo TUN que a VPN necesita ao arrincar, unha entrada opcional pode deixar que o servizo arrinque antes de que exista o seu requisito previo.
Verifique visibilidade, apertura e interface nesa orde
Primeiro confirme o nodo dentro do contedor previsto. A ruta, os números maior e menor e a propiedade deben coincidir co dispositivo do host e coa entrada que engadiu. Un nodo ausente significa que o xestor non aplicou a entrada, ou a aplicou a outra instancia.
lxc exec vpnbox -- ls -l /dev/net/tun
lxc exec vpnbox -- sh -c 'test -c /dev/net/tun && echo char-device-ok'
Despois confirme que a conta do servizo pode abrila. Unha proba curta con esa conta separa un problema de propiedade dun problema de servizo. Por último, arrinque o cliente e confirme que aparece unha interface de túnel; só ese terceiro paso demostra todo o camiño, porque os dous primeiros poden pasar mentres o perfil ou a capacidade do cliente seguen mal.
Anote a instancia, a etiqueta do dispositivo, a orixe no host, a ruta no convidado e a conta propietaria cando se aprobe o cambio. Eses cinco valores son os que unha recreación, migración ou cambio de perfil posterior ten que conservar, e son moito máis fáciles de comparar que un erro de permiso sen contexto.