Los espacios de nombres de Linux proporcionan aislamiento para los procesos en ejecución, lo que limita su acceso a los recursos del sistema sin que el proceso en ejecución sea consciente de las limitaciones. Para obtener más información sobre los espacios de nombres de Linux, consulte Espacios de nombres de Linux.

La mejor manera de evitar ataques de escalada de privilegios desde dentro de un contenedor es configurar las aplicaciones de su contenedor para que se ejecuten como usuarios sin privilegios. Para contenedores cuyos procesos deben ejecutarse como root usuario dentro del contenedor, puede volver a asignar este usuario a un usuario con menos privilegios en el host de Docker. Al usuario mapeado se le asigna un rango de UID que funcionan dentro del espacio de nombres como UID normales de 0 a 65536, pero no tienen privilegios en la máquina host en sí.

Acerca de la reasignación y los ID de grupos y usuarios subordinados

La reasignación en sí es manejada por dos archivos: /etc/subuid y /etc/subgid. Cada archivo funciona igual, pero uno se ocupa del rango de ID de usuario y el otro del rango de ID de grupo. Considere la siguiente entrada en /etc/subuid:

testuser:231072:65536

Esto significa que testuser se le asigna un rango de ID de usuario subordinado de 231072 y los siguientes 65536 enteros en secuencia. UID 231072 se asigna dentro del espacio de nombres (dentro del contenedor, en este caso) como UID 0 (root). UID 231073 está mapeado como UID 1, Etcétera. Si un proceso intenta escalar privilegios fuera del espacio de nombres, el proceso se ejecuta como un UID de alto número sin privilegios en el host, que ni siquiera se asigna a un usuario real. Esto significa que el proceso no tiene ningún privilegio en el sistema host.

Varias gamas

Es posible asignar múltiples rangos subordinados para un usuario o grupo dado agregando múltiples asignaciones no superpuestas para el mismo usuario o grupo en el /etc/subuid o /etc/subgid expediente. En este caso, Docker usa solo las primeras cinco asignaciones, de acuerdo con la limitación del kernel de solo cinco entradas en /proc/self/uid_map y /proc/self/gid_map.

Cuando configura Docker para usar el userns-remap característica, puede especificar opcionalmente un usuario y / o grupo existente, o puede especificar default. Si especifica default, un usuario y un grupo dockremap se crea y se utiliza para este propósito.

Advertencia: Algunas distribuciones, como RHEL y CentOS 7.3, no agregan automáticamente el nuevo grupo al /etc/subuid y /etc/subgid archivos. Usted es responsable de editar estos archivos y asignar rangos que no se superpongan, en este caso. Este paso se trata en Requisitos previos.

Es muy importante que los rangos no se superpongan, de modo que un proceso no pueda obtener acceso en un espacio de nombres diferente. En la mayoría de las distribuciones de Linux, las utilidades del sistema administran los rangos por usted cuando agrega o elimina usuarios.

Esta reasignación es transparente para el contenedor, pero introduce cierta complejidad de configuración en situaciones en las que el contenedor necesita acceso a los recursos en el host de Docker, como los montajes de enlace en áreas del sistema de archivos en las que el usuario del sistema no puede escribir. Desde el punto de vista de la seguridad, es mejor evitar estas situaciones.

