Proteger contêineres do SQL Server no Linux

Aplica-se a: SQL Server – Linux

Contêineres do SQL Server 2017 (14.x) são iniciados como o usuário raiz por padrão, o que pode causar algumas preocupações de segurança. Este artigo aborda as opções de segurança disponíveis ao executar contêineres do SQL Server no Linux e como criar um contêiner do SQL Server como um usuário não raiz.

Os exemplos neste artigo pressupõem que você esteja usando o Docker, mas você pode aplicar os mesmos princípios a outras ferramentas de orquestração de contêiner, incluindo o Kubernetes.

Compilar e executar contêineres não raiz do SQL Server 2017

Siga estas etapas para criar um contêiner do SQL Server 2017 (14.x) que é iniciado como o usuário mssql (não raiz).

Observação

Contêineres para SQL Server 2019 (15.x) e versões posteriores iniciam automaticamente como não raiz, enquanto os contêineres do SQL Server 2017 (14.x) iniciam como raiz por padrão. Confira mais informações sobre como executar contêineres de SQL Server como não raiz em Configurar a segurança.

  1. Baixe o Dockerfile de exemplo para contêineres do SQL Server não raiz e salve-o como dockerfile.

  2. Execute o seguinte comando no contexto do diretório do Dockerfile para criar o contêiner de SQL Server não raiz:

    cd <path to dockerfile>
    docker build -t 2017-latest-non-root .
    
  3. Inicie o contêiner.

    Importante

    A variável de ambiente SA_PASSWORD foi preterida. Use MSSQL_SA_PASSWORD em vez disso.

    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
    

    Observação

    O sinalizador --cap-add SYS_PTRACE é necessário para contêineres de SQL Server não raiz para gerar despejos para fins de solução de problemas.

  4. Verifique se o contêiner está sendo executado como um usuário não raiz:

    docker exec -it sql1 bash
    

    Execute whoami, que retorna o usuário em execução dentro do contêiner.

    whoami
    

Executar o contêiner como um usuário não raiz diferente no host

Para executar o contêiner do SQL Server como um usuário não raiz diferente, adicione o sinalizador -u ao comando docker run. O contêiner não raiz tem a restrição de que precisa ser executado como parte do grupo root, a menos que um volume seja montado em /var/opt/mssql, ao qual o usuário não raiz tenha acesso. O grupo root não concede permissões de raiz extras ao usuário não raiz.

Executar como um usuário com UID 4000

Você pode iniciar o SQL Server com uma UID personalizada. Por exemplo, o seguinte comando inicia o SQL Server com 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

Aviso

Garanta que o contêiner do SQL Server tem um usuário nomeado como mssql ou root. Caso contrário, sqlcmd não poderá ser executado dentro do contêiner. Você pode verificar se o contêiner do SQL Server está sendo executado como um usuário nomeado executando whoami dentro do contêiner.

Executar o contêiner não raiz como o usuário raiz

Você pode executar o contêiner não raiz como o usuário raiz, se necessário, que também concede todas as permissões de arquivo automaticamente ao contêiner, pois ele tem privilégios mais altos.

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

Executar como um usuário em seu computador host

Você pode iniciar o SQL Server com um usuário existente no computador host com o seguinte comando:

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

Executar como um usuário e grupo diferentes

Você pode iniciar o SQL Server com um usuário e um grupo personalizados. Neste exemplo, o volume montado tem permissões configuradas para o usuário ou o grupo no computador 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

Configurar permissões de armazenamento persistente para contêineres não raiz

Para permitir que o usuário não raiz acesse arquivos de banco de dados que estão em volumes montados, garanta que o usuário ou o grupo no qual o contêiner é executado pode fazer leituras/gravações do/no armazenamento de arquivos persistente.

Você pode obter a propriedade atual dos arquivos de banco de dados com este comando.

ls -ll <database file dir>

Execute um dos comandos a seguir se o SQL Server não tiver acesso aos arquivos de banco de dados persistentes.

Conceder ao grupo raiz acesso de leitura/gravação aos arquivos de banco de dados

Conceda as permissões do grupo raiz aos seguintes diretórios para que o contêiner do SQL Server não raiz tenha acesso aos arquivos de banco de dados.

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

