Protección de contenedores de SQL Server en Linux

Se aplica a:SQL Server: Linux

Los contenedores de SQL Server 2017 (14.x) se inician como el usuario raíz de forma predeterminada, lo que puede causar algunos problemas de seguridad. En este artículo se describen las opciones de seguridad que existen al ejecutar contenedores de SQL Server en Linux y cómo crear un contenedor de SQL Server como un usuario no raíz.

En los ejemplos de este artículo se supone que usa Docker, pero puede aplicar los mismos principios a otras herramientas de orquestación de contenedores, incluido Kubernetes.

Compilación y ejecución de contenedores no raíz de SQL Server 2017

Siga estos pasos para compilar un contenedor de SQL Server 2017 (14.x) que se inicie como el usuario mssql (no raíz).

Nota

Los contenedores de SQL Server 2019 (15.x) y versiones posteriores se inician automáticamente como no raíz, mientras que los contenedores de SQL Server 2017 (14.x) se inician como raíz de manera predeterminada. Para obtener más información sobre cómo ejecutar contenedores de SQL Server como no raíz, consulte Configuración de la seguridad.

  1. Descargue el Dockerfile de ejemplo para contenedores de SQL Server no raíz y guárdelo como dockerfile.

  2. Ejecute el comando siguiente en el contexto del directorio del dockerfile para compilar el contenedor de SQL Server no raíz:

    cd <path to dockerfile>
    docker build -t 2017-latest-non-root .
    
  3. Inicie el contenedor.

    Importante

    La variable de entorno SA_PASSWORD está en desuso. En su lugar, use MSSQL_SA_PASSWORD.

    docker run -e "ACCEPT_EULA=Y" -e "MSSQL_SA_PASSWORD=MyStrongPassword@" --cap-add SYS_PTRACE --name sql1 -p 1433:1433 -d 2017-latest-non-root
    

    Nota

    La marca --cap-add SYS_PTRACE es obligatoria para que los contenedores de SQL Server no raíz generen volcados con fines de solución de problemas.

  4. Compruebe que el contenedor se ejecuta como usuario no raíz:

    docker exec -it sql1 bash
    

    Ejecute whoami, que devuelve el usuario que se ejecuta en el contenedor.

    whoami
    

Ejecución del contenedor como otro usuario no raíz en el host

Para ejecutar el contenedor de SQL Server como otro usuario no raíz, agregue la marca -u al comando docker run. El contenedor no raíz tiene la restricción de que se debe ejecutar como parte del grupo root a menos que haya un volumen montado en /var/opt/mssql con acceso para el usuario no raíz. El grupo root no concede ningún permiso de raíz adicional al usuario no raíz.

Ejecutar como usuario con un UID 4000

Puede iniciar SQL Server con un UID personalizado. Por ejemplo, el comando siguiente inicia SQL Server con UID 4000:

docker run -e "ACCEPT_EULA=Y" -e "MSSQL_SA_PASSWORD=MyStrongPassword" --cap-add SYS_PTRACE -u 4000:0 -p 1433:1433 -d mcr.microsoft.com/mssql/server:2019-latest

Advertencia

Asegúrese de que el contenedor de SQL Server tiene un usuario con nombre como mssql o root. De lo contrario, sqlcmd no se podrá ejecutar dentro del contenedor. Puede comprobar si el contenedor de SQL Server se ejecuta como un usuario con nombre mediante la ejecución de whoami en el contenedor.

Ejecutar el contenedor no raíz como el usuario raíz

Puede ejecutar el contenedor no raíz como usuario raíz si es necesario, lo que también concede automáticamente todos los permisos de archivo al contenedor, ya que tiene privilegios más elevados.

docker run -e "ACCEPT_EULA=Y" -e "MSSQL_SA_PASSWORD=MyStrongPassword" -u 0:0 -p 1433:1433 -d mcr.microsoft.com/mssql/server:2019-latest

Ejecutar como un usuario en el equipo host

Puede iniciar SQL Server con un usuario existente en el equipo host con el comando siguiente:

docker run -e "ACCEPT_EULA=Y" -e "MSSQL_SA_PASSWORD=MyStrongPassword" --cap-add SYS_PTRACE -u $(id -u myusername):0 -p 1433:1433 -d mcr.microsoft.com/mssql/server:2019-latest

Ejecutar como otro usuario y grupo

Puede iniciar SQL Server con un grupo y un usuario personalizados. En este ejemplo, el volumen montado tiene permisos configurados para el usuario o grupo en el equipo host.

docker run -e "ACCEPT_EULA=Y" -e "MSSQL_SA_PASSWORD=MyStrongPassword" --cap-add SYS_PTRACE -u $(id -u myusername):$(id -g myusername) -v /path/to/mssql:/var/opt/mssql -p 1433:1433 -d mcr.microsoft.com/mssql/server:2019-latest

Configuración de permisos de almacenamiento persistentes para contenedores no raíz

Para permitir que el usuario no raíz acceda a los archivos de base de datos que se encuentran en volúmenes montados, asegúrese de que el usuario o grupo en el que se ejecuta el contenedor pueda leer o escribir en el almacenamiento de archivos persistente.

Puede obtener la propiedad actual de los archivos de base de datos con este comando.

ls -ll <database file dir>

Ejecute uno de los comandos siguientes si SQL Server no tiene acceso a los archivos de base de datos persistentes.

Concesión al grupo raíz de acceso de lectura y escritura para los archivos de base de datos

