1. 程式人生 > >使用Linux docker容器中的整合安全性對SQL Server的.Net Core客戶端進行身份驗證

使用Linux docker容器中的整合安全性對SQL Server的.Net Core客戶端進行身份驗證

目錄

面對問題

逐步發現解決方案

先決條件

我們的演示應用

在容器中準備kerberos身份驗證

KDC消費所需的包

建立一個合適的krb5.conf檔案

生成keytab檔案

Docker化演示應用程式

處理kerberos票證的到期日期

處理keytab檔案的到期日期

執行


說明.Net Core應用程式的實現,在linux容器中執行,連線到具有整合安全性的SQL Server資料庫。

面對問題

如果使用SQL Server.Net應用程式進行docker化,則必須考慮連線資料庫的方法。

幸運的是,Microsoft為我們提供了幾個建立安全可靠連線的機會,這些連線也可以應用於

Windows容器。但是,在連線linux容器的情況下,並不是所有這些概念都是開箱即用的。這還影響整合安全性的使用,以便從已經過身份驗證的客戶端(例如:單點登入系統)建立連線。

本文適用於Linux容器的整合安全性概念,它構建於kerberos身份驗證過程之上。該解決方案不需要在.Net Core應用程式中進行程式碼更改。相反,它說明了在系統級別上的docker映象預備和kerberos身份驗證的配置。最後,您可以通過整合安全性連線到以前經過身份驗證的Linux容器中的SQL Server

逐步發現解決方案

對於這個解決方案,在我們能夠建立解決方案之前,我們必須走更長的路,拾起一個更大的拼圖塊。

先決條件

