SQL Server Linux 컨테이너 보호

적용 대상:SQL Server - Linux

SQL Server 2017(14.x) 컨테이너는 기본적으로 루트 사용자로 시작하므로 일부 보안 문제가 발생할 수 있습니다. 이 문서에서는 SQL Server Linux 컨테이너를 실행할 때의 보안 옵션 및 SQL Server 컨테이너를 루트가 아닌 사용자로 빌드하는 방법을 설명합니다.

이 문서의 예제에서는 Docker를 사용한다고 가정하지만 Kubernetes를 비롯한 다른 컨테이너 오케스트레이션 도구에 동일한 원칙을 적용할 수 있습니다.

루트가 아닌 SQL Server 2017 컨테이너를 빌드하여 실행

다음 단계에 따라 (루트가 아닌) 사용자로 mssql 시작하는 SQL Server 2017(14.x) 컨테이너를 빌드합니다.

참고 항목

SQL Server 2019(15.x) 이상 버전의 컨테이너는 자동으로 루트가 아닌 것으로 시작되고 SQL Server 2017(14.x) 컨테이너는 기본적으로 루트로 시작됩니다. 루트가 아닌 형식으로 SQL Server 컨테이너를 실행하는 방법에 대한 자세한 정보는 보안 구성을 참조하세요.

  1. 루트가 아닌 SQL Server 컨테이너에 대한 샘플 Dockerfile을 다운로드하고 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 컨테이너를 다른 루트가 아닌 사용자로 실행하려면 docker run 명령에 -u 플래그를 추가합니다. 루트가 아닌 사용자가 액세스할 수 있는 /var/opt/mssql에 볼륨이 탑재되지 않은 경우 루트가 아닌 컨테이너를 root 그룹의 일부로 실행해야 한다는 제한 사항이 있습니다. root 그룹은 루트가 아닌 사용자에게 추가 루트 권한을 부여하지 않습니다.

UID 4000을 갖는 사용자로 실행

사용자 지정 UID를 사용하여 SQL Server를 시작할 수 있습니다. 예를 들어 다음 명령은 UID 4000으로 SQL Server를 시작합니다.

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

Warning

SQL Server 컨테이너에 명명된 사용자(예: mssql 또는 root그렇지 않으면 sqlcmd )가 컨테이너 내에서 실행할 수 없는지 확인합니다. 컨테이너 내에서 whoami를 실행하여 SQL Server 컨테이너가 명명된 사용자로 실행되고 있는지 확인할 수 있습니다.

루트가 아닌 컨테이너를 루트 사용자 권한으로 실행

필요한 경우 루트가 아닌 컨테이너를 루트 사용자로 실행할 수 있습니다. 이 사용자는 더 높은 권한을 가지므로 모든 파일 권한을 컨테이너에 자동으로 부여합니다.

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>

루트가 아닌 사용자를 파일의 소유자로 설정

이것은 기본 루트가 아닌 사용자이거나 지정하려는 다른 루트가 아닌 사용자일 수 있습니다. 이 예제에서는 UID 10001을 루트가 아닌 사용자로 설정합니다.

chown -R 10001:0 <database file dir>

SQL Server Linux 컨테이너에 대한 연결 암호화

중요

SQL Server on Linux 또는 컨테이너에 대한 TDE(투명한 데이터 암호화) 및 SSL과 같은 Active Directory 인증 또는 암호화 옵션을 구성할 때 기본적으로 폴더 /var/opt/mssql/secrets 아래에 만들어지는 keytab, 인증서 및 컴퓨터 키와 같은 여러 파일이 있으며, 액세스는 기본적으로 mssqlroot 사용자로 제한됩니다. SQL Server 컨테이너에 대한 영구 스토리지를 구성하는 경우 동일한 액세스 전략을 사용하여 컨테이너 내의 /var/opt/mssql/secrets 폴더에 매핑된 호스트 또는 공유 볼륨의 경로가 보호되고 호스트의 mssqlroot 사용자만 액세스할 수 있도록 하세요. 이 경로/폴더에 대한 액세스가 손상되면 악의적인 사용자가 이러한 중요한 파일에 액세스하여 암호화 계층 및/또는 Active Directory 구성을 손상시킬 수 있습니다.

SQL Server Linux 컨테이너에 대한 연결을 암호화하려면 다음 요구 사항이 있는 인증서가 필요합니다.

다음은 SQL Server Linux 컨테이너에 대한 연결을 암호화하는 방법의 예입니다. 여기서는 프로덕션 시나리오에 사용하면 안 되는 자체 서명된 인증서를 사용합니다. 해당 환경의 경우 CA 인증서를 대신 사용해야 합니다.

  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.keymssql.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/이 될 수도 있습니다. SQL Server 컨테이너에 대한 mssql.conf를 업데이트하기 전에 경로를 확인하세요. mssql.conf에서 설정한 위치는 컨테이너의 SQL Server가 인증서와 해당 키를 검색할 위치가 됩니다. 이 경우 해당 위치는 /etc/ssl/certs//etc/ssl/private/입니다.

    mssql.conf 파일도 동일한 폴더 위치인 /container/sql1/ 아래에 생성됩니다. 위 단계를 실행한 후 mssql.conf, mssql.key, mssql.pem의 3개 파일이 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.pem하고 mssql.key 컨테이너의 1433(SQL Server 기본 포트) 포트를 호스트의 포트 5434에 매핑했습니다.

    참고 항목

    RHEL 8 이상을 사용하는 경우 docker run 대신 podman run 명령을 사용할 수도 있습니다.

"클라이언트 컴퓨터에 인증서 등록" 및 클라이언트 시작 암호화에 설명된 "연결 문자열 예제" 섹션에 따라 Linux 컨테이너에서 SQL Server에 대한 연결 암호화를 시작합니다.

  • 빠른 시작을 진행하여 Docker에서 SQL Server 2017(14.x) 컨테이너 이미지로 시작합니다.
  • 빠른 시작을 진행하여 Docker에서 SQL Server 2019(15.x) 컨테이너 이미지로 시작합니다.
  • 빠른 시작을 진행하여 Docker에서 SQL Server 2022(16.x) 컨테이너 이미지로 시작합니다.