Automatisation de la gestion des certificats SSL Let's Encrypt à l'aide du challenge DNS-01 et AWS

L'article décrit les étapes pour automatiser la gestion des certificats SSL à partir de Chiffrons l'AC en utilisant Défi DNS-01 и AWS.

acme-dns-route53 est un outil qui nous permettra d'implémenter cette fonctionnalité. Il peut fonctionner avec les certificats SSL de Let's Encrypt, les enregistrer dans Amazon Certificate Manager, utiliser l'API Route53 pour implémenter le défi DNS-01 et, enfin, envoyer des notifications push vers SNS. DANS acme-dns-route53 Il existe également des fonctionnalités intégrées à utiliser dans AWS Lambda, et c'est ce dont nous avons besoin.

Cet article est divisé en 4 sections :

  • créer un fichier zip ;
  • créer un rôle IAM ;
  • créer une fonction lambda qui s'exécute acme-dns-route53;
  • créer une minuterie CloudWatch qui déclenche une fonction 2 fois par jour ;

Remarque: Avant de commencer, vous devez installer GoLang 1.9+ и CLI AWS

Création d'un fichier zip

acme-dns-route53 est écrit en GoLang et prend en charge la version non inférieure à 1.9.

Nous devons créer un fichier zip avec un binaire acme-dns-route53 à l'intérieur. Pour ce faire, vous devez installer acme-dns-route53 depuis le référentiel GitHub à l'aide de la commande go install:

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

Le binaire est installé dans $GOPATH/bin annuaire. Veuillez noter que lors de l'installation, nous avons spécifié deux environnements modifiés : GOOS=linux и GOARCH=amd64. Ils indiquent clairement au compilateur Go qu'il doit créer un binaire adapté au système d'exploitation Linux et à l'architecture amd64 - c'est ce qui fonctionne sur AWS.
AWS s'attend à ce que notre programme soit déployé dans un fichier zip, alors créons acme-dns-route53.zip archive qui contiendra le binaire nouvellement installé :

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

Remarque: Le binaire doit être à la racine de l'archive zip. Pour cela nous utilisons -j drapeau.

Maintenant notre pseudo zip est prêt à être déployé, il ne reste plus qu'à créer un rôle avec les droits nécessaires.

Création d'un rôle IAM

Nous devons mettre en place un rôle IAM avec les droits requis par notre lambda lors de son exécution.
Appelons cette politique lambda-acme-dns-route53-executor et donnez-lui immédiatement un rôle de base AWSLambdaBasicExecutionRole. Cela permettra à notre lambda d'exécuter et d'écrire des journaux sur le service AWS CloudWatch.
Tout d'abord, nous créons un fichier JSON qui décrit nos droits. Cela permettra essentiellement aux services lambda d'utiliser le rôle lambda-acme-dns-route53-executor:

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

Le contenu de notre dossier est le suivant :

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

Maintenant, exécutons la commande aws iam create-role pour créer un rôle :

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

Remarque: rappelez-vous l'ARN de la politique (Amazon Resource Name) - nous en aurons besoin dans les prochaines étapes.

Rôle lambda-acme-dns-route53-executor créé, nous devons maintenant spécifier les autorisations pour celui-ci. Le moyen le plus simple de procéder est d'utiliser la commande aws iam attach-role-policy, en transmettant l'ARN de la stratégie AWSLambdaBasicExecutionRole comme suit:

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

Remarque: une liste avec d'autres politiques peut être trouvée ici.

Création d'une fonction lambda qui s'exécute acme-dns-route53

Hourra! Vous pouvez maintenant déployer notre fonction sur AWS à l'aide de la commande aws lambda create-function. Le lambda doit être configuré à l'aide des variables d'environnement suivantes :

  • AWS_LAMBDA - c'est clair acme-dns-route53 cette exécution a lieu dans AWS Lambda.
  • DOMAINS — une liste de domaines séparés par des virgules.
  • LETSENCRYPT_EMAIL - contient Chiffrons les e-mails.
  • NOTIFICATION_TOPIC — nom du sujet de notification SNS (facultatif).
  • STAGING - à la valeur 1 un environnement de préparation est utilisé.
  • 1024 Mo - limite de mémoire, peut être modifiée.
  • 900 secondes (15 min) – délai d'attente.
  • acme-dns-route53 — le nom de notre binaire, qui se trouve dans l'archive.
  • fileb://~/acme-dns-route53.zip — le chemin d'accès à l'archive que nous avons créée.

Déployons maintenant :

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

Création d'une minuterie CloudWatch qui déclenche une fonction 2 fois par jour

La dernière étape consiste à configurer cron, qui appelle notre fonction deux fois par jour :

  • créer une règle CloudWatch avec la valeur schedule_expression.
  • créez une cible de règle (ce qui doit être exécuté) en spécifiant l'ARN de la fonction lambda.
  • autorisez la règle à appeler la fonction lambda.

Ci-dessous, j'ai joint ma configuration Terraform, mais en fait cela se fait très simplement à l'aide de la console AWS ou de 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}"
}

Vous êtes maintenant configuré pour créer et mettre à jour automatiquement les certificats SSL

Source: habr.com

Ajouter un commentaire