在您的環境中重建解決方案所需的一切:

  • Docker主機(例如:windows上的dockerdocker tool box ......
  • 啟用了整合安全性的SQL Server例項(內部部署甚至是容器化)
  • 域控制器(AD充當金鑰分發伺服器)

我們的演示應用

為了驗證資料庫連線,我建立了一個非常簡單的解決方案。該應用程式掛在一個無限迴圈中,查詢SQL Server例項myDataBaseServer的資料庫myDataBase的特定表dat.MyDataTable。檢索結果集(我假設MyDataTable包含至少三列)列印為控制檯輸出,可以通過附加到容器來檢視。

using System;
using System.Data.SqlClient;

namespace MyApplication
{
    class Program
    {
        static void Main(string[] args)
        {
            while (true)
            {
                try
                {
                    using (var connection = new SqlConnection("Server=tcp:myDataBaseServer,46005;Initial Catalog=myDataBase;Integrated Security=true;;"))
                    {
                        var command = new SqlCommand("SELECT TOP 10 * FROM dat.myDataTable", connection);
                        connection.Open();
                        using (var reader = command.ExecuteReader())
                        {
                            while (reader.Read())
                            {
                                Console.WriteLine($"{reader[0]}:{reader[1]} ${reader[2]}");
                            }
                        }
                    }
                }
                catch (Exception ex)
                {
                    Console.Write(ex);
                }

                System.Threading.Thread.Sleep(10000);
            }
        }
    }
}

請考慮指定整合安全性的連線字串:

"Server=tcp:myDataBaseServer,46005;Initial Catalog=myDataBase;Integrated Security=true;;"

在容器中準備kerberos身份驗證

為了通過金鑰分發中心(KDC)與Linux容器進行通訊,需要對容器映像和配置進行一些準備。

  1. 安裝KDC消費包。
  2. 建立適當的krb5.conf檔案以訪問AD域控制器中託管的KDC應用程式
  3. 生成keytab檔案(以避免以純文字形式暴露密碼)

KDC消費所需的包

演示應用程式執行在Microsoft/dotnet:aspnetcore執行時映像上該映像主要來自debian:stretch slim映像這要求我們安裝以下包(從dockerfile底層貼上的程式碼):

...
RUN apt install -y krb5-config 
RUN apt-get install -y krb5-user
...

這些pacakges使我們能夠在容器內執行kinit命令,以便從KDC獲取kerberos票證。另外還有ktutil工具可用於建立上述提到的keytab檔案。

建立一個合適的krb5.conf檔案

為了與底層KDC進行通訊,將建立一個正確的krb5.conf檔案並將其儲存在containers/etc資料夾中。為了構造一個正確的例子,假設我們在域my.company.local,我們的KDCmydomaincontroller.my.company.local提供(在Windows AD驅動的環境中,你可以通過簡單地執行命令echo logonserver 獲得mydomaincontroller的值,當你通過AD記錄時)。還要記住,KDC位於域控制器中並使用AD資料庫。

# /etc/krb5.conf -- Kerberos V5 general configuration.
# $Id: krb5.conf,v 1.43 2011/09/23 00:37:20 eagle Exp $
#
# This is my default Kerberos v5 configuration file.  The
# canonical location of this file is http://www...
#
# This configuration allows any enctypes.  Some systems with really old
# Kerberos software may have to limit to triple-DES and DES.

[appdefaults]
    default_lifetime      = 25hrs
    krb4_convert          = false
    krb4_convert_524      = false

    ksu = {
        forwardable       = false
    }

    pam = {
        minimum_uid       = 100
        forwardable       = true
    }

    pam-afs-session = {
        minimum_uid       = 100
    }

[libdefaults]
    default_realm         = MY.COMPANY.LOCAL
    ticket_lifetime       = 25h
    renew_lifetime        = 7d
    forwardable           = true
    noaddresses           = true
    allow_weak_crypto     = true
    rdns                  = false

[realms]
     MY.COMPANY.LOCAL = {
        kdc            = mydomaincontroller.my.company.local
        default_domain = my.company.local
    }

[domain_realm]
    my.company.local    = MY.COMPANY.LOCAL

[logging]
    kdc          = SYSLOG:NOTICE
    admin_server = SYSLOG:NOTICE
    default      = SYSLOG:NOTICE

krb5.conf檔案必須位於/etc/kerb5.conf的容器中。

生成keytab檔案

為了避免將密碼傳遞給kinit命令(例如:執行 kinit username  並隨後輸入密碼),我決定生成正確的keytab檔案。這些檔案用於獲取kerberos票證,而不需要明文密碼。要生成此類keytab,您需要在Linux shell中執行以下命令:

ktutil 
ktutil: add_entry -password -p [email protected] -k 1 -e RC4-HMAC
# ktutil will promt for entering the password ...
ktutil: write_kt myUserName.keytab
ktuilt: extit

收到的keytab檔案可以在容器中對映或複製。要使用keytab檔案請求kerberos,您可以執行:

kinit myUserName -k -t myUserName.keytab

通過執行klist您可以看到收到了kereberos票證。

Docker化演示應用程式

現在我們已經足夠了解docker檔案:

FROM microsoft/dotnet:sdk AS build-env
WORKDIR /app

# Copy csproj and restore as distinct layers
COPY *.csproj ./
RUN dotnet restore

# Copy everything else and build
COPY . ./
RUN dotnet publish -c Release -o out


# Build runtime image
FROM microsoft/dotnet:aspnetcore-runtime
WORKDIR /app
COPY --from=build-env /app/out .

# Install krb5 packages
RUN apt-get update
RUN apt-get remove krb5-config krb5-user
RUN apt install -y krb5-config 
RUN apt-get install -y krb5-user

# Copy kerberso configuration and keytab
COPY krb5.conf /etc/krb5.conf
COPY myUserName.keytab /app/myUserName.keytab

# copy the launch script
COPY launch.sh /launch.sh

ENTRYPOINT /launch.sh

dockerfile的工作可以通過以下方式描述:

  1. 在基於microsoft/dotnet:sdk AS build-env 映像的容器中構建.Net Core應用程式  
  2. 將構建工件複製到執行時映像(來自  Microsoft/dotnet:aspnetcore-runtime
  3. debian: stretch-slim映像安裝kerberos軟體包(是microsoft /dotnet: aspnetcore-runtime的基礎
  4. 複製krb5.conf檔案和keytab
  5. 複製執行kinit並啟動.Net應用程式的指令碼
  6. 將啟動指令碼指定為入口點。

啟動指令碼launch.sh必須包含keberos身份驗證(kinit命令)和應用程式的執行:

...
kinit myUserName-k -t myUserName.keytab
dotnet MyApplication.dll

處理kerberos票證的到期日期

通過kinit命令收到的每張kerberos票證都有一個到期日期。為了避免在容器執行期間丟失身份驗證,必須在票證過期之前再次呼叫kinit。換句話說,kinit必須在容器生命週期內定期執行。

處理keytab檔案的到期日期

keberos票證類似,​​keytab檔案將過期。您還必須以定期方式建立和提供新的keytab檔案。可能的選擇是在容器啟動過程中建立檔案並將其對映到容器檔案系統。然而,根據潛在的環境,可能還有其他選擇。 

執行

要執行應用程式,您必須建立(使用上面的dockerfile)映像並執行容器。當您附加到docker容器時,您可以看到DB查詢的結果,該查詢被寫為控制檯輸出。

 

原文地址:https://www.codeproject.com/Articles/1272546/Authenticate-Net-Core-client-of-SQL-Server-with-In