Prerrequisitos

  1. Los rangos de UID y GID subordinados deben estar asociados con un usuario existente, aunque la asociación es un detalle de implementación. El usuario es propietario de los directorios de almacenamiento con espacio de nombres en /var/lib/docker/. Si no desea utilizar un usuario existente, Docker puede crear uno para usted y utilizarlo. Si desea utilizar un nombre de usuario o ID de usuario existente, ya debe existir. Normalmente, esto significa que las entradas relevantes deben estar en /etc/passwd y /etc/group, pero si está utilizando un back-end de autenticación diferente, este requisito puede traducirse de manera diferente.

    Para verificar esto, use el id mando:

    $ id testuser
    
    uid=1001(testuser) gid=1001(testuser) groups=1001(testuser)
    
  2. La forma en que se maneja la reasignación del espacio de nombres en el host es mediante dos archivos, /etc/subuid y /etc/subgid. Por lo general, estos archivos se administran automáticamente cuando agrega o elimina usuarios o grupos, pero en algunas distribuciones como RHEL y CentOS 7.3, es posible que deba administrar estos archivos manualmente.

    Cada archivo contiene tres campos: el nombre de usuario o ID del usuario, seguido de un UID o GID inicial (que se trata como UID o GID 0 dentro del espacio de nombres) y un número máximo de UID o GID disponibles para el usuario. Por ejemplo, dada la siguiente entrada:

    testuser:231072:65536
    

    Esto significa que los procesos con espacios de nombre de usuario iniciados por testuser son propiedad del UID del host 231072 (que parece UID 0 dentro del espacio de nombres) hasta 296607 (231072 + 65536 – 1). Estos rangos no deben superponerse para garantizar que los procesos con espacios de nombres no puedan acceder a los espacios de nombres de los demás.

    Después de agregar su usuario, verifique /etc/subuid y /etc/subgid para ver si su usuario tiene una entrada en cada uno. De lo contrario, debe agregarlo, teniendo cuidado de evitar superposiciones.

    Si desea utilizar el dockremap usuario creado automáticamente por Docker, compruebe el dockremap entrada en estos archivos después configurar y reiniciar Docker.

  3. Si hay ubicaciones en el host de Docker donde el usuario sin privilegios necesita escribir, ajuste los permisos de esas ubicaciones en consecuencia. Esto también es true si quieres usar el dockremap usuario creado automáticamente por Docker, pero no puede modificar los permisos hasta después de configurar y reiniciar Docker.

  4. Habilitar userns-remap enmascara eficazmente las capas de imagen y contenedor existentes, así como otros objetos de Docker dentro /var/lib/docker/. Esto se debe a que Docker necesita ajustar la propiedad de estos recursos y, de hecho, los almacena en un subdirectorio dentro de /var/lib/docker/. Es mejor habilitar esta función en una nueva instalación de Docker en lugar de en una existente.

    En la misma línea, si desactiva userns-remap no puede acceder a ninguno de los recursos creados mientras estaba habilitado.

  5. Verifique las limitaciones en los espacios de nombres de usuario para asegurarse de que su caso de uso sea posible.

Habilitar userns-remap en el demonio

Tu puedes empezar dockerd con el --userns-remap o siga este procedimiento para configurar el demonio usando el daemon.json archivo de configuración. los daemon.json Se recomienda el método. Si usa la bandera, use el siguiente comando como modelo:

$ dockerd --userns-remap="testuser:testuser"
  1. Editar /etc/docker/daemon.json. Suponiendo que el archivo estaba previamente vacío, la siguiente entrada habilita userns-remap usando el usuario y el grupo llamado testuser. Puede dirigirse al usuario y al grupo por ID o nombre. Solo necesita especificar el nombre del grupo o ID si es diferente del nombre de usuario o ID. Si proporciona tanto el nombre de usuario como el de grupo o ID, sepárelos con dos puntos (:) personaje. Los siguientes formatos funcionan todos para el valor, asumiendo el UID y GID de testuser están 1001:

    • testuser
    • testuser:testuser
    • 1001
    • 1001:1001
    • testuser:1001
    • 1001:testuser
      "userns-remap": "testuser"
    
    

    Nota: Usar el dockremap usuario y haga que Docker lo cree por usted, establezca el valor en default en vez de testuser.

    Guarde el archivo y reinicie Docker.

  2. Si está utilizando el dockremap usuario, verifique que Docker lo haya creado usando el id mando.

    $ id dockremap
    
    uid=112(dockremap) gid=116(dockremap) groups=116(dockremap)
    

    Verifique que la entrada se haya agregado a /etc/subuid y /etc/subgid:

    $ grep dockremap /etc/subuid
    
    dockremap:231072:65536
    
    $ grep dockremap /etc/subgid
    
    dockremap:231072:65536
    

    Si estas entradas no están presentes, edite los archivos como root usuario y asigne un UID y GID de inicio que sea el más alto asignado más el desplazamiento (en este caso, 65536). Tenga cuidado de no permitir ninguna superposición en los rangos.

  3. Verifique que las imágenes anteriores no estén disponibles usando el docker image ls mando. La salida debe estar vacía.

  4. Inicie un contenedor desde el hello-world imagen.

    $ docker run hello-world
    
  5. Verifique que exista un directorio con espacio de nombres dentro /var/lib/docker/ nombrado con el UID y GID del usuario con espacio de nombres, propiedad de ese UID y GID, y no legible por grupo o mundo. Algunos de los subdirectorios siguen siendo propiedad de root y tener diferentes permisos.

    $ sudo ls -ld /var/lib/docker/231072.231072/
    
    drwx------ 11 231072 231072 11 Jun 21 21:19 /var/lib/docker/231072.231072/
    
    $ sudo ls -l /var/lib/docker/231072.231072/
    
    total 14
    drwx------ 5 231072 231072 5 Jun 21 21:19 aufs
    drwx------ 3 231072 231072 3 Jun 21 21:21 containers
    drwx------ 3 root   root   3 Jun 21 21:19 image
    drwxr-x--- 3 root   root   3 Jun 21 21:19 network
    drwx------ 4 root   root   4 Jun 21 21:19 plugins
    drwx------ 2 root   root   2 Jun 21 21:19 swarm
    drwx------ 2 231072 231072 2 Jun 21 21:21 tmp
    drwx------ 2 root   root   2 Jun 21 21:19 trust
    drwx------ 2 231072 231072 3 Jun 21 21:19 volumes
    

    Su lista de directorio puede tener algunas diferencias, especialmente si usa un controlador de almacenamiento de contenedor diferente al aufs.

    Los directorios que son propiedad del usuario reasignado se utilizan en lugar de los mismos directorios directamente debajo /var/lib/docker/ y las versiones no utilizadas (como /var/lib/docker/tmp/ en el ejemplo aquí) se puede eliminar. Docker no los usa mientras userns-remap está habilitado.