Definir o usuário não raiz como o proprietário dos arquivos

Esse pode ser o usuário não raiz padrão ou qualquer outro usuário não raiz que você queira especificar. Neste exemplo, definimos a UID 10001 como o usuário não raiz.

chown -R 10001:0 <database file dir>

Criptografar conexões com os contêineres do SQL Server no Linux

Importante

Ao configurar opções de autenticação ou criptografia do Active Directory, como TDE (Transparent Data Encryption) e SSL para SQL Server em Linux ou contêineres, há vários arquivos, como o keytab, os certificados e a chave do computador, que são criados por padrão na pasta /var/opt/mssql/secrets, e o acesso a ela é restrito por padrão aos usuários mssql e root. Ao configurar o armazenamento persistente para contêineres do SQL Server, use a mesma estratégia de acesso, garantindo que o caminho no host ou no volume compartilhado mapeado para a pasta /var/opt/mssql/secrets dentro do contêiner esteja protegido e acessível somente pelos usuários mssql e root no host também. Se o acesso a esse caminho/pasta estiver comprometido, um usuário mal-intencionado poderá obter acesso a esses arquivos críticos, comprometendo a hierarquia de criptografia e/ou as configurações do Active Directory.

Para criptografar conexões com os contêineres do SQL Server no Linux, você precisará de um certificado com os requisitos a seguir.

A seguir está um exemplo de como a conexão pode ser criptografada para os contêineres do SQL Server no Linux. Aqui, usamos um certificado autoassinado, que não deve ser usado para cenários de produção. Para esses ambientes, você deve usar certificados de AC.

  1. Crie um certificado autoassinado, que é adequado somente para ambientes de teste e de não produção.

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

    No exemplo de código anterior, sql1 é o nome do host do contêiner de SQL, portanto, ao se conectar a esse contêiner, o nome usado na cadeia de conexão será sql1.contoso.com,port. Você também precisa verificar se o caminho da pasta /container/sql1/ já existe antes de executar o comando acima.

  2. Certifique-se de definir as permissões corretas nos arquivos mssql.key e mssql.pem, para evitar erros ao montar os arquivos no contêiner do SQL Server:

    chmod 440 /container/sql1/mssql.pem
    chmod 440 /container/sql1/mssql.key
    
  3. Agora crie um arquivo mssql.conf com o conteúdo abaixo para habilitar a criptografia iniciada pelo servidor. Para a criptografia iniciada pelo cliente, altere a última linha para forceencryption = 0.

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

    Observação

    Para algumas distribuições do Linux, o caminho para armazenar o certificado e a chave também pode ser /etc/pki/tls/certs/ e /etc/pki/tls/private/, respectivamente. Verifique o caminho antes de atualizar o mssql.conf para contêineres do SQL Server. A localização definida no mssql.conf será a localização que o SQL Server no contêiner usará para pesquisar o certificado e a chave. Nesse caso, esse local é /etc/ssl/certs/ e /etc/ssl/private/.

    O arquivo mssql.conf também é criado na mesma localização da pasta /container/sql1/. Após executar as etapas acima, você deve ter três arquivos: mssql.conf, mssql.key e mssql.pem na pasta sql1.

  4. Implante o contêiner do SQL Server com o seguinte 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
    

    No comando anterior, montamos os arquivos mssql.conf, mssql.pem e mssql.key para o contêiner e mapeamos a porta 1433 (porta padrão do SQL Server) no contêiner para a porta 5434 no host.

    Observação

    Se você estiver usando o RHEL 8 e superiores, também poderá usar o comando podman run em vez de docker run.

Siga as seções "Registrar o certificado no computador cliente" e "Cadeias de conexão de exemplo" documentadas em Criptografia iniciada pelo cliente para iniciar a criptografia de conexões aos contêineres do SQL Server no Linux.

  • Comece a usar as imagens de contêiner do SQL Server 2017 (14.x) no Docker acompanhando o guia de início rápido
  • Comece a usar as imagens de contêiner do SQL Server 2019 (15.x) no Docker acompanhando o guia de início rápido
  • Comece a usar as imagens de contêiner do SQL Server 2022 (16.x) no Docker acompanhando o guia de início rápido