Automatizando Let's Encrypt SSL Certificate Management usando DNS-01 challenge y AWS

La publicación describe los pasos para automatizar la administración de certificados SSL de Let's Encrypt CA usando el desafío DNS-01 y AWS .


acme-dns-route53 es una herramienta que nos permitirá implementar esta función. Sabe cómo trabajar con certificados SSL de Let's Encrypt, guardarlos en Amazon Certificate Manager, usar la API Route53 para implementar el desafío DNS-01 y, al final, enviar notificaciones a SNS. Acme-dns-route53 también tiene una funcionalidad incorporada para usar dentro de AWS Lambda, y esto es lo que necesitamos.


Este artículo está dividido en 4 secciones:


  • crear un archivo zip;
  • creando un rol de IAM;
  • creando una función lambda que ejecuta acme-dns-route53 ;
  • crear un temporizador CloudWatch que active una función 2 veces al día;

Nota: Antes de comenzar, debe instalar GoLang 1.9+ y AWS CLI


Crea un archivo zip


acme-dns-route53 está escrito en GoLang y admite la versión no inferior a 1.9.


Necesitamos crear un archivo zip con el acme-dns-route53 dentro. Para hacer esto, instale acme-dns-route53 desde el repositorio de GitHub usando el comando go install :


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

El binario se instala en el $GOPATH/bin . Tenga en cuenta que durante la instalación especificamos dos variables de entorno: GOOS=linux y GOARCH=amd64 . Le dejan claro al compilador Go sobre la necesidad de crear un binario adecuado para el sistema operativo Linux y la arquitectura amd64: esto es lo que se ejecuta en AWS.
AWS asume la implementación de nuestro programa en un archivo zip, así que acme-dns-route53.zip un archivo acme-dns-route53.zip que contendrá el binario recién instalado:


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

Nota: el binario debe estar en la raíz del archivo zip. Para esto usamos la bandera -j .


Ahora nuestro apodo zip está listo para la implementación, solo queda para crear un rol con los derechos necesarios.


Crear roles de IAM


Necesitamos afirmar el rol de IAM con los privilegios que nuestra lambda necesita durante su ejecución.
Llamemos a esta política lambda-acme-dns-route53-executor e inmediatamente le demos el rol básico de AWSLambdaBasicExecutionRole . Esto permitirá que nuestro lambda se inicie y escriba registros en el servicio AWS CloudWatch.
Primero, cree un archivo JSON que describa nuestros derechos. Esto esencialmente permitirá que los servicios lambda utilicen la función lambda-acme-dns-route53-executor :


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

El contenido de nuestro archivo es 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/*" ] } ] } 

Ahora ejecute el comando aws iam create-role para crear el rol:


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

Nota: recuerde la política ARN (Nombre de recurso de Amazon): la necesitaremos en los próximos pasos.


Se ha creado el rol lambda-acme-dns-route53-executor , ahora necesitamos especificar permisos para ello. La forma más fácil de hacer esto es usar el comando aws iam attach-role-policy , pasando la AWSLambdaBasicExecutionRole ARN AWSLambdaBasicExecutionRole siguiente manera:


 $ aws iam attach-role-policy --role-name lambda-acme-dns-route53-executor \ --policy-arn arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole 

Nota: una lista con otras políticas se puede encontrar aquí .


Crear una función lambda que ejecute acme-dns-route53


¡Hurra! Ahora puede implementar nuestra función en AWS utilizando el comando aws lambda create-function . La lambda debe configurarse utilizando las siguientes variables de entorno:


  • AWS_LAMBDA : hace que acme-dns-route53 entienda que la ejecución se produce dentro de AWS Lambda.
  • DOMAINS : una lista de dominios separados por comas.
  • LETSENCRYPT_EMAIL - Contiene Let's Encrypt Email .
  • NOTIFICATION_TOPIC - Nombre del tema de notificación SNS (opcional).
  • STAGING : si se establece en 1 , se utiliza el entorno de ensayo.
  • RENEW_BEFORE : la cantidad de días que determinan el período anterior al vencimiento del período durante el cual se debe renovar el certificado.
  • 1024 MB - límite de memoria, sujeto a cambios.
  • 900 segundos (15 min) - tiempo de espera.
  • acme-dns-route53 - el nombre de nuestro binario, que está en el archivo.
  • fileb://~/acme-dns-route53.zip : ruta al archivo que creamos.

Ahora despliegue:


 $ 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 2 veces al día


El último paso es configurar la corona, que llama a nuestra función dos veces al día:


  • Cree una regla de CloudWatch con un valor de schedule_expression .
  • cree el objetivo de la regla (lo que debe hacerse) especificando el ARN de la función lambda.
  • dar permiso a la regla que llama a la función lambda.

A continuación adjunté mi configuración de Terraform, pero de hecho se hace de manera muy simple usando la consola de AWS o la CLI de AWS.


 # 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 está configurado para crear y renovar automáticamente certificados SSL

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


All Articles