使用 DNS-01 質詢和 AWS 自動化 Let's Encrypt SSL 憑證管理

這篇文章描述了自動管理 SSL 憑證的步驟 讓我們加密 CA 使用 DNS-01 挑戰 и AWS.

acme-dns-route53 是一個允許我們實現此功能的工具。 它可以使用 Let's Encrypt 的 SSL 證書,將其保存在 Amazon Certificate Manager 中,使用 Route53 API 實作 DNS-01 質詢,最後將通知推送到 SNS。 在 acme-dns-route53 AWS Lambda 中也提供了內建功能,這正是我們所需要的。

本文分為 4 部分:

  • 建立一個 zip 檔案;
  • 創建 IAM 角色;
  • 建立一個運行的 lambda 函數 acme-dns-route53;
  • 建立一個每天觸發函數 2 次的 CloudWatch 計時器;

注意: 在開始之前您需要安裝 Go 語言 1.9+ и 命令行界面

建立 zip 文件

acme-dns-route53是用GoLang寫的,支援不低於1.9的版本。

我們需要建立一個帶有二進位檔案的 zip 文件 acme-dns-route53 裡面。 為此,您需要安裝 acme-dns-route53 使用命令從 GitHub 儲存庫中獲取 go install:

$ env GOOS=linux GOARCH=amd64 go install github.com/begmaroman/acme-dns-route53

二進位檔安裝在 $GOPATH/bin 目錄。 請注意,在安裝過程中我們指定了兩個變更的環境: GOOS=linux и GOARCH=amd64。 他們向 Go 編譯器明確表示,它需要建立一個適合 Linux 作業系統和 amd64 架構的二進位檔案 - 這就是在 AWS 上運行的二進位檔案。
AWS 希望我們的程式部署在 zip 檔案中,所以讓我們建立 acme-dns-route53.zip 存檔將包含新安裝的二進位檔案:

$ zip -j ~/acme-dns-route53.zip $GOPATH/bin/acme-dns-route53

注意: 二進位檔案應位於 zip 檔案的根目錄中。 為此我們使用 -j 旗幟。

現在我們的 zip 暱稱已準備好部署,剩下的就是建立一個具有必要權限的角色。

建立 IAM 角色

我們需要設定一個 IAM 角色,並具有 lambda 在執行過程中所需的權限。
我們稱這個政策為 lambda-acme-dns-route53-executor 並立即給她一個基本角色 AWSLambdaBasicExecutionRole。 這將允許我們的 lambda 運行並將日誌寫入 AWS CloudWatch 服務。
首先,我們建立一個描述我們權利的 JSON 檔案。 這本質上將允許 lambda 服務使用該角色 lambda-acme-dns-route53-executor:

$ touch ~/lambda-acme-dns-route53-executor-policy.json

我們的文件內容如下:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "logs:CreateLogGroup"
            ],
            "Resource": "arn:aws:logs:<AWS_REGION>:<AWS_ACCOUNT_ID>:*"
        },
        {
            "Effect": "Allow",
            "Action": [
                "logs:PutLogEvents",
                "logs:CreateLogStream"
            ],
            "Resource": "arn:aws:logs:<AWS_REGION>:<AWS_ACCOUNT_ID>:log-group:/aws/lambda/acme-dns-route53:*"
        },
        {
            "Sid": "",
            "Effect": "Allow",
            "Action": [
                "route53:ListHostedZones",
                "cloudwatch:PutMetricData",
                "acm:ImportCertificate",
                "acm:ListCertificates"
            ],
            "Resource": "*"
        },
        {
            "Sid": "",
            "Effect": "Allow",
            "Action": [
                "sns:Publish",
                "route53:GetChange",
                "route53:ChangeResourceRecordSets",
                "acm:ImportCertificate",
                "acm:DescribeCertificate"
            ],
            "Resource": [
                "arn:aws:sns:${var.region}:<AWS_ACCOUNT_ID>:<TOPIC_NAME>",
                "arn:aws:route53:::hostedzone/*",
                "arn:aws:route53:::change/*",
                "arn:aws:acm:<AWS_REGION>:<AWS_ACCOUNT_ID>:certificate/*"
            ]
        }
    ]
}

現在讓我們運行命令 aws iam create-role 創建角色:

$ aws iam create-role --role-name lambda-acme-dns-route53-executor 
 --assume-role-policy-document ~/lambda-acme-dns-route53-executor-policy.json

注意: 請記住策略 ARN(Amazon 資源名稱) - 我們將在後續步驟中需要它。

