设置 AWS Secrets Manager .Net Core

Setting up AWS Secrets Manager .Net Core

我有一个 .Net Core 应用程序 运行 在 EC2 实例上。 我想使用 Secrets Manager 来包含我的 Web 应用程序的秘密,例如 "connection string" 等。 AWS Secrets Manager 文档不是很有用,我似乎找不到显示/解释如何在 EC2 上使用 Secrets Manager 的教程。

我已经能够使用邮递员并使用以下代码成功提取 "Secret": 然而,Access Key 和 Secrets Key 都是硬编码的。

我不希望出现这种情况。 我已经安装了 SDK 并将访问密钥和密钥加载到此配置文件中。

基本上我的问题是如何从 SDK 中提取访问密钥和密钥来签署请求?

if (secretsDetail == null)
        {
            return "Please provide SecretsDetails.";
        }
        string secretName = "";
        string secret = "";

        MemoryStream memoryStream = new MemoryStream();
        AmazonSecretsManagerConfig amazonSecretsManagerConfig = new AmazonSecretsManagerConfig();
        amazonSecretsManagerConfig.ServiceURL = secretsDetail.ServiceURL;

        IAmazonSecretsManager client = new AmazonSecretsManagerClient(RegionEndpoint.GetBySystemName("eu-west-2"));

        GetSecretValueRequest request = new GetSecretValueRequest();
        request.SecretId = secretName;
        request.VersionStage = secretsDetail.VersionStage == null ? "AWSCURRENT" : secretsDetail.VersionStage; // VersionStage defaults to AWSCURRENT if unspecified.

        GetSecretValueResponse response = null;


        try
        {
            response = client.GetSecretValueAsync(request).Result;
        }
        catch (DecryptionFailureException)
        {
            // Secrets Manager can't decrypt the protected secret text using the provided KMS key.
            // Deal with the exception here, and/or rethrow at your discretion
            throw;
        }
        catch (InternalServiceErrorException)
        {
            // An error occurred on the server side.
            // Deal with the exception here, and/or rethrow at your discretion
            throw;
        }
        catch (InvalidParameterException)
        {
            // You provided an invalid value for a parameter.
            // Deal with the exception here, and/or rethrow at your discretion
            throw;
        }
        catch (InvalidRequestException)
        {
            // You provided a parameter value that is not valid for the current state of the resource.
            // Deal with the exception here, and/or rethrow at your discretion.
            throw;
        }
        catch (ResourceNotFoundException)
        {
            // We can't find the resource that you asked for.
            // Deal with the exception here, and/or rethrow at your discretion.
            throw;
        }
        catch (System.AggregateException)
        {
            // More than one of the above exceptions were triggered.
            // Deal with the exception here, and/or rethrow at your discretion.
            throw;
        }
        // Decrypts secret using the associated KMS CMK.
        // Depending on whether the secret is a string or binary, one of these fields will be populated.
        if (response.SecretString != null)
        {
            return secret = response.SecretString;
        }
        else
        {
            memoryStream = response.SecretBinary;
            StreamReader reader = new StreamReader(memoryStream);
            string decodedBinarySecret = System.Text.Encoding.UTF8.GetString(Convert.FromBase64String(reader.ReadToEnd()));
            return decodedBinarySecret;
        }

对您的问题的简短回答是您没有。 SDK 将自动为您获取凭据。 Using Credentials in an Application。您可以使用此处描述的任何方法,但 #4 是首选、最安全的选项。

For applications running on an Amazon EC2 instance, credentials stored in an instance profile.

在 EC2/Lambda 中使用 SDK 时,您不必提供 access/secret 密钥。要访问 EC2 或 Lambda 中的 Secrets Manager 等服务,您可以将角色附加到资源(EC2、Lambda),并附加策略。

1 - 首先创建一个角色

如果您已经拥有 EC2/Lambda 的角色,则可以跳过此步骤。

选择类型(EC2):

2 - 附加 SecretsManagerReadWrite 策略:


3 - 将角色附加到 EC2 实例

对于新实例,您可以select您创建的 IAM 角色,如下所示。

对于现有实例,select 实例并更改 IAM 角色如下:


通过执行这些步骤,您的实例无需显式提供 access/secret 密钥即可使用 SDK。您可以稍后在需要使用新资源(例如 SQS)时将新策略附加到角色。

这个问题的其他答案是准确的,但可能无法涵盖您的所有用例。对于与 AWS 服务的连接,您可以依赖其他答案中所述的 IAM 设置。根本不需要为凭据或连接字符串操心!

但是假设您需要连接 AWS 外部的第 3 方服务?

如果您想在 AWS Secrets Manager 中存储这些第 3 方服务的连接字符串或 API 密钥,您有几个选择:

  1. 在部署期间将这些机密作为环境变量注入到您的托管进程中。
  2. 修改您的 .NET Core 代码以访问机密。

对于方法 #2,我找到的最好的文章是这篇文章: http://blog.travisgosselin.com/net-core-and-aws-secrets/

它深入讨论了如何扩展 .NET Core 的配置管理器以合并 AWS Secrets Manager 机密。

指的是这个NuGet包,它是几个解决方案的基础。 https://www.nuget.org/packages/Kralizek.Extensions.Configuration.AWSSecretsManager

Amazon 有一个使用 C# 获取机密的第一方包,在此处宣布: https://aws.amazon.com/blogs/security/how-to-use-aws-secrets-manager-client-side-caching-in-dotnet/

您可能需要尝试几种方法才能找到最适合您的方法——截至 2021 年 9 月,还没有针对此问题的完整“开箱即用”解决方案。