目录
面对问题
逐步发现解决方案
先决条件
我们的演示应用
在容器中准备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上的docker,docker 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容器进行通信,需要对容器映像和配置进行一些准备。
- 安装KDC消费包。
- 创建适当的krb5.conf文件以访问AD域控制器中托管的KDC应用程序
- 生成keytab文件(以避免以纯文本形式暴露密码)
演示应用程序运行在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中,我们的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的容器中。
生成keytab文件为了避免将密码传递给kinit命令(例如:执行 kinit username 并随后输入密码),我决定生成正确的keytab文件。这些文件用于获取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.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的工作可以通过以下方式描述:
- 在基于microsoft/dotnet:sdk AS build-env 映像的容器中构建.Net Core应用程序 。
- 将构建工件复制到运行时映像(来自 Microsoft/dotnet:aspnetcore-runtime)
- 为debian: stretch-slim映像安装kerberos软件包(是microsoft /dotnet: aspnetcore-runtime的基础)
- 复制krb5.conf文件和keytab。
- 复制执行kinit并启动.Net应用程序的脚本
- 将启动脚本指定为入口点。
启动脚本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