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!