Automatització de la gestió de certificats SSL de Let's Encrypt mitjançant DNS-01 Challenge i AWS

La publicació descriu els passos per automatitzar la gestió dels certificats SSL des de Xifrem CA utilitzant Repte DNS-01 и AWS.

acme-dns-route53 és una eina que ens permetrà implementar aquesta característica. Pot funcionar amb certificats SSL de Let's Encrypt, desar-los a Amazon Certificate Manager, utilitzar l'API Route53 per implementar el repte DNS-01 i, finalment, notificacions push a SNS. EN acme-dns-route53 També hi ha una funcionalitat integrada per utilitzar-la dins d'AWS Lambda, i això és el que necessitem.

Aquest article està dividit en 4 seccions:

  • crear un fitxer zip;
  • crear un rol IAM;
  • creant una funció lambda que s'executi acme-dns-route53;
  • crear un temporitzador de CloudWatch que activa una funció 2 vegades al dia;

Nota: Abans de començar cal instal·lar-lo GoLang 1.9+ и AWS CLI

Creació d'un fitxer zip

acme-dns-route53 està escrit a GoLang i admet una versió no inferior a 1.9.

Hem de crear un fitxer zip amb un binari acme-dns-route53 dins. Per fer-ho, cal instal·lar-lo acme-dns-route53 des del dipòsit de GitHub mitjançant l'ordre go install:

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

El binari està instal·lat a $GOPATH/bin directori. Tingueu en compte que durant la instal·lació vam especificar dos entorns canviats: GOOS=linux и GOARCH=amd64. Deixen clar al compilador Go que ha de crear un binari adequat per al sistema operatiu Linux i l'arquitectura amd64: això és el que s'executa a AWS.
AWS espera que el nostre programa es desplegui en un fitxer zip, així que creem acme-dns-route53.zip arxiu que contindrà el nou binari instal·lat:

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

Nota: El binari hauria d'estar a l'arrel de l'arxiu zip. Per a això fem servir -j bandera.

Ara el nostre àlies zip està preparat per al desplegament, només queda crear un rol amb els drets necessaris.

Creació d'un rol IAM

Hem de configurar un rol IAM amb els drets que requereix la nostra lambda durant la seva execució.
Anomenem aquesta política lambda-acme-dns-route53-executor i donar-li immediatament un paper bàsic AWSLambdaBasicExecutionRole. Això permetrà que la nostra lambda s'executi i escrigui registres al servei AWS CloudWatch.
Primer, creem un fitxer JSON que descriu els nostres drets. Això permetrà bàsicament als serveis lambda utilitzar el rol lambda-acme-dns-route53-executor:

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

El contingut del nostre fitxer és el següent:

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

Ara executem l'ordre aws iam create-role per crear un rol:

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

Nota: recordeu la política ARN (Amazon Resource Name) - la necessitarem en els passos següents.

Paper lambda-acme-dns-route53-executor creat, ara hem d'especificar-hi els permisos. La manera més senzilla de fer-ho és utilitzar l'ordre aws iam attach-role-policy, aprovant la política ARN AWSLambdaBasicExecutionRole de la manera següent:

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

Nota: es pot trobar una llista amb altres polítiques aquí.

Creació d'una funció lambda que s'executi acme-dns-route53

Hura! Ara podeu implementar la nostra funció a AWS mitjançant l'ordre aws lambda create-function. El lambda s'ha de configurar mitjançant les variables d'entorn següents:

  • AWS_LAMBDA - ho deixa clar acme-dns-route53 aquesta execució es produeix dins d'AWS Lambda.
  • DOMAINS — una llista de dominis separats per comes.
  • LETSENCRYPT_EMAIL - conté Xifrem el correu electrònic.
  • NOTIFICATION_TOPIC — nom del tema de notificació SNS (opcional).
  • STAGING - al valor 1 s'utilitza un entorn d'escenificació.
  • 1024 MB - límit de memòria, es pot canviar.
  • 900 segons (15 min) — temps d'espera.
  • acme-dns-route53 — el nom del nostre binari, que es troba a l'arxiu.
  • fileb://~/acme-dns-route53.zip — el camí cap a l'arxiu que hem creat.

Ara despleguem:

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

Creació d'un temporitzador de CloudWatch que activa una funció 2 vegades al dia

L'últim pas és configurar cron, que crida a la nostra funció dues vegades al dia:

  • creeu una regla de CloudWatch amb el valor schedule_expression.
  • creeu un objectiu de regla (el que s'ha d'executar) especificant l'ARN de la funció lambda.
  • donar permís a la regla per cridar la funció lambda.

A continuació, he adjuntat la meva configuració de Terraform, però de fet això es fa de manera molt senzilla utilitzant la consola AWS o 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}"
}

Ara esteu configurat per crear i actualitzar automàticament certificats SSL

Font: www.habr.com

Afegeix comentari