Esta publicaci贸n describe los pasos necesarios para configurar la creaci贸n y renovaci贸n de certificados SSL autom谩ticos, utilizando Let's Encrypt como la Autoridad de Certificaci贸n automatizada, que proporciona una API bien mantenida.
acme-dns-route53
es la herramienta para obtener certificados SSL de Let's Encrypt usando el desaf铆o DNS-01 con Route53 y Amazon Certificate Manager de AWS. acme-dns-route53
tambi茅n tiene la funcionalidad incorporada para usar esta herramienta dentro de AWS Lambda, y esto es lo que vamos a hacer.
Esta publicaci贸n se divide en 4 secciones:
- construir un archivo zip desplegable e independiente
- crear un rol de IAM para la funci贸n lambda que le otorga los permisos necesarios para ejecutar
- creando una funci贸n lambda que ejecuta
acme-dns-route53
- crear un temporizador CloudWatch que active una funci贸n lambda dos veces al d铆a
Nota: antes de comenzar, aseg煤rese de que GoLang 1.9+ y AWS CLI ya est茅n instalados.
Construy贸 un archivo zip desplegable e independiente
acme-dns-route53
est谩 escrito en GoLang y la versi贸n de soporte no es inferior a 1.9. Necesitamos crear un archivo zip desplegable y aut贸nomo que contenga el ejecutable de la herramienta acme-dns-route53
.
El primer paso es construir un ejecutable desde el repositorio remoto de GitHub de la herramienta acme-dns-route53
usando el comando go install
:
$ env GOOS=linux GOARCH=amd64 go install github.com/begmaroman/acme-dns-route53
El ejecutable se instalar谩 en el $GOPATH/bin
. Importante: como parte de este comando, estamos usando env para establecer temporalmente dos variables de entorno durante la duraci贸n del comando ( GOOS=linux
y GOARCH=amd64
). Estos le indican al compilador Go que cree un ejecutable adecuado para usar con un sistema operativo Linux y una arquitectura amd64, que es en lo que se ejecutar谩 cuando lo implementemos en AWS.
AWS requiere que carguemos nuestras funciones lambda en un archivo zip, as铆 que hagamos un archivo zip acme-dns-route53.zip
que contenga el ejecutable que acabamos de crear:
$ zip -j ~/acme-dns-route53.zip $GOPATH/bin/acme-dns-route53
Tenga en cuenta que el ejecutable debe estar en la ra铆z del archivo zip, no en una carpeta dentro del archivo zip. Para asegurar esto, he usado la bandera -j
en el fragmento de arriba para los nombres de directorio basura.
Ahora el archivo zip se puede implementar, pero a煤n necesita permisos para ejecutarse.
Crear un rol de IAM para la funci贸n lambda que le otorgue los permisos necesarios para ejecutar
Necesitamos configurar un rol de IAM que defina el permiso que tendr谩 nuestra funci贸n lambda cuando se est茅 ejecutando.
Por ahora, configuremos un rol de lambda-acme-dns-route53-executor
y AWSLambdaBasicExecutionRole
pol铆tica administrada AWSLambdaBasicExecutionRole
. Esto le dar谩 a nuestra funci贸n lambda los permisos b谩sicos que necesita para ejecutarse e iniciar sesi贸n en el servicio AWS CloudWatch.
Primero, tenemos que crear un archivo JSON de pol铆tica de confianza. Esto esencialmente le indicar谩 a AWS que permita que los servicios lambda asuman el rol de lambda-acme-dns-route53-executor
:
$ touch ~/lambda-acme-dns-route53-executor-policy.json
El contenido del archivo JSON creado debe ser el siguiente:
{ "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/*" ] } ] }
Luego use el comando aws iam create-role
para crear el rol con esta pol铆tica de confianza:
$ aws iam create-role --role-name lambda-acme-dns-route53-executor \ --assume-role-policy-document ~/lambda-acme-dns-route53-executor-policy.json
Tome nota del ARN (nombre de recurso de Amazon) devuelto; lo necesitar谩 en el siguiente paso.
Ahora que se ha creado el rol lambda-acme-dns-route53-executor
, necesitamos especificar los permisos que tiene el rol. La forma m谩s f谩cil de hacer esto es usar el comando aws iam attach-role-policy
, pasando el ARN de la pol铆tica de permisos AWSLambdaBasicExecutionRole
de la AWSLambdaBasicExecutionRole
manera:
$ aws iam attach-role-policy --role-name lambda-acme-dns-route53-executor \ --policy-arn arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole
Nota: puede encontrar una lista de otras pol铆ticas de permisos que pueden ser 煤tiles aqu铆 .
Crear una funci贸n lambda que ejecute acme-dns-route53
Ahora estamos listos para implementar la funci贸n lambda en AWS, lo que podemos hacer con el comando aws lambda create-function
. La funci贸n lambda debe configurarse con las siguientes opciones:
AWS_LAMBDA
variable de entorno con valor 1
que ajusta la herramienta para usar dentro de la funci贸n Lambda.DOMAINS
es la variable de entorno que contiene una lista de dominios separados por comas para los que se emitir谩n certificados.LETSENCRYPT_EMAIL
es la variable de entorno que contiene el correo electr贸nico de caducidad Let's Encrypt.NOTIFICATION_TOPIC
es la variable de entorno que contiene el ARN del tema de notificaci贸n SNS.STAGING
es la variable de entorno que debe contener 1
valor para usar el entorno Let's Encrypt de puesta en escena o 0
para el entorno de producci贸n.RENEW_BEFORE
es el n煤mero de d铆as que define el per铆odo antes del vencimiento dentro del cual se debe renovar un certificado.1024
MB es el l铆mite de memoria (se puede cambiar si es necesario).900
segundos (15 min) es el tiempo de espera m谩ximo.acme-dns-route53
es el nombre del controlador de la funci贸n lambda.fileb://~/acme-dns-route53.zip
es el archivo .zip creado arriba.
Siga adelante e intente implementarlo:
$ 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" }
Crear un temporizador CloudWatch que active una funci贸n lambda una vez al d铆a
El 煤ltimo paso es crear un activador diario para la funci贸n. Para hacer esto podemos:
- cree una regla de CloudWatch con la expresi贸n_programaci贸n deseada (cu谩ndo deber铆a ejecutarse).
- crear un objetivo de regla (lo que deber铆a ejecutarse) especificando el ARN de la funci贸n lambda.
- otorgue permiso a la regla de CloudWatch para invocar la funci贸n lambda.
He pegado mi configuraci贸n de Terraform a continuaci贸n, pero tambi茅n es muy sencillo hacerlo desde la consola de AWS o desde la 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}" }
隆Ahora usted tambi茅n puede tener renovaciones de certificados TLS 100% automatizadas!