本文共 5653 字,大约阅读时间需要 18 分钟。
目录
说明.Net Core应用程序的实现,在linux容器中运行,连接到具有集成安全性的SQL Server数据库。
如果使用SQL Server对.Net应用程序进行docker化,则必须考虑连接数据库的方法。
幸运的是,Microsoft为我们提供了几个建立安全可靠连接的机会,这些连接也可以应用于Windows容器。但是,在连接linux容器的情况下,并不是所有这些概念都是开箱即用的。这还影响集成安全性的使用,以便从已经过身份验证的客户端(例如:单点登录系统)建立连接。
本文适用于Linux容器的集成安全性概念,它构建于kerberos身份验证过程之上。该解决方案不需要在.Net Core应用程序中进行代码更改。相反,它说明了在系统级别上的docker镜像预备和kerberos身份验证的配置。最后,您可以通过集成安全性连接到以前经过身份验证的Linux容器中的SQL Server。
对于这个解决方案,在我们能够创建解决方案之前,我们必须走更长的路,拾起一个更大的拼图块。
在您的环境中重建解决方案所需的一切:
为了验证数据库连接,我创建了一个非常简单的解决方案。该应用程序挂在一个无限循环中,查询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;;"
为了通过密钥分发中心(KDC)与Linux容器进行通信,需要对容器映像和配置进行一些准备。
演示应用程序运行在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文件。
为了与底层KDC进行通信,将创建一个正确的krb5.conf文件并将其存储在containers/etc文件夹中。为了构造一个正确的例子,假设我们在域my.company.local中,我们的KDC由mydomaincontroller.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的容器中。
为了避免将密码传递给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文件:
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的工作可以通过以下方式描述:
启动脚本launch.sh必须包含keberos身份验证(kinit命令)和应用程序的执行:
...kinit myUserName-k -t myUserName.keytabdotnet MyApplication.dll
通过kinit命令收到的每张kerberos票证都有一个到期日期。为了避免在容器运行期间丢失身份验证,必须在票证过期之前再次调用kinit。换句话说,kinit必须在容器生命周期内定期执行。
与keberos票证类似,keytab文件将过期。您还必须以定期方式创建和提供新的keytab文件。可能的选择是在容器启动过程中创建文件并将其映射到容器文件系统。然而,根据潜在的环境,可能还有其他选择。
要运行应用程序,您必须创建(使用上面的dockerfile)映像并运行容器。当您附加到docker容器时,您可以看到DB查询的结果,该查询被写为控制台输出。
原文地址:
转载地址:http://ouzhj.baihongyu.com/