使用Linux docker容器中的集成安全性对SQL Server的.Net Core客户端进行身份验证

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/mzl87/article/details/86363664

目录

面对问题

逐步发现解决方案

先决条件

我们的演示应用

在容器中准备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

猜你喜欢

转载自blog.csdn.net/mzl87/article/details/86363664