角色 lambda-acme-dns-route53-executor 創建完畢,現在我們需要為其指定權限。 最簡單的方法是使用指令 aws iam attach-role-policy,傳遞策略 ARN AWSLambdaBasicExecutionRole 如下所示:

$ aws iam attach-role-policy --role-name lambda-acme-dns-route53-executor 
--policy-arn arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole

注意: 可以找到包含其他政策的列表 這裡.

建立一個運行的 lambda 函數 acme-dns-route53

萬歲! 現在您可以使用命令將我們的函數部署到AWS aws lambda create-function。 必須使用以下環境變數來配置 lambda:

  • AWS_LAMBDA - 說清楚了 acme-dns-route53 該執行發生在 AWS Lambda 內部。
  • DOMAINS — 以逗號分隔的網域清單。
  • LETSENCRYPT_EMAIL - 包含 讓我們加密電子郵件.
  • NOTIFICATION_TOPIC — SNS 通知主題的名稱(可選)。
  • STAGING - 按價值 1 使用暫存環境。
  • 1024 MB——記憶體限制,可以更改。
  • 900 秒(15 分鐘)— 超時。
  • acme-dns-route53 — 我們的二進位檔案的名稱,位於檔案中。
  • fileb://~/acme-dns-route53.zip — 我們所建立的存檔的路徑。

現在我們來部署:

$ aws lambda create-function 
 --function-name acme-dns-route53 
 --runtime go1.x 
 --role arn:aws:iam::<AWS_ACCOUNT_ID>:role/lambda-acme-dns-route53-executor 
 --environment Variables="{AWS_LAMBDA=1,DOMAINS="example1.com,example2.com",[email protected],STAGING=0,NOTIFICATION_TOPIC=acme-dns-route53-obtained}" 
 --memory-size 1024 
 --timeout 900 
 --handler acme-dns-route53 
 --zip-file fileb://~/acme-dns-route53.zip

 {
     "FunctionName": "acme-dns-route53", 
     "LastModified": "2019-05-03T19:07:09.325+0000", 
     "RevisionId": "e3fadec9-2180-4bff-bb9a-999b1b71a558", 
     "MemorySize": 1024, 
     "Environment": {
         "Variables": {
            "DOMAINS": "example1.com,example2.com", 
            "STAGING": "1", 
            "LETSENCRYPT_EMAIL": "[email protected]", 
            "NOTIFICATION_TOPIC": "acme-dns-route53-obtained", 
            "AWS_LAMBDA": "1"
         }
     }, 
     "Version": "$LATEST", 
     "Role": "arn:aws:iam::<AWS_ACCOUNT_ID>:role/lambda-acme-dns-route53-executor", 
     "Timeout": 900, 
     "Runtime": "go1.x", 
     "TracingConfig": {
         "Mode": "PassThrough"
     }, 
     "CodeSha256": "+2KgE5mh5LGaOsni36pdmPP9O35wgZ6TbddspyaIXXw=", 
     "Description": "", 
     "CodeSize": 8456317,
"FunctionArn": "arn:aws:lambda:us-east-1:<AWS_ACCOUNT_ID>:function:acme-dns-route53", 
     "Handler": "acme-dns-route53"
 }

建立每天觸發函數 2 次的 CloudWatch 計時器

最後一步是設定 cron,它每天呼叫我們的函數兩次:

  • 使用該值建立 CloudWatch 規則 schedule_expression.
  • 透過指定 lambda 函數的 ARN 建立規則目標(應執行的內容)。
  • 授予規則呼叫 lambda 函數的權限。

下面我附上了我的 Terraform 配置,但實際上這是使用 AWS 控制台或 AWS CLI 非常簡單地完成的。

# Cloudwatch event rule that runs acme-dns-route53 lambda every 12 hours
resource "aws_cloudwatch_event_rule" "acme_dns_route53_sheduler" {
  name                = "acme-dns-route53-issuer-scheduler"
  schedule_expression = "cron(0 */12 * * ? *)"
}

# Specify the lambda function to run
resource "aws_cloudwatch_event_target" "acme_dns_route53_sheduler_target" {
  rule = "${aws_cloudwatch_event_rule.acme_dns_route53_sheduler.name}"
  arn  = "${aws_lambda_function.acme_dns_route53.arn}"
}

# Give CloudWatch permission to invoke the function
resource "aws_lambda_permission" "permission" {
  action        = "lambda:InvokeFunction"
  function_name = "${aws_lambda_function.acme_dns_route53.function_name}"
  principal     = "events.amazonaws.com"
  source_arn    = "${aws_cloudwatch_event_rule.acme_dns_route53_sheduler.arn}"
}

現在您已設定為自動建立和更新 SSL 憑證

來源: www.habr.com

添加評論