Automazione della gestione dei certificati SSL Let's Encrypt utilizzando la sfida DNS-01 e AWS

Il post descrive i passaggi per automatizzare la gestione dei certificati SSL da Crittografiamo CA utilizzando Sfida DNS-01 и AWS.

acme-dns-route53 è uno strumento che ci permetterà di implementare questa funzionalità. Può funzionare con i certificati SSL di Let's Encrypt, salvarli in Amazon Certificate Manager, utilizzare l'API Route53 per implementare la sfida DNS-01 e, infine, inviare notifiche a SNS. IN acme-dns-route53 Sono inoltre disponibili funzionalità integrate da utilizzare all'interno di AWS Lambda e questo è ciò di cui abbiamo bisogno.

Questo articolo è diviso in 4 sezioni:

  • creazione di un file zip;
  • creazione di un ruolo IAM;
  • creando una funzione lambda che viene eseguita acme-dns-route53;
  • creazione di un timer CloudWatch che attiva una funzione 2 volte al giorno;

Nota: Prima di iniziare è necessario installare GoLang 1.9+ и CLI AWS

Creazione di un file zip

acme-dns-route53 è scritto in GoLang e supporta la versione non inferiore alla 1.9.

Dobbiamo creare un file zip con un binario acme-dns-route53 dentro. Per fare ciò è necessario installare acme-dns-route53 dal repository GitHub utilizzando il comando go install:

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

Il binario è installato in $GOPATH/bin directory. Tieni presente che durante l'installazione abbiamo specificato due ambienti modificati: GOOS=linux и GOARCH=amd64. Chiedono chiaramente al compilatore Go che deve creare un file binario adatto al sistema operativo Linux e all'architettura amd64: questo è ciò che viene eseguito su AWS.
AWS prevede che il nostro programma venga distribuito in un file zip, quindi creiamo acme-dns-route53.zip archivio che conterrà il binario appena installato:

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

Nota: Il file binario dovrebbe trovarsi nella radice dell'archivio zip. Per questo usiamo -j bandiera.

Ora il nostro nickname zip è pronto per l'implementazione, non resta che creare un ruolo con i diritti necessari.

Creazione di un ruolo IAM

Dobbiamo impostare un ruolo IAM con i diritti richiesti dal nostro lambda durante la sua esecuzione.
Chiamiamo questa politica lambda-acme-dns-route53-executor e darle subito un ruolo fondamentale AWSLambdaBasicExecutionRole. Ciò consentirà al nostro lambda di eseguire e scrivere log nel servizio AWS CloudWatch.
Per prima cosa creiamo un file JSON che descrive i nostri diritti. Ciò consentirà essenzialmente ai servizi lambda di utilizzare il ruolo lambda-acme-dns-route53-executor:

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

Il contenuto del nostro file è il seguente:

{
    "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/*"
            ]
        }
    ]
}

Ora eseguiamo il comando aws iam create-role per creare un ruolo:

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

Nota: ricorda la policy ARN (Amazon Resource Name): ne avremo bisogno nei passaggi successivi.

Ruolo lambda-acme-dns-route53-executor creato, ora dobbiamo specificarne le autorizzazioni. Il modo più semplice per farlo è usare il comando aws iam attach-role-policy, approvando la 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

Nota: è possibile trovare un elenco con altre politiche qui.

Creazione di una funzione lambda che viene eseguita acme-dns-route53

Evviva! Ora puoi distribuire la nostra funzione su AWS utilizzando il comando aws lambda create-function. La lambda deve essere configurata utilizzando le seguenti variabili di ambiente:

  • AWS_LAMBDA - chiarisce acme-dns-route53 tale esecuzione avviene all'interno di AWS Lambda.
  • DOMAINS — un elenco di domini separati da virgole.
  • LETSENCRYPT_EMAIL - contiene Crittifichiamo l'e-mail.
  • NOTIFICATION_TOPIC — nome dell'argomento di notifica SNS (facoltativo).
  • STAGING - al valore 1 viene utilizzato l'ambiente di staging.
  • 1024 MB - limite di memoria, può essere modificato.
  • 900 secondi (15 min) — timeout.
  • acme-dns-route53 — il nome del nostro binario, che è nell'archivio.
  • fileb://~/acme-dns-route53.zip - il percorso dell'archivio che abbiamo creato.

Ora distribuiamo:

$ 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"
 }

Creazione di un timer CloudWatch che attiva una funzione 2 volte al giorno

L'ultimo passaggio è impostare cron, che chiama la nostra funzione due volte al giorno:

  • creare una regola CloudWatch con il valore schedule_expression.
  • creare una destinazione della regola (cosa dovrebbe essere eseguito) specificando l'ARN della funzione lambda.
  • dare il permesso alla regola di chiamare la funzione lambda.

Di seguito ho allegato la mia configurazione Terraform, ma in realtà ciò avviene in modo molto semplice utilizzando la console AWS o l'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}"
}

Ora sei configurato per creare e aggiornare automaticamente i certificati SSL

Fonte: habr.com

Aggiungi un commento