Безопасные контейнеры SQL Server Linux

Применимо к:SQL Server — Linux

Контейнеры SQL Server 2017 (14.x) запускаются как корневой пользователь по умолчанию, что может вызвать некоторые проблемы безопасности. В этой статье рассказывается о параметрах безопасности, которые у вас есть при запуске контейнеров SQL Server Linux, а также о том, как создать контейнер SQL Server в качестве пользователя, не являющегося корневым пользователем.

В примерах этой статьи предполагается, что вы используете Docker, но вы можете применить те же принципы к другим средствам оркестрации контейнеров, включая Kubernetes.

Сборка и запуск контейнеров, не являющихся корневыми sql Server 2017

Выполните следующие действия, чтобы создать контейнер SQL Server 2017 (14.x), который запускается как mssql пользователь (не корневой).

Примечание.

Контейнеры для SQL Server 2019 (15.x) и более поздних версий автоматически запускались как не корневые, а контейнеры SQL Server 2017 (14.x) запускались как корневые по умолчанию. Дополнительные сведения о том, SQL Server контейнеры не являются корневыми, см. в статье Защита контейнеров Docker в SQL Server.

  1. Скачайте пример Dockerfile для контейнеров SQL Server, не являющихся корневыми, и сохраните его как dockerfile.

  2. Выполните следующую команду в контексте каталога dockerfile, чтобы выполнить сборку непривилегированного контейнера SQL Server:

    cd <path to dockerfile>
    docker build -t 2017-latest-non-root .
    
  3. Запустите контейнер.

    Важно!

    Переменная среды SA_PASSWORD является нерекомендуемой. Вместо этого используйте 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
    

    Примечание.

    Флаг --cap-add SYS_PTRACE необходим для создания дампов в целях устранения неполадок непривилегированных контейнеров SQL Server.

  4. Убедитесь в том, что контейнер запущен от имени пользователя, не являющегося привилегированным:

    docker exec -it sql1 bash
    

    Выполнение whoami, которое возвращает пользователя, работающего в контейнере.

    whoami
    

Запуск контейнера в качестве другого пользователя, не являющегося корневым пользователем на узле

Чтобы запустить контейнер SQL Server в качестве другого пользователя, не являющегося корневым, добавьте -u флаг в docker run команду. Контейнер, отличный от корневого root , имеет ограничение, которое оно должно выполняться как часть группы, если только том не подключен к /var/opt/mssql этому не корневому пользователю. Группа root не предоставляет дополнительных корневых разрешений пользователю, не относямуся к корневому каталогу.

Выполнение от имени пользователя с ИД пользователя 4000

SQL Server можно запускать с настраиваемым идентификатором пользователя. Например, следующая команда запускает SQL Server с 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

Предупреждение

Убедитесь, что контейнер SQL Server имеет именованного пользователя, например mssql или , в rootпротивном случае sqlcmd не сможет выполняться в контейнере. Вы можете проверить, выполняется ли контейнер SQL Server от имени именованного пользователя, запустив whoami в контейнере.

Запуск непривилегированного контейнера от имени привилегированного пользователя

При необходимости вы можете запустить контейнер, не являющийся корневым пользователем, который также предоставляет все разрешения на файлы автоматически контейнеру, так как он имеет более высокий уровень привилегий.

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

Запуск от имени пользователя на хост-компьютере

SQL Server можно запустить от имени существующего пользователя на хост-компьютере с помощью следующей команды:

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

Запуск от имени другого пользователя и группы

SQL Server можно запускать от имени произвольного пользователя и группы. В этом примере подключенный том имеет разрешения, настроенные для пользователя или группы на хост-компьютере.

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

Настройка разрешений постоянного хранилища для контейнеров, не являющихся корневыми

Чтобы разрешить не корневому пользователю получать доступ к файлам базы данных, подключенным томам, убедитесь, что пользователь или группа, в которых запущен контейнер, может считывать и записывать в постоянное хранилище файлов.

Узнать текущего владельца файлов базы данных можно с помощью приведенной ниже команды.

ls -ll <database file dir>

Выполните одну из следующих команд, если SQL Server не имеет доступа к сохраненным файлам базы данных.

Предоставление корневой группе доступа на чтение и запись к файлам базы данных

