博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
使用Linux docker容器中的集成安全性对SQL Server的.Net Core客户端进行身份验证
阅读量:3522 次
发布时间:2019-05-20

本文共 5653 字,大约阅读时间需要 18 分钟。

目录


说明.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  并随后输入密码),我决定生成正确的文件。这些文件用于获取kerberos票证,而不需要明文密码。要生成此类keytab,您需要在Linux shell中运行以下命令:

ktutil ktutil: add_entry -password -p myUserName@MY.COMPANY.LOCAL -k 1 -e RC4-HMAC# ktutil will promt for entering the password ...ktutil: write_kt myUserName.keytabktuilt: extit

收到的keytab文件可以在容器中映射或复制。要使用keytab文件请求kerberos票,您可以运行:

kinit myUserName -k -t myUserName.keytab

通过运行klist您可以看到收到了kereberos票证。

Docker化演示应用程序

现在我们已经足够了解docker文件:

FROM microsoft/dotnet:sdk AS build-envWORKDIR /app# Copy csproj and restore as distinct layersCOPY *.csproj ./RUN dotnet restore# Copy everything else and buildCOPY . ./RUN dotnet publish -c Release -o out# Build runtime imageFROM microsoft/dotnet:aspnetcore-runtimeWORKDIR /appCOPY --from=build-env /app/out .# Install krb5 packagesRUN apt-get updateRUN apt-get remove krb5-config krb5-userRUN apt install -y krb5-config RUN apt-get install -y krb5-user# Copy kerberso configuration and keytabCOPY krb5.conf /etc/krb5.confCOPY myUserName.keytab /app/myUserName.keytab# copy the launch scriptCOPY launch.sh /launch.shENTRYPOINT /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.keytabdotnet MyApplication.dll

处理kerberos票证的到期日期

通过kinit命令收到的每张kerberos票证都有一个到期日期。为了避免在容器运行期间丢失身份验证,必须在票证过期之前再次调用kinit。换句话说,kinit必须在容器生命周期内定期执行。

处理keytab文件的到期日期

keberos票证类似,​​keytab文件将过期。您还必须以定期方式创建和提供新的keytab文件。可能的选择是在容器启动过程中创建文件并将其映射到容器文件系统。然而,根据潜在的环境,可能还有其他选择。 

运行

要运行应用程序,您必须创建(使用上面的dockerfile)映像并运行容器。当您附加到docker容器时,您可以看到DB查询的结果,该查询被写为控制台输出。

 

原文地址:

转载地址:http://ouzhj.baihongyu.com/

你可能感兴趣的文章
Memcache技术精华
查看>>
Redis详解入门篇
查看>>
php开启redis扩展包与redis安装
查看>>
php使用openssl来实现非对称加密
查看>>
pdo如何防止 sql注入
查看>>
myisam和innodb的区别
查看>>
MySQL建表规范与注意事项(个人精华)
查看>>
JDK8接口的新特性
查看>>
synchronized的局限性与lock的好处
查看>>
redis和memcached有什么区别?
查看>>
Spring中的设计模式
查看>>
如何设计一个秒杀系统 -- 架构原则
查看>>
如何设计一个秒杀系统 -- 动静分离方案
查看>>
JWT 快速了解
查看>>
实习日志一
查看>>
排序算法稳定性
查看>>
图算法总结(判断有环、最短路径)
查看>>
spring中的类
查看>>
python练习编程网址
查看>>
Python练习小程序1
查看>>