保護 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 容器,請將 -u 旗標新增至 docker run 命令。 非根容器包含限制,除非磁碟區是掛接到非根使用者可存取的 /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

警告

請確定 SQL Server 容器具有像是 mssqlroot 等具名使用者,否則 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 容器的連線

重要

設定 Active Directory 驗證或加密選項 (例如透明資料加密 (TDE) 和 Linux 上的 SQL Server 或容器的 SSL) 時,會有數個檔案 (例如金鑰表、憑證和電腦金鑰) 預設會建立在 /var/opt/mssql/secrets 資料夾下,且其存取權預設會限制給 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.confmssql.keymssql.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 命令。

遵循記載於用戶端起始加密中的「在用戶端電腦上註冊憑證」與「範例連接字串」區段,開始為 Linux 容器上 SQL Server 的連線加密。

  • 透過此快速入門,開始使用 Docker 上的 SQL Server 2017 (14.x) 容器映像
  • 透過此快速入門,開始使用 Docker 上的 SQL Server 2019 (15.x) 容器映像
  • 透過此快速入門,開始使用 Docker 上的 SQL Server 2022 (16.x) 容器映像