NET_ADMIN é a capacidade de Linux que permite a un proceso realizar administración de rede, e nun contedor fai exactamente iso dentro do espazo de nomes de rede no que se executa o proceso. Non é unha licenza para abrir un socket nin un substituto dun dispositivo ou dunha ruta. A pregunta interesante nunca é se a capacidade foi concedida, senón que espazo de nomes recibe o cambio.

Que cubre a capacidade

Dentro do seu espazo de nomes, un proceso con NET_ADMIN pode levantar e baixar interfaces, asignar enderezos, engadir e eliminar rutas e escribir regras de cortalumes, que é o grupo de operacións que capabilities(7) reúne baixo esta capacidade. Tamén pode axustar parámetros a nivel de interface que controlan como o núcleo encola e filtra o tráfico. Un cliente VPN normalmente necesita unhas cantas ao arrincar e nada máis despois. Por iso a maioría das imaxes piden máis alcance do que usan.

As operacións fóra dese espazo de nomes non están cubertas, e os privilexios adxacentes son separados. Ler e escribir paquetes crus pertence a NET_RAW, e crear un dispositivo tun necesita tanto a capacidade como acceso ao nodo do dispositivo. Un proceso sen o dispositivo recibe un erro de permisos que parece un problema de rede e non o é.

O espazo de nomes decide o raio de dano

Un contedor na súa propia rede ponte alcanza o seu propio loopback, as súas propias interfaces e a súa propia táboa de encamiñamento. Conceder NET_ADMIN alí permite ao cliente VPN construír un túnel sen tocar as decisións de encamiñamento do host, que é a disposición que asumen a maioría das imaxes de contedor.

Cambie ese contedor a rede do host e a mesma concesión agora edita as rutas do host e o seu cortalumes, porque non queda ningún espazo de nomes separado. O cliente que debía xestionar un só túnel pode entón redirixir o tráfico de toda a máquina, e un erro no seu script de desmontaxe deixa ao host regras que ninguén escribiu. Nada na capacidade cambiou; cambiou o contexto. Por iso o mesmo ficheiro compose compórtase de forma distinta en dous hosts.

Tres requisitos previos que se funden nun

Os fallos de arrinque en contedores VPN adoitan implicar unha de tres cousas separadas: a capacidade, o dispositivo de túnel e o soporte do núcleo para o protocolo. Conceder as tres á vez funciona, e tamén fai imposible atribuír o seguinte fallo. Un fragmento mínimo de compose concede a capacidade e pasa o nodo do dispositivo explicitamente:

services:
  vpn:
    image: example/vpn-client:latest
    cap_add:
      - NET_ADMIN
    devices:
      - /dev/net/tun
    sysctls:
      - net.ipv4.conf.all.src_valid_mark=1

Lea a documentación da propia imaxe para saber que sysctls necesita, porque un sysctl dentro dun contedor pode requirir un privilexio adicional ou un axuste a nivel de host. Onde a imaxe admite só modo de espazo de usuario, non fai falta ningún dispositivo e a lista de capacidades redúcese en consecuencia.

Conceda a operación estreita, non o modo

O modo privilexiado entrega todas as capacidades e amplía o acceso a dispositivos ao mesmo tempo, así que oculta cal dos tres requisitos previos faltaba. Tamén fai indistinguibles os modos de fallo do contedor dos cambios do host. Prefira unha lista explícita aínda que sexa máis longa de escribir.

Os despregamentos rootless e con espazos de nomes de usuario cambian que significa unha capacidade na práctica, xa que o proceso só pode tela dentro dun espazo de nomes mapeado. Copiar unha lista de capacidades dun exemplo rootful a un contorno de execución rootless e esperar o mesmo alcance é unha forma habitual de perder unha tarde.

Os segredos pertencen a unha decisión aparte. Ter NET_ADMIN non di nada sobre que identidade de par presenta o cliente, que credenciais carga nin como se rotan. A administración de rede non achega confianza.

Verifique o cambio e rexistre por que existe a concesión

Confirme que recibiu realmente o contedor antes de depurar o túnel. A inspección de abaixo informa das capacidades engadidas e do modo de rede, e despois mostra como se ve a lista de interfaces desde dentro:

docker inspect --format '{{.HostConfig.CapAdd}} {{.HostConfig.NetworkMode}} {{.HostConfig.Privileged}}' vpn
docker exec vpn sh -c 'grep CapEff /proc/self/status'
docker exec vpn ip -br addr
docker exec vpn ip route

Se a capacidade está presente e a lista de interfaces segue baleira, o cliente fallou antes de poder crear nada, e os rexistros do contedor son o seguinte lugar onde mirar. Se o túnel existe pero o tráfico non flúe, a táboa de encamiñamento dentro do contedor responde a seguinte pregunta.

Probe tamén a ruta de desmontaxe, porque un cliente que escribe regras de cortalumes pode deixalas atrás. Deteña o contedor e volva comprobar o conxunto de regras do host se se usa a rede do host. Unha concesión que só se necesita dous segundos ao arrincar non debería describirse no ficheiro compose como un requisito permanente sen unha nota que o explique.

Escriba o motivo xunto a cada capacidade: que operación a necesitaba e que falla sen ela. Esa nota sobrevive ás actualizacións de imaxe, e é a diferenza entre unha lista de privilexios revisada e unha que medrou a base de copiar e pegar.

Artigos relacionados