Conceda al grupo raíz permisos a los directorios siguientes para que el contenedor de SQL Server no raíz tenga acceso a los archivos de base de datos.

chgrp -R 0 <database file dir>
chmod -R g=u <database file dir>

Establecimiento del usuario no raíz como el propietario de los archivos

Puede ser el usuario no raíz predeterminado o cualquier otro usuario no raíz que quiera especificar. En este ejemplo, se establece el UID 10001 como usuario no raíz.

chown -R 10001:0 <database file dir>

Cifrado de las conexiones a contenedores de SQL Server en Linux

Importante

Al configurar las opciones de cifrado o autenticación de Active Directory, como cifrado de datos transparente (TDE) y SSL para SQL Server en Linux o contenedores, hay varios archivos, como keytab, certificados y clave de máquina, que se crean de forma predeterminada en la carpeta /var/opt/mssql/secrets, y a los que los usuarios mssql y root tienen acceso restringido de forma predeterminada. Al configurar el almacenamiento persistente para contenedores de SQL Server, use la misma estrategia de acceso y asegúrese de que la ruta de acceso del host o del volumen compartido asignado a la carpeta /var/opt/mssql/secrets dentro del contenedor también está protegida y es accesible solo para los usuarios mssql y root del host. Si se pone en peligro el acceso a esta ruta de acceso o carpeta, un usuario malintencionado podría obtener acceso a estos archivos críticos, poniendo en peligro la jerarquía de cifrado y/o las configuraciones de Active Directory.

Para cifrar conexiones a los contenedores de SQL Server en Linux, necesita un certificado que cumpla estos requisitos.

A continuación, se muestra un ejemplo de cómo se cifra la conexión para contenedores de SQL Server en Linux. Se usa un certificado autofirmado, que no se debe usar para escenarios de producción. Para dichos entornos, debe usar certificados de entidad de certificación.

  1. Cree un certificado autofirmado, que será adecuado solo para entornos de prueba y entornos que no sean de producción.

    openssl req -x509 -nodes -newkey rsa:2048 -subj '/CN=sql1.contoso.com' -keyout /container/sql1/mssql.key -out /container/sql1/mssql.pem -days 365
    

    En el ejemplo de código precedente, sql1 es el nombre de host del contenedor de SQL, por lo que, al conectarse a este contenedor, el nombre que se usará en la cadena de conexión será sql1.contoso.com,port. Antes de ejecutar el comando anterior, asegúrese de que la ruta de acceso a la carpeta /container/sql1/ exista.

  2. Asegúrese de establecer los permisos adecuados en los archivos mssql.key y mssql.pem para evitar errores al montar los archivos en el contenedor de SQL Server:

    chmod 440 /container/sql1/mssql.pem
    chmod 440 /container/sql1/mssql.key
    
  3. Ahora, cree un archivo mssql.conf con el contenido a continuación para habilitar el cifrado iniciado por el servidor. En el cifrado iniciado por el cliente, cambie la última línea a forceencryption = 0.

    [network]
    tlscert = /etc/ssl/certs/mssql.pem
    tlskey = /etc/ssl/private/mssql.key
    tlsprotocols = 1.2
    forceencryption = 1
    

    Nota

    En algunas distribuciones de Linux, las rutas de acceso para almacenar el certificado y la clave también podrían ser las siguientes: /etc/pki/tls/certs/ y /etc/pki/tls/private/, respectivamente. Compruebe la ruta de acceso antes de actualizar el mssql.conf para contenedores de SQL Server. La ubicación que establezca en el mssql.conf será la ubicación en la que la instancia de SQL Server del contenedor buscará el certificado y su clave. En este caso, esa ubicación es /etc/ssl/certs/ y /etc/ssl/private/.

    El archivo mssql.conf también se crea en la misma ubicación de carpeta /container/sql1/. Una vez ejecutados los pasos anteriores, debería tener tres archivos, mssql.conf, mssql.key y mssql.pem, en la carpeta sql1.

  4. Implemente el contenedor de SQL Server con el siguiente comando:

    docker run -e "ACCEPT_EULA=Y" -e "MSSQL_SA_PASSWORD=P@ssw0rd" -p 5434:1433 --name sql1 -h sql1 -v /container/sql1/mssql.conf:/var/opt/mssql/mssql.conf -v   /container/sql1/mssql.pem:/etc/ssl/certs/mssql.pem -v /container/sql1/mssql.key:/etc/ssl/private/mssql.key -d mcr.microsoft.com/mssql/server:2019-latest
    

    En el comando anterior, hemos montado los archivos mssql.conf, mssql.pem y mssql.key en el contenedor y hemos asignado el puerto 1433 (puerto predeterminado de SQL Server) del contenedor al puerto 5434 del host.

    Nota

    Si usa RHEL 8 o una versión posterior, también puede usar el comando podman run en lugar de docker run.

Siga las secciones "Registro del certificado en la máquina cliente" y "Cadenas de conexión de ejemplo "que se documentan en Cifrado iniciado por el cliente a fin de iniciar el cifrado de las conexiones para los contenedores de SQL Server en Linux.

  • Para empezar a trabajar con imágenes de contenedor de SQL Server 2017 (14.x) en Docker, revise el inicio rápido
  • Para empezar a trabajar con imágenes de contenedor de SQL Server 2019 (15.x) en Docker, revise el inicio rápido
  • Para empezar a trabajar con imágenes de contenedor de SQL Server 2022 (16.x) en Docker, revise el inicio rápido