Traefik + 让我们在 AWS Lightsail 上加密

Traefik + Let's Encrypt on AWS Lightsail

我目前正在使用 Traefik and Lego in order to have HTTPS connection for my docker containers (as mentioned here) 在下面documentation, it's mentioned that I need to use the following provider做DNS Challenge。

但是我得到这个错误:

AccessDeniedException: User: arn:aws:sts::<USER_ID>:assumed-role/AmazonLightsailInstanceRole/<AN_ID> is not authorized to perform: lightsail:CreateDomainEntry on resource: arn:aws:lightsail:us-east-1:<INSTANCE_ID>:*

还有一个用于 DeleteDomainEntry,即使我对用于配置的 IAM 用户具有 lightsail:* Resource: * 权限。

如果我理解正确的话,Lightsail 是为其他 AWS 服务单独管理的,因此我们需要使用 STS 来连接它(如果我错了请告诉我)。所以我的问题是,如何设置临时令牌的权限才能执行 CreateDomainEntry 和 DeleteDomainEntry?

更多信息

错误消息表明 Lego 使用分配给您的 lightsail 实例的 IAM 角色发出了请求。我猜您的实例缺少修改 lightsail 的 DNS 设置的权限。

您应该在 AWS IAM 中创建一个新用户并启用编程访问以获得 AWS_ACCESS_KEY_IDAWS_SECRET_ACCESS_KEY.

然后,将这些值作为环境变量传递给容器 运行 Lego。 Lego 将使用这些环境变量通过 us-east-1 中的 Lightsail API 进行身份验证。 [1]

My instance's region is eu-west-3 (I tried changing the region in Lego config, doesn't work)

您的 Lego 实例必须调用 us-east-1 中的 AWS API,请参阅 [2][3]。

Lego and Traefik do not call the AssumeRole directly and do not create the temporary token

我猜 Traefik/Lego 使用 EC2 实例元数据服务自动承担 lightsail 实例角色,请参阅 [4]:

For applications, AWS CLI, and Tools for Windows PowerShell commands that run on the instance, you do not have to explicitly get the temporary security credentials—the AWS SDKs, AWS CLI, and Tools for Windows PowerShell automatically get the credentials from the EC2 instance metadata service and use them. To make a call outside of the instance using temporary security credentials (for example, to test IAM policies), you must provide the access key, secret key, and the session token.

I'm using AWS_ACCESS_KEY_ID_FILE and AWS_SECRET_ACCESS_KEY_FILE in Traefik environment configuration.

我在 Lego 源代码 [1] 中找不到那些环境变量。确保 Lego 确实在使用您配置的 AWS 凭证。上面发布的错误消息表明它没有使用它们,而是回退到实例配置文件。

[1] https://github.com/go-acme/lego/blob/master/providers/dns/lightsail/lightsail.go#L81
[2] https://docs.aws.amazon.com/cli/latest/reference/lightsail/create-domain-entry.html#examples
[3] https://github.com/go-acme/lego/blob/master/providers/dns/lightsail/lightsail.go#L69
[4] https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/iam-roles-for-amazon-ec2.html#instance-metadata-security-credentials

乱七八糟的东西太多了。 Martin Löper's answer and answer on the github issue I opened 帮我解决了问题。

这是令人困惑的地方:

  • 凭据上的乐高lightsail provider documentation is listing the environment variable and then say The environment variable names can be suffixed by _FILE to reference a file instead of a value. Turns out, Lego's code never call their getOrFile 方法。此外,AWS SDK 不会检查 AWS_ACCESS_KEY_IDAWS_SECRET_ACCESS_KEY.

    后缀为 _FILE 的变量
  • 来自 AWS 的错误消息有点误导。我一直以为这是一个权限问题,但实际上这是一个身份验证问题(我认为有点不同)。

下面是解决方法(与建议的略有不同):

我使用 AWS_SHARED_CREDENTIALS_FILE(提到 here) environment variable so that I can use docker secrets by specifying /run/secrets/aws_shared_credentials file. This is more secure (more info here). AWS sdk will automatically detect this env variable and initialize this new session 正确。