In diesem Beitrag werden die Schritte beschrieben, die zum Einrichten der automatischen Erstellung und Erneuerung von SSL-Zertifikaten unter Verwendung von Let's Encrypt als automatisierte Zertifizierungsstelle erforderlich sind, die eine gut gewartete API bereitstellt.
acme-dns-route53
ist das Tool zum acme-dns-route53
SSL-Zertifikaten von Let's Encrypt mithilfe der DNS-01-Challenge mit Route53 und Amazon Certificate Manager von AWS. acme-dns-route53
verfügt auch über die integrierte Funktionalität für die Verwendung dieses Tools in AWS Lambda. Dies werden wir tun.
Dieser Beitrag ist in 4 Abschnitte unterteilt:
- Erstellen Sie eine eigenständige, bereitstellbare Zip-Datei
- Erstellen einer IAM-Rolle für die Lambda-Funktion, die die erforderlichen Berechtigungen zur Ausführung erteilt
- Erstellen einer Lambda-Funktion, die
acme-dns-route53
- Erstellen eines CloudWatch-Timers, der zweimal täglich eine Lambda-Funktion auslöst
Hinweis: Stellen Sie vor dem Start sicher, dass GoLang 1.9+ und AWS CLI bereits installiert sind.
Erstellt eine in sich geschlossene, bereitstellbare Zip-Datei
acme-dns-route53
ist in GoLang geschrieben und unterstützt mindestens Version 1.9. Wir müssen eine in sich geschlossene, bereitstellbare Zip-Datei erstellen, die die ausführbare Datei des Tools acme-dns-route53
enthält.
Der erste Schritt besteht darin, eine ausführbare Datei aus dem Remote-GitHub-Repo des Tools acme-dns-route53
mit dem Befehl go install
acme-dns-route53
:
$ env GOOS=linux GOARCH=amd64 go install github.com/begmaroman/acme-dns-route53
Die ausführbare Datei wird im $GOPATH/bin
installiert. Wichtig: Als Teil dieses Befehls verwenden wir env, um vorübergehend zwei Umgebungsvariablen für die Dauer des Befehls GOARCH=amd64
( GOOS=linux
und GOARCH=amd64
). Diese weisen den Go-Compiler an, eine ausführbare Datei zu erstellen, die für die Verwendung mit einem Linux-Betriebssystem und einer amd64-Architektur geeignet ist. Darauf wird sie ausgeführt, wenn wir sie in AWS bereitstellen.
AWS verlangt, dass wir unsere Lambda-Funktionen in eine Zip-Datei hochladen. Erstellen wir also eine acme-dns-route53.zip
Zip-Datei, die die gerade erstellte ausführbare Datei enthält:
$ zip -j ~/acme-dns-route53.zip $GOPATH/bin/acme-dns-route53
Beachten Sie, dass sich die ausführbare Datei im Stammverzeichnis der Zip-Datei befinden muss - nicht in einem Ordner in der Zip-Datei. Um dies sicherzustellen, habe ich das Flag -j
im obigen Snippet verwendet, um Verzeichnisnamen zu verschmutzen.
Jetzt kann die Zip-Datei bereitgestellt werden, benötigt jedoch noch Berechtigungen zum Ausführen.
Erstellen einer IAM-Rolle für die Lambda-Funktion, die die erforderlichen Ausführungsberechtigungen erteilt
Wir müssen eine IAM-Rolle einrichten, die die Berechtigung definiert, die unsere Lambda-Funktion hat, wenn sie ausgeführt wird.
Lassen Sie uns zunächst eine lambda-acme-dns-route53-executor
Rolle AWSLambdaBasicExecutionRole
und die verwaltete Richtlinie AWSLambdaBasicExecutionRole
anhängen. Dadurch erhält unsere Lambda-Funktion die grundlegenden Berechtigungen, die zum Ausführen und Protokollieren beim AWS CloudWatch-Dienst erforderlich sind.
Zuerst müssen wir eine JSON-Datei für Vertrauensrichtlinien erstellen. Dadurch wird AWS im Wesentlichen angewiesen, dass Lambda-Dienste die Rolle des lambda-acme-dns-route53-executor
übernehmen dürfen:
$ touch ~/lambda-acme-dns-route53-executor-policy.json
Der Inhalt der erstellten JSON-Datei sollte wie folgt sein:
{ "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:<AWS_REGION>:<AWS_ACCOUNT_ID>:<TOPIC_NAME>", "arn:aws:route53:::hostedzone/*", "arn:aws:route53:::change/*", "arn:aws:acm:<AWS_REGION>:<AWS_ACCOUNT_ID>:certificate/*" ] } ] }
Verwenden Sie dann den Befehl aws iam create-role
, um die Rolle mit dieser Vertrauensrichtlinie zu erstellen:
$ aws iam create-role --role-name lambda-acme-dns-route53-executor \ --assume-role-policy-document ~/lambda-acme-dns-route53-executor-policy.json
Notieren Sie sich die zurückgegebene ARN (Amazon Resource Name) - diese benötigen Sie im nächsten Schritt.
lambda-acme-dns-route53-executor
Rolle lambda-acme-dns-route53-executor
erstellt wurde, müssen Sie die Berechtigungen angeben, über die die Rolle verfügt. Der einfachste Weg, dies zu tun, besteht darin, den Befehl aws iam attach-role-policy
zu verwenden und die Berechtigungsrichtlinie ARN der AWSLambdaBasicExecutionRole
wie AWSLambdaBasicExecutionRole
zu übergeben:
$ aws iam attach-role-policy --role-name lambda-acme-dns-route53-executor \ --policy-arn arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole
Hinweis: Hier finden Sie eine Liste anderer Berechtigungsrichtlinien, die möglicherweise hilfreich sind .
Erstellen einer Lambda-Funktion, die acme-dns-route53 ausführt
Jetzt können wir die Lambda-Funktion tatsächlich in AWS bereitstellen. Dies können wir mit dem Befehl aws lambda create-function
tun. Die Lambda-Funktion muss mit folgenden Optionen konfiguriert werden:
- Umgebungsvariable
AWS_LAMBDA
mit dem Wert 1
, die das Tool für die Verwendung innerhalb der Lambda-Funktion anpasst. DOMAINS
ist die Umgebungsvariable, die eine durch Kommas getrennte Liste von Domänen enthält, für die Zertifikate ausgestellt werden.LETSENCRYPT_EMAIL
ist die Umgebungsvariable, die Let's Encrypt-Ablauf-E-Mail enthält.NOTIFICATION_TOPIC
ist die Umgebungsvariable, die das SNS-Benachrichtigungsthema ARN enthält.STAGING
ist die Umgebungsvariable, die 1
Wert für die Verwendung der Staging Let's Encrypt-Umgebung oder 0
für die Produktionsumgebung enthalten muss.RENEW_BEFORE
ist die Anzahl der Tage, die den Zeitraum vor Ablauf definieren, innerhalb dessen ein Zertifikat erneuert werden muss.1024
MB ist das Speicherlimit (kann bei Bedarf geändert werden).900
Sekunden (15 Minuten) sind die maximale Zeitüberschreitung.acme-dns-route53
ist der acme-dns-route53
der Lambda-Funktion.fileb://~/acme-dns-route53.zip
ist die oben erstellte .zip-Datei.
Versuchen Sie es bereitzustellen:
$ 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\",LETSENCRYPT_EMAIL=begmaroman@gmail.com,STAGING=0,NOTIFICATION_TOPIC=acme-dns-route53-obtained,RENEW_BEFORE=7}" \ --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": "your@email.com", "NOTIFICATION_TOPIC": "acme-dns-route53-obtained", "RENEW_BEFORE": "7", "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" }
Erstellen eines CloudWatch-Timers, der einmal täglich eine Lambda-Funktion auslöst
Der letzte Schritt besteht darin, einen täglichen Trigger für die Funktion zu erstellen. Dazu können wir:
- Erstellen Sie eine CloudWatch-Regel mit dem gewünschten
schedule_expression
(wann sollte sie ausgeführt werden). - Erstellen Sie ein Regelziel (was ausgeführt werden soll), das die ARN der Lambda-Funktion angibt.
- Geben Sie der CloudWatch-Regel die Berechtigung zum Aufrufen der Lambda-Funktion.
Ich habe meine Terraform-Konfiguration unten eingefügt, aber es ist auch sehr einfach, dies entweder über die AWS-Konsole oder die CLI zu tun.
# 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}" }
Jetzt können auch Sie 100% automatisierte TLS-Zertifikatserneuerungen durchführen!