Automatisches Abrufen von SSL-Zertifikaten durch Let's Encrypt mithilfe von DNS-01 Challenge und AWS

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!

Source: https://habr.com/ru/post/de451200/


All Articles