简体   繁体   English

使用 AWS ECS 从运行在 Linux 容器上的 .NET 核心应用程序访问具有集成安全性的 SQL 服务器

[英]Access SQL Server with Integrated security from .NET Core app running on Linux container using AWS ECS

I have a .NET Core application running on Linux container using AWS ECS Fargate.我有一个使用 AWS ECS Fargate 在 Linux 容器上运行的 .NET Core 应用程序。

How to connect from that application to SQL Server using integrated security?如何使用集成安全性从该应用程序连接到 SQL 服务器?

Step 1 : ensure that SQL Server supports Kerberos authentication # Using SQL Server Management Studio (SSMS), connect to your database and execute following statement:第 1 步:确保 SQL 服务器支持 Kerberos 身份验证 # 使用 SQL 服务器管理工作室 (SSMS),连接到您的数据库并执行以下语句:

select auth_scheme  
from sys.dm_exec_connections 
where session_id = @@spid

If result of the query is KERBEROS , you are all set and proceed to Step 2. Otherwise, if result is NTLM , this means that Kerberos authentication failed, and SSMS silently fell back to using NTLM authentication.如果查询的结果是KERBEROS ,则您已全部设置并继续执行第 2 步。否则,如果结果是NTLM ,则意味着 Kerberos 身份验证失败,SSMS 会自动回退到使用 NTLM 身份验证。 Since integrated security between SQL Server and clients running in Linux environments solely rely on Kerberos authentication, this issue must be addressed first.由于 SQL 服务器和在 Linux 环境中运行的客户端之间的集成安全完全依赖于 Kerberos 身份验证,因此必须首先解决此问题。

Note : when connecting to SQL Server, it is important to use server hostname or FQDN instead of IP address, otherwise Kerberos authentication will not work.注意:当连接到 SQL 服务器时,重要的是使用服务器主机名或 FQDN 而不是 IP 地址,否则 Kerberos 身份验证将不起作用。

Check SPN configuration检查 SPN配置

Ensure that SPN is properly configured for SQL Server. 确保为 SQL 服务器正确配置了 SPN。

Microsoft has also released several diagnostic tools that can help with SPN verification and configuration: Microsoft 还发布了几个有助于 SPN 验证和配置的诊断工具:

Last but not least, you can use following setspn command to query for a specific SPN(s):最后但同样重要的是,您可以使用以下setspn命令来查询特定的 SPN:

setspn -T CONTOSO.COM -F -Q MSSQLSvc/your_sql_server.contoso.com

Query above does support * for a wildcard (replace CONTOSO.COM with your domain)上面的查询确实支持*通配符(将CONTOSO.COM替换为您的域)

Configure encryption types allowed for Kerberos配置 Kerberos 允许的加密类型

Within Active Directory, find an account under which SQL Server is running.在 Active Directory 中,找到运行 SQL 服务器的帐户。 Under Account tab and Account options section, confirm that applicable Kerberos cyphers are selected .在“帐户”选项卡和“帐户选项”部分下,确认选择了适用的 Kerberos 密码

Example:例子:

在此处输入图像描述

Step 2 : Configure ECS Task To use Kerberos authentication, Application Task within ECS Service will be composed of two containers:第 2 步:配置 ECS 任务 要使用 Kerberos 身份验证,ECS 服务中的应用程序任务将由两个容器组成:

  1. A container that will periodically (re)obtain and cache Kerberos ticket-granting tickets (TGT) using kinit command.将使用kinit命令定期(重新)获取和缓存 Kerberos 票证授予票证 (TGT) 的容器。
  2. A container that will run application, and use TGT acquired by first task to authenticate against MS SQL Server.将运行应用程序并使用第一个任务获取的 TGT 对 MS SQL 服务器进行身份验证的容器。

Both containers will mount the same volume.两个容器将安装相同的卷。 1st container will cache/write TGT ticket to it, 2nd container will read cached TGT ticket from it.第一个容器将缓存/写入 TGT 票证,第二个容器将从中读取缓存的 TGT 票证。

TGT acquisition container (sidecar container) TGT获取容器(sidecar容器)

There are only 3 files needed to setup TGT acquisition container:设置 TGT 采集容器只需要 3 个文件:

  1. krb5.conf - a Kerberos configuration file. krb5.conf - Kerberos 配置文件。
  2. renew.sh - script file with commands to renew TGT. renew.sh - 包含更新 TGT 命令的脚本文件。
  3. Dockerfile - packages all into a docker image. Dockerfile - 全部打包成一个 docker 图像。
# krb5.conf
[libdefaults]
dns_lookup_realm = true
dns_lookup_kdc = true
forwardable = true
default_ccache_name = FILE:/var/kerberos/krbcache # TGT cache location
default_realm = CONTOSO.COM
permitted_enctypes = aes256-cts aes128-cts

[realms]
CONTOSO.COM = {
  kdc = CONTOSO.COM
  admin_server = CONTOSO.COM
}

[domain_realm]
.contoso.com = SCIF.COM
contoso.com = SCIF.COM

[logging]
default = STDERR
# renew.sh
#!/bin/bash

# Refresh the token periodically.
# Set the length of time that the script will wait to refresh the token.
[[ "$DELAY_SECONDS" == "" ]] && DELAY_SECONDS=3600