Предоставьте привилегированной группе разрешения на доступ к указанным ниже каталогам, чтобы у непривилегированного контейнера SQL Server был доступ к файлам базы данных.

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

Назначение непривилегированного пользователя владельцем файлов

Это может быть пользователь, отличный от корневого пользователя по умолчанию, или любой другой не корневой пользователь, который вы хотите указать. В этом примере в качестве непривилегированного пользователя задан пользователь с идентификатором 10001.

chown -R 10001:0 <database file dir>

Шифрование подключений к контейнерам SQL Server Linux

Важно!

При настройке проверки подлинности Или шифрования Active Directory, таких как прозрачное шифрование данных (TDE) и SSL для SQL Server на Linux или контейнеров, существует несколько файлов, таких как keytab, сертификаты и ключ компьютера, созданные по умолчанию в папке/var/opt/mssql/secrets, и доступ к которому по умолчанию mssql ограничен пользователями.root При настройке сохраняемого хранилища для контейнеров SQL Server используйте ту же стратегию доступа, чтобы путь к узлу или общему тому, сопоставленному с /var/opt/mssql/secrets папкой внутри контейнера, был защищен и доступен только mssqlroot пользователям на узле. Если доступ к этому пути или папке скомпрометирован, злоумышленник может получить доступ к этим критически важным файлам, компрометируя иерархию шифрования и (или) конфигурации Active Directory.

Для шифрования подключений к контейнерам SQL Server Linux требуется сертификат со следующими требованиями.

Ниже приведен пример шифрования подключения к контейнерам SQL Server Linux. Здесь мы используем самозаверяющий сертификат, который не следует использовать для рабочих сценариев. Для таких сред вместо этого следует использовать сертификаты ЦС.

  1. Создайте самозаверяющий сертификат, который подходит только для тестовых и нерабочих сред.

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

    В предыдущем примере sql1 кода используется имя узла контейнера SQL, поэтому при подключении к этому контейнеру имя, используемое в строка подключения, будетsql1.contoso.com,port. Необходимо также убедиться, что путь /container/sql1/ к папке уже существует перед выполнением приведенной выше команды.

  2. Убедитесь, что вы устанавливаете правильные разрешения для mssql.key файлов и mssql.pem файлов, поэтому при подключении файлов к контейнеру SQL Server можно избежать ошибок.

    chmod 440 /container/sql1/mssql.pem
    chmod 440 /container/sql1/mssql.key
    
  3. Теперь создайте mssql.conf файл с приведенным ниже содержимым, чтобы включить шифрование, инициированное сервером. Для шифрования, инициированного клиентом, измените последнюю строку forceencryption = 0на .

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

    Примечание.

    Для некоторых дистрибутивов Linux путь для хранения сертификата и ключа также может быть следующим: /etc/pki/tls/certs/ и /etc/pki/tls/private/ соответственно. Перед обновлением mssql.conf контейнеров SQL Server проверьте путь. Расположение, заданное в mssql.conf этом поле, будет расположением, в котором SQL Server в контейнере будет искать сертификат и его ключ. В этом случае это расположение и /etc/ssl/certs//etc/ssl/private/.

    Файл mssql.conf также создается в том же расположении /container/sql1/папки. После выполнения описанных выше действий необходимо иметь три файла: mssql.conf, mssql.keyи mssql.pem в папке sql1 .

  4. Разверните контейнер SQL Server с помощью следующей команды:

    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
    

    В предыдущей команде мы подключили mssql.confmssql.pemmssql.key и файлы к контейнеру и сопоставили порт 1433 (порт по умолчанию SQL Server) в контейнере с портом 5434 на узле.

    Примечание.

    Если вы используете RHEL 8 и более поздних версий, вы также можете использовать podman run команду вместо docker run.

Следуйте указаниям в подразделах "Регистрация сертификата на клиентском компьютере" и "Примеры строк подключения" в разделе Шифрование, инициированное клиентом, чтобы начать шифрование подключений к контейнерам SQL Server в Linux.

  • Сведения о начале работы с образами контейнеров с SQL Server 2017 (14.x) в Docker можно найти в кратком руководстве
  • Сведения о начале работы с образами контейнеров с SQL Server 2019 (15.x) в Docker можно найти в кратком руководстве
  • Начало работы с образами контейнеров SQL Server 2022 (16.x) в Docker, выполнив краткое руководство.