Безопасные контейнеры SQL Server Linux
Область применения: SQL Server — Linux
Контейнеры SQL Server 2017 (14.x) запускаются как корневой пользователь по умолчанию, что может вызвать некоторые проблемы безопасности. В этой статье рассказывается о параметрах безопасности, которые у вас есть при запуске контейнеров SQL Server Linux, а также о том, как создать контейнер SQL Server в качестве пользователя, не являющегося корневым пользователем.
В примерах этой статьи предполагается, что вы используете Docker, но вы можете применить те же принципы к другим средствам оркестрации контейнеров, включая Kubernetes.
Сборка и запуск контейнеров SQL Server 2017, не работающих с правами root
Выполните следующие действия, чтобы создать контейнер SQL Server 2017 (14.x), который запускается от имени пользователя mssql
(без root-прав).
Примечание.
Контейнеры для SQL Server 2019 (15.x) и более поздних версий автоматически запускались как не корневые, а контейнеры SQL Server 2017 (14.x) запускались как корневые по умолчанию. Дополнительные сведения о запуске контейнеров SQL Server в качестве не корневых, см. в разделе "Безопасные контейнеры SQL Server Linux".
Скачайте пример Dockerfile для контейнеров SQL Server, не являющихся корневыми, и сохраните его как
dockerfile
.Выполните следующую команду в контексте каталога dockerfile, чтобы выполнить сборку непривилегированного контейнера SQL Server:
cd <path to dockerfile> docker build -t 2017-latest-non-root .
Запустите контейнер.
Внимание
Переменная среды
SA_PASSWORD
является нерекомендуемой. Вместо этого используйтеMSSQL_SA_PASSWORD
.docker run -e "ACCEPT_EULA=Y" -e "MSSQL_SA_PASSWORD=<password>" --cap-add SYS_PTRACE --name sql1 -p 1433:1433 -d 2017-latest-non-root
Примечание.
Флаг
--cap-add SYS_PTRACE
необходим, чтобы непривилегированные контейнеры SQL Server могли создавать дампы в целях устранения неполадок.Убедитесь в том, что контейнер запущен от имени пользователя, не являющегося привилегированным:
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=<password>" --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
в контейнере.
Запуск непривилегированного контейнера от имени привилегированного пользователя
При необходимости вы можете запустить контейнер как root-пользователь, что автоматически предоставляет контейнеру все разрешения на файлы благодаря более высоким привилегиям.
docker run -e "ACCEPT_EULA=Y" -e "MSSQL_SA_PASSWORD=<password>" -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=<password>" --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=<password>" --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 не имеет доступа к сохраненным файлам базы данных.
Предоставление корневой группе доступа на чтение и запись к файлам базы данных
Предоставьте разрешения группы root на указанные ниже каталоги, чтобы у не-root контейнера 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
внутри контейнера, был защищен и доступен только для mssql
и root
пользователей на узле. Если доступ к этому пути или папке скомпрометирован, злоумышленник может получить доступ к этим критически важным файлам, компрометируя иерархию шифрования и (или) конфигурации Active Directory.
Для шифрования подключений к контейнерам SQL Server Linux требуется сертификат со следующими требованиями.
Ниже приведен пример шифрования подключения к контейнерам SQL Server Linux. Здесь мы используем самозаверяющий сертификат, который не следует использовать для рабочих сценариев. Для таких сред вместо этого следует использовать сертификаты ЦС.
Создайте самозаверяющий сертификат, который подходит только для тестовых и нерабочих сред.
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/
к папке уже существует перед выполнением приведенной выше команды.Убедитесь, что вы устанавливаете правильные разрешения для
mssql.key
файлов иmssql.pem
файлов, поэтому при подключении файлов к контейнеру SQL Server можно избежать ошибок.chmod 440 /container/sql1/mssql.pem chmod 440 /container/sql1/mssql.key
Теперь создайте
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
.Разверните контейнер 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.conf
mssql.pem
mssql.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, воспользовавшись кратким руководством.