Skip to content

Run Certbot on AWS Lambda/Cloud Functions and upload certs to AWS Secrets Manager.

License

Notifications You must be signed in to change notification settings

KiraLT/certbot-lambda

Repository files navigation

Certbot Lambda

semantic-release Code style: black

Running Certbot on AWS Lambda and upload certs to AWS Secrets Manager.

Inspired by kingsoftgames/certbot-lambda and Deploying EFF's Certbot in AWS Lambda.

Features

Deployment

Download latest version of certbot-lambda.zip from releases.

AWS Lambda

  1. Create new lambda in Google Dashboard with Python 3.11 runtime.
  2. Upload certbot-lambda.zip at Code > Code source > Upload from > .zip file.
  3. Update handler to main.handler at Code > Runtime settings > Handler.
  4. Create new Execution role at Configuration > Execution role > Edit > Create a new role from AWS policy templates with name lambda-certbot.
  5. Go to created role by clicking on the name and Attach policies:
    • SecretsManagerReadWrite
    • AmazonRoute53FullAccess
  6. Increase execution timeout in Configuration > General configuration to 10 minutes and memory limit to 150Mb.
  7. Add ENV variables at Configuration > Environment variables (check bellow for required ENV variables).
  8. Run lambda manually one time to create a secret by going to Test and executing hello-wold template.

Automatic rotation

AWS secret can run created lambda periodically to generate new certs, for example, every month.

For that to work, update lambda and add new Resource-based policy at Configuration > Permissions -> Add permissions: * AWS Service: Secrets Manager * Statement ID: SecretsManagerAccess * Principal: secretsmanager.amazonaws.com * Action: lambda:InvokeFunction

Then go to AWS Secrets dashboard and create a rotation rule for created secrets - it should execute created lambda.

Google Function

  1. Create new function in Google Cloud dashboard.
  2. Set trigger Cloud Pub/Sub (create new topic).
  3. Add runtime environment variables according your needs (check configuration section and examples bellow).
  4. Increase timeout to 540 seconds.
  5. Select Python 3.11 runtime.
  6. Select Zip upload source code type and upload certbot-lambda.zip (you may need to create storage bucket where zip will be stored).
  7. Deploy function.

Environment variables

Name Description Default/required
CERTBOT_EMAILS Email used for registration and recovery contact. Use comma to register multiple emails, eg: u1@example.com,u2@example.com. required
CERTBOT_DOMAINS One or more domains that require certs generation. required
CERTBOT_DNS_PLUGIN DNS provider plugin name for acme challenge. E.g. dns-cloudflare, find plugin list here. required
CERTBOT_CREDENTIALS Credentials file content depending on CERTBOT_DNS_PLUGIN. E. g. {\n"type": "service_account",\n...} for dns-google plugin. required except for route53
CERTBOT_SERVER Letsencrypt API url. https://acme-v02.api.letsencrypt.org/directory
CERTBOT_DIR Temporary certbot directory where logs and generated certs will be stored. /tmp/certbot
CERTBOT_PREFERRED_CHAIN Force to use specified cert chain, e.g. ISRG Root X1
AWS_SECRET_NAME AWS secret name template, {domain} will be replaced with domain name. certbot-{domain}
AWS_SECRET_DESCRIPTION AWS secret name description text. Auto generated SSL certificate by lambda-certbot
CERTBOT_PROPAGATION_SECONDS The number of seconds to wait for DNS to propagate before asking the ACME server to verify the DNS record. Depends on dns plugin
CERTBOT_EXTRA_ARGS Additional arguments that will be passed to certbot.

Each DNS challenge plugin requires different configuration, check documentation for more information.

Letsencrypt

2021 September 30th Root CA X3 root certificate expired

Due to a bug in some versions of OpenSSL (1.0.0 - 1.0.2), GnuTLS (< 3.6.14), LibreSSL (< 3.2.0) and perhaps other TLS/SSL libraries as well, Let's Encrypt's certificates will be seen as invalid as a result of this invalid DST Root CA X3 certificate still being included.

To solve this issue, you can disable Root CA X3 certificate that is still included due to legacy support (mostly Android) by providing CERTBOT_PREFERRED_CHAIN=ISRG Root X1 environment variable.

Source: Laravel: Let's Encrypt Compatibility Changes

Examples

AWS Lambda to AWS Secrets using Route 53

Configuration

CERTBOT_EMAILS=name@example.com
CERTBOT_DOMAINS=*.example.com,example.com
CERTBOT_DNS_PLUGIN=dns-route53

In the lambda aws credentials are provided by default. Make sure lambda role has access to AWS Secrets and Route 53. Or you can configure them manually.

AWS Lambda to AWS Secrets using Cloudflare

Configuration

CERTBOT_EMAILS=name@example.com
CERTBOT_DOMAINS=*.example.com,example.com
CERTBOT_DNS_PLUGIN=dns-cloudflare
CERTBOT_CREDENTIALS="dns_cloudflare_api_token = 0123456789abcdef0123456789abcdef01234567"

In the lambda aws credentials are provided by default. Make sure lambda role has access to AWS Secrets. Or you can configure them manually.