Deshabilitar la reasignación de espacios de nombres para un contenedor

Si habilita los espacios de nombre de usuario en el demonio, todos los contenedores se inician con los espacios de nombre de usuario habilitados de forma predeterminada. En algunas situaciones, como contenedores privilegiados, es posible que deba deshabilitar los espacios de nombres de usuario para un contenedor específico. Consulte las limitaciones conocidas del espacio de nombres de usuario para conocer algunas de estas limitaciones.

Para deshabilitar los espacios de nombres de usuario para un contenedor específico, agregue el --userns=host bandera a la docker container create, docker container run, o docker container exec mando.

Hay un efecto secundario al usar esta bandera: la reasignación de usuarios no se habilitará para ese contenedor pero, debido a que las capas de solo lectura (imagen) se comparten entre contenedores, la propiedad del sistema de archivos de los contenedores seguirá siendo reasignada.

Lo que esto significa es que todo el sistema de archivos contenedor pertenecerá al usuario especificado en el --userns-remap configuración del demonio231072 en el ejemplo anterior). Esto puede provocar un comportamiento inesperado de los programas dentro del contenedor. Por ejemplo sudo (que comprueba que sus binarios pertenecen al usuario 0) o binarios con setuid bandera.

Limitaciones conocidas del espacio de nombres de usuario

Las siguientes funciones estándar de Docker son incompatibles con la ejecución de un demonio de Docker con los espacios de nombres de usuario habilitados:

  • compartir espacios de nombres PID o NET con el host (--pid=host o --network=host).
  • controladores externos (volumen o almacenamiento) que no son conscientes o son incapaces de utilizar asignaciones de usuarios de demonios.
  • Utilizando el --privileged indicador de modo activado docker run sin especificar también --userns=host.

Los espacios de nombres de usuario son una característica avanzada y requieren coordinación con otras capacidades. Por ejemplo, si los volúmenes se montan desde el host, la propiedad del archivo debe estar preestablecida y necesita acceso de lectura o escritura al contenido del volumen.

Mientras que el usuario root dentro de un proceso contenedor con espacio de nombre de usuario tiene muchos de los privilegios esperados del superusuario dentro del contenedor, el kernel de Linux impone restricciones basadas en el conocimiento interno de que este es un proceso con espacio de nombre de usuario. Una restricción notable es la imposibilidad de utilizar el mknod mando. Se deniega el permiso para la creación de dispositivos dentro del contenedor cuando lo ejecuta el root usuario.

seguridad, espacios de nombres