# If the AWS region hasn't been set, get it from instance metadata. This will work in an instance as well as in an ECS container.
[[ "$AWS_REGION" == "" ]] && AWS_REGION=$(curl --silent http://169.254.169.254/latest/dynamic/instance-identity/document | jq -r .region)

# Use the ECS container as the source for AWS credentials. This allows the AWS CLI to use the permissions of the task role.
aws configure set credential_source EcsContainer


while true
do
    echo "Starting ticket renewal at: " + $(date)

    # Get the credentials from Secrets Manager.
    CREDENTIALS_SECRET_VALUE=$(aws secretsmanager get-secret-value --secret-id $CREDENTIALS_SECRET_ARN --region $AWS_REGION --query SecretString --output text)

    # Use `jq` to parse the credentials into username & password.
    CREDENTIALS_USERNAME=$(echo $CREDENTIALS_SECRET_VALUE | jq -r '.username')
    CREDENTIALS_PASSWORD=$(echo $CREDENTIALS_SECRET_VALUE | jq -r '.password')

    # Use the username & password to authenticate to Kerberos. The resulting token is written to the token cache, 
    # which is set up in `krb5.conf` to use the task scratch volume, shared by all containers.
    echo $CREDENTIALS_PASSWORD | kinit $CREDENTIALS_USERNAME -f -V $OPTIONS

    echo "Ticket renewal complete, waiting for $DELAY_SECONDS seconds"


    sleep $DELAY_SECONDS &
    wait
done
# Dockerfile

FROM amazonlinux:2

COPY renew.sh /
COPY krb5.conf /etc/krb5.conf

# Install the Kerberos tools -- to authenticate;
# `jq` -- to parse the credentials from the AWS Secrets Manager, which returns JSON
# `unzip` -- to install the latest version of the AWS CLI
RUN yum install -y krb5-workstation jq unzip 

# Download and install the latest version of the AWS CLI
RUN curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"
RUN unzip awscliv2.zip
RUN ./aws/install

VOLUME ["/var/kerberos"]

ENTRYPOINT ["/renew.sh"]

Based on value specified in CREDENTIALS_SECRET_ARN , renew.sh will periodically renew TGT and cache/save it in location specified at krb5.conf file (eg /var/kerberos/krbcache ).根据CREDENTIALS_SECRET_ARN中指定的值,renew.sh 将定期更新 TGT 并将其缓存/保存在 krb5.conf 文件中指定的位置(例如/var/kerberos/krbcache )。

To test that container successfully acquires TGT for a given principle, establish interactive session with the container and execute klist command.要测试容器是否成功获取给定原则的 TGT,请与容器建立交互 session 并执行klist命令。 When successful, you should see the details of TGT ticket, containing principle name, expiration date, etc.成功后,您应该会看到 TGT 票据的详细信息,包括委托人姓名、到期日期等。

Application Container应用容器

Application container runs your .NET Core application.应用程序容器运行您的 .NET Core 应用程序。 To enable Kerberos on that container add following lines in Dockerfile:要在该容器上启用 Kerberos,请在 Dockerfile 中添加以下行:

...
RUN apt update
RUN apt install -y krb5-config krb5-user  
COPY krb5.conf /etc/krb5.conf
VOLUME ["/var/kerberos"]
...

The content of krb5.conf file should be identical to one in TGT acquisition container, and it will instruct application to locate Kerberos TGT at FILE:/var/kerberos/krbcache . krb5.conf 文件的内容应该与 TGT 获取容器中的内容相同,它将指示应用程序将 Kerberos TGT 定位到FILE:/var/kerberos/krbcache

Your application SQL connection string should look similar to this:您的应用程序 SQL 连接字符串应类似于以下内容:

Server=yourSqlServer.contoso.com;Initial Catalog=YourDB;Integrated Security=true;

To test that container has access to cached TGT, establish interactive session with the container and execute klist .要测试容器是否可以访问缓存的 TGT,请与容器建立交互 session 并执行klist When successful, you should see same TGT ticket, as in another container.成功后,您应该会看到与另一个容器中相同的 TGT 票证。

If everything went well, you should be able to successfully connect to SQL Server using Integrated Security from your .NET Core application running on Linux.如果一切顺利,您应该能够从运行在 Linux 上的 .NET 核心应用程序使用集成安全成功连接到 SQL 服务器。

Additional resources额外资源

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 在 AWS ECS 容器中运行节点应用程序的问题 - Issue with running Node application in AWS ECS container 如何使用 Fargate 在 AWS ECS 中正在运行的容器中运行命令 - How can I run commands in a running container in AWS ECS using Fargate 如何为在 AWS ECS 中运行的 Docker 容器配置“ulimits”? - How do I configure "ulimits" for a Docker container running in AWS ECS? 如何从在自动缩放组后面运行并连接到 jms 队列的 aws ecs docker 容器中排出消息 - How to drain message from aws ecs docker container which is running behind autoscaling group and connected to jms queue AWS websocket 容器 cdk ecs - AWS websocket container cdk ecs 使用 Fargate 使用 AWS ECS 任务从 SFTP 服务器并行获取文件 - Fetch files parallelly from an SFTP server using AWS ECS tasks using Fargate 在 ECS 集群中运行来自 AWS ECR 的公共镜像 - Running a public image from AWS ECR in ECS Cluster Angular 2 应用程序部署在 AWS 上运行的 docker 容器中 - Angular 2 app deploy in a docker Container running on AWS 更改 AWS ECS 服务的安全组 - Change AWS ECS service's security groups ASP.NET 核心应用程序未在 AWS 中运行 Linux EC2 实例而不是显示 Apache 测试页 - ASP.NET Core Application not Running in AWS Linux EC2 instance instead showing Apache Test Page
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM