אוטומציה של ניהול תעודות SSL של Let's Encrypt באמצעות אתגר DNS-01 ו-AWS

הפוסט מתאר שלבים לאוטומציה של ניהול תעודות SSL מ בואו להצפין CA באמצעות אתגר DNS-01 и AWS.

acme-dns-route53 הוא כלי שיאפשר לנו ליישם תכונה זו. זה יכול לעבוד עם אישורי SSL מ-Let's Encrypt, לשמור אותם במנהל התעודות של Amazon, להשתמש ב-API של Route53 כדי ליישם את אתגר ה-DNS-01, ולבסוף, לדחוף התראות ל-SNS. IN acme-dns-route53 יש גם פונקציונליות מובנית לשימוש בתוך AWS Lambda, וזה מה שאנחנו צריכים.

מאמר זה מחולק ל-4 חלקים:

  • יצירת קובץ zip;
  • יצירת תפקיד IAM;
  • יצירת פונקציית למבדה שפועלת acme-dns-route53;
  • יצירת טיימר CloudWatch שמפעיל פונקציה 2 פעמים ביום;

הערה: לפני שתתחיל אתה צריך להתקין GoLang 1.9+ и AWS CLI

יצירת קובץ zip

acme-dns-route53 כתוב ב-GoLang ותומך בגרסה שאינה נמוכה מ-1.9.

אנחנו צריכים ליצור קובץ zip עם קובץ בינארי acme-dns-route53 בְּתוֹך. כדי לעשות זאת אתה צריך להתקין acme-dns-route53 ממאגר GitHub באמצעות הפקודה go install:

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

הבינארי מותקן ב $GOPATH/bin מַדרִיך. שימו לב שבמהלך ההתקנה ציינו שתי סביבות שהשתנו: GOOS=linux и GOARCH=amd64הם אומרים למהדר של Go ליצור קובץ בינארי שמתאים ל Linux ארכיטקטורות מערכת הפעלה ו-amd64 הן מה שפועלות ב-AWS.
AWS מצפה שהתוכנית שלנו תיפרס בקובץ zip, אז בואו ניצור acme-dns-route53.zip ארכיון שיכיל את הבינארי שהותקן לאחרונה:

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

הערה: הקובץ הבינארי צריך להיות בשורש של ארכיון ה-zip. בשביל זה אנחנו משתמשים -j דֶגֶל.

כעת כינוי ה-zip שלנו מוכן לפריסה, כל מה שנותר הוא ליצור תפקיד עם הזכויות הדרושות.

יצירת תפקיד IAM

אנחנו צריכים להקים תפקיד IAM עם הזכויות הנדרשות על ידי הלמבדה שלנו במהלך ביצועו.
בואו נקרא לזה מדיניות lambda-acme-dns-route53-executor ומיד לתת לה תפקיד בסיסי AWSLambdaBasicExecutionRole. זה יאפשר למבדה שלנו להפעיל ולכתוב יומנים לשירות AWS CloudWatch.
ראשית, אנו יוצרים קובץ JSON שמתאר את הזכויות שלנו. זה בעצם יאפשר לשירותי למבדה להשתמש בתפקיד lambda-acme-dns-route53-executor:

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

התוכן של הקובץ שלנו הוא כדלקמן:

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

עכשיו בואו נריץ את הפקודה aws iam create-role כדי ליצור תפקיד:

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

הערה: זכור את המדיניות ARN (שם משאב אמזון) - נצטרך אותה בשלבים הבאים.

תפקידו של lambda-acme-dns-route53-executor נוצר, כעת עלינו לציין הרשאות עבורו. הדרך הקלה ביותר לעשות זאת היא להשתמש בפקודה aws iam attach-role-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

הערה: ניתן למצוא רשימה עם מדיניות אחרת כאן.

יצירת פונקציית למבדה שפועלת acme-dns-route53

הידד! עכשיו אתה יכול לפרוס את הפונקציה שלנו ל-AWS באמצעות הפקודה aws lambda create-function. יש להגדיר את הלמבדה באמצעות משתני הסביבה הבאים:

  • AWS_LAMBDA - מבהיר acme-dns-route53 שהביצוע מתרחש בתוך AWS Lambda.
  • DOMAINS - רשימה של תחומים מופרדים בפסיקים.
  • LETSENCRYPT_EMAIL - מכיל בואו להצפין אימייל.
  • NOTIFICATION_TOPIC - שם נושא הודעת SNS (אופציונלי).
  • STAGING - לפי הערך 1 נעשה שימוש בסביבת הבמה.
  • 1024 MB - מגבלת זיכרון, ניתן לשינוי.
  • 900 שניות (15 דקות) - פסק זמן.
  • acme-dns-route53 - שם הבינארי שלנו, שנמצא בארכיון.
  • fileb://~/acme-dns-route53.zip - הדרך לארכיון שיצרנו.

עכשיו בואו נפרוס:

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

יצירת טיימר CloudWatch שמפעיל פונקציה 2 פעמים ביום

השלב האחרון הוא להגדיר את cron, שקורא לפונקציה שלנו פעמיים ביום:

  • צור כלל CloudWatch עם הערך schedule_expression.
  • צור יעד כלל (מה יש לבצע) על ידי ציון ה-ARN של פונקציית lambda.
  • לתת רשות לכלל לקרוא לפונקציית lambda.

למטה צירפתי את תצורת ה- Terraform שלי, אבל למעשה זה נעשה בצורה פשוטה מאוד באמצעות קונסולת AWS או 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}"
}

כעת אתה מוגדר ליצור ולעדכן באופן אוטומטי תעודות SSL

מקור: www.habr.com

קנה אירוח אמין לאתרים עם הגנת DDoS, שרתי VPS VDS 🔥 קנה אחסון אתרים אמין עם הגנת DDoS, שרתי VPS VDS | ProHoster