Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Select an option

  • Save andrew-pause/2c58c606bd271a396d4e393b514e9b45 to your computer and use it in GitHub Desktop.

Select an option

Save andrew-pause/2c58c606bd271a396d4e393b514e9b45 to your computer and use it in GitHub Desktop.

Revisions

  1. mikob revised this gist Feb 28, 2016. 1 changed file with 8 additions and 8 deletions.
    16 changes: 8 additions & 8 deletions README.md
    Original file line number Diff line number Diff line change
    @@ -10,14 +10,14 @@ Requirements

    IAM User required Permissions
    ------------------------------
    `cloudfront:ListDistributions`
    `cloudfront:GetDistributionConfig`
    `cloudfront:UpdateDistribution`
    `elasticloadbalancing:DescribeLoadBalancers`
    `elasticloadbalancing:SetLoadBalancerListenerSSLCertificate`
    `iam:ListServerCertificates`
    `iam:UploadServerCertificate`
    `iam:DeleteServerCertificate`
    `cloudfront:ListDistributions`
    `cloudfront:GetDistributionConfig`
    `cloudfront:UpdateDistribution`
    `elasticloadbalancing:DescribeLoadBalancers`
    `elasticloadbalancing:SetLoadBalancerListenerSSLCertificate`
    `iam:ListServerCertificates`
    `iam:UploadServerCertificate`
    `iam:DeleteServerCertificate`

    Passing the Let's Encrypt Challenge
    ------------------------------------
  2. mikob revised this gist Feb 28, 2016. 3 changed files with 64 additions and 11 deletions.
    1 change: 1 addition & 0 deletions AWS, ELB, CF and Let's Encrypt
    Original file line number Diff line number Diff line change
    @@ -0,0 +1 @@
    Elastic Load Balancer, CloudFront and Let's Encrypt
    12 changes: 8 additions & 4 deletions README.md
    Original file line number Diff line number Diff line change
    @@ -1,8 +1,6 @@
    This simple bash script will check if a ssl certificate expires within a defined threshold, perform a letsencrypt certificate renewal, upload the new certificate and set loadbalancers to use the new certificate. It is perfect for those who want to use Let's Encrypt with their SSL-enabled ELB. It uses the aws-cli and letsencrypt.
    This simple bash script will check if a ssl certificate expires within a defined threshold, perform a letsencrypt certificate renewal, upload the new certificate and set loadbalancers to use the new certificate. It can optionally update a cloudfront distribution to use the same certificate and delete any old certificates. It is perfect for those who want to use Let's Encrypt with their SSL-enabled ELB and or CloudFront. It uses the aws-cli and letsencrypt.

    It is recommended to be run in as a daily cron-job. If the certificate does not need to be renewed, the script will print "The certificate is up to date, no need for renewal..." and do nothing.

    Based off of script found here: https://vincent.composieux.fr/article/install-configure-and-automatically-renew-let-s-encrypt-ssl-certificate. Also, for a much more comprehensive solution see here: https://github.com/alex/letsencrypt-aws.
    It is recommended to be run in as a daily cron-job. If the certificate does not need to be renewed, the script will print "The certificate is up to date, no need for renewal..." and do nothing. You can force a renewal with the `--force` option.

    Requirements
    ------------
    @@ -12,8 +10,14 @@ Requirements

    IAM User required Permissions
    ------------------------------
    `cloudfront:ListDistributions`
    `cloudfront:GetDistributionConfig`
    `cloudfront:UpdateDistribution`
    `elasticloadbalancing:DescribeLoadBalancers`
    `elasticloadbalancing:SetLoadBalancerListenerSSLCertificate`
    `iam:ListServerCertificates`
    `iam:UploadServerCertificate`
    `iam:DeleteServerCertificate`

    Passing the Let's Encrypt Challenge
    ------------------------------------
    62 changes: 55 additions & 7 deletions auto-cert-renewal.sh
    Original file line number Diff line number Diff line change
    @@ -1,11 +1,30 @@
    #!/bin/bash
    #
    # [1] "If you're using a CA other than AWS Certificate Manager and if you want to
    # use the same certificate both for CloudFront and for other AWS services,
    # you must upload the certificate twice: once for CloudFront and once for the
    # other services." (http://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/SecureConnections.html#CNAMEsAndHTTPS)
    #
    # If using your cert on cloudfront, make sure your cloudfront distribution has
    # a behavior for .well-known/acme-challenge/* that lets requests through to
    # the origin. You will probably need to forward the 'host' header in this behavior.
    #
    # References:
    # http://marketing.intracto.com/renew-https-certificate-on-amazon-cloudfront
    # https://vincent.composieux.fr/article/install-configure-and-automatically-renew-let-s-encrypt-ssl-certificate
    # https://github.com/alex/letsencrypt-aws

    CONFIG_FILE='/usr/local/etc/le-exampledomain-webroot.ini'
    LE_PATH='/opt/letsencrypt'
    LOAD_BALANCER_NAME='exampleloadbalancer'
    export AWS_DEFAULT_PROFILE='ExampleProfile'
    export AWS_DEFAULT_REGION='us-west-2'

    EXP_LIMIT=30;
    EXP_LIMIT=30
    UPDATE_CLOUDFRONT=true
    # deletes the old certs
    DELETE_OLD=false


    if [ ! -f $CONFIG_FILE ]; then
    echo "[ERROR] config file does not exist: $CONFIG_FILE"
    @@ -25,28 +44,57 @@ EXP_DAYS=$(echo \( $EXP_DATE - $DATE_NOW \) / 86400 |bc)

    echo "Checking expiration date for $DOMAIN..."

    if [ "$EXP_DAYS" -gt "$EXP_LIMIT" ] ; then
    if [ "$EXP_DAYS" -gt "$EXP_LIMIT" ] && [ "$1" != "--force" ] ; then
    echo "The certificate is up to date, no need for renewal ($EXP_DAYS days left)."
    exit 0;
    else
    echo "The certificate for $DOMAIN is about to expire soon. Starting webroot renewal script..."
    $LE_PATH/letsencrypt-auto certonly --agree-tos --renew-by-default --config $CONFIG_FILE
    CERT_NAME="auto_cert_`date +%m-%d-%y_%H-%M-%S`"
    echo "Uploading $CERT_NAME to IAM"
    # path needs to be this to work for cloudfront (will work with elb too)
    CERT_RES=$(aws iam upload-server-certificate \
    --server-certificate-name $CERT_NAME \
    --certificate-body file:///etc/letsencrypt/live/$DOMAIN/cert.pem \
    --private-key file:///etc/letsencrypt/live/$DOMAIN/privkey.pem \
    --output json)
    --certificate-chain file:///etc/letsencrypt/live/$DOMAIN/chain.pem \
    --path /cloudfront/production/ \
    --output json
    )
    echo $CERT_RES
    CERT_ARN=$(echo $CERT_RES | python -c 'import json,sys;obj=json.load(sys.stdin);print(obj["ServerCertificateMetadata"]["Arn"])')
    echo $CERT_ARN
    NEW_CERT_ARN=$(echo $CERT_RES | python -c 'import json,sys;obj=json.load(sys.stdin);print(obj["ServerCertificateMetadata"]["Arn"])')
    echo $NEW_CERT_ARN
    echo "Updating ELB IAM cert..."
    sleep 20
    aws elb set-load-balancer-listener-ssl-certificate \
    --load-balancer-name $LOAD_BALANCER_NAME \
    --load-balancer-port 443 \
    --ssl-certificate-id $CERT_ARN
    --ssl-certificate-id $NEW_CERT_ARN
    if [ UPDATE_CLOUDFRONT = true ] ; then
    echo "Updating cloudfront distribution..."
    aws configure set preview.cloudfront true
    DISTRIBUTION=$(aws cloudfront list-distributions --query \
    "DistributionList.Items[0].{DistributionId: Id}" --output text)
    OLD_CERT_ARN=$(aws cloudfront list-distributions --query "DistributionList.Items[0].ViewerCertificate.Certificate" --output text)
    aws cloudfront get-distribution-config --id $DISTRIBUTION --query 'DistributionConfig' --output json > /tmp/dist_config.json
    sed -i "s/$OLD_CERT_ARN/$NEW_CERT_ARN/" /tmp/dist_config.json
    aws cloudfront update-distribution \
    --id $DISTRIBUTION \
    --distribution-config file:///tmp/dist_config.json
    echo "Done updating cloudfront"
    fi
    echo "Renewal process finished for domain $DOMAIN"

    # TODO: test!
    if [ DELETE_OLD = true ] ; then
    echo "Deleting ALL old certs in 10 minutes..."
    sleep 600
    aws iam list-server-certificates --query \
    "ServerCertificateMetadataList[?ServerCertificateName != '$CERT_NAME'].ServerCertificateName" \
    --output text | xargs -n 1 aws iam \
    delete-server-certificate \
    --server-certificate-name
    echo "Deleted old certificates"
    fi
    exit 0;
    fi
    fi
  3. mikob revised this gist Feb 21, 2016. No changes.
  4. mikob revised this gist Feb 21, 2016. 1 changed file with 11 additions and 2 deletions.
    13 changes: 11 additions & 2 deletions README.md
    Original file line number Diff line number Diff line change
    @@ -2,10 +2,19 @@ This simple bash script will check if a ssl certificate expires within a defined

    It is recommended to be run in as a daily cron-job. If the certificate does not need to be renewed, the script will print "The certificate is up to date, no need for renewal..." and do nothing.

    Based off of script found here: https://vincent.composieux.fr/article/install-configure-and-automatically-renew-let-s-encrypt-ssl-certificate.
    Based off of script found here: https://vincent.composieux.fr/article/install-configure-and-automatically-renew-let-s-encrypt-ssl-certificate. Also, for a much more comprehensive solution see here: https://github.com/alex/letsencrypt-aws.

    Requirements
    ------------
    * awscli (`pip install awscli`)
    * letsencrypt (`git clone https://github.com/letsencrypt/letsencrypt`)
    * bc (`apt-get install bc`)
    * bc (`apt-get install bc`)

    IAM User required Permissions
    ------------------------------
    `elasticloadbalancing:SetLoadBalancerListenerSSLCertificate`
    `iam:UploadServerCertificate`

    Passing the Let's Encrypt Challenge
    ------------------------------------
    Handling of ACME challenge is not done through this script. The config file for LE should define a `webroot-path` where letsencrypt can write a hash. For example in the `/web/root/path/.well-known/acme-challenge` directory. That path should be accessible by let's encrypts servers so your cert renewal request can be authenticated. This script will need access to the acme-challenge directory to write a hash. If you are dockerizing the script, you can use the --volumes-from feature and attach this dockerized service to your nginx/apache/other webserver that hosts the acme challenge.
  5. mikob created this gist Feb 21, 2016.
    11 changes: 11 additions & 0 deletions README.md
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,11 @@
    This simple bash script will check if a ssl certificate expires within a defined threshold, perform a letsencrypt certificate renewal, upload the new certificate and set loadbalancers to use the new certificate. It is perfect for those who want to use Let's Encrypt with their SSL-enabled ELB. It uses the aws-cli and letsencrypt.

    It is recommended to be run in as a daily cron-job. If the certificate does not need to be renewed, the script will print "The certificate is up to date, no need for renewal..." and do nothing.

    Based off of script found here: https://vincent.composieux.fr/article/install-configure-and-automatically-renew-let-s-encrypt-ssl-certificate.

    Requirements
    ------------
    * awscli (`pip install awscli`)
    * letsencrypt (`git clone https://github.com/letsencrypt/letsencrypt`)
    * bc (`apt-get install bc`)
    52 changes: 52 additions & 0 deletions auto-cert-renewal.sh
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,52 @@
    #!/bin/bash
    CONFIG_FILE='/usr/local/etc/le-exampledomain-webroot.ini'
    LE_PATH='/opt/letsencrypt'
    LOAD_BALANCER_NAME='exampleloadbalancer'
    export AWS_DEFAULT_PROFILE='ExampleProfile'
    export AWS_DEFAULT_REGION='us-west-2'

    EXP_LIMIT=30;

    if [ ! -f $CONFIG_FILE ]; then
    echo "[ERROR] config file does not exist: $CONFIG_FILE"
    exit 1;
    fi

    DOMAIN=`grep "^\s*domains" $CONFIG_FILE | sed "s/^\s*domains\s*=\s*//" | sed 's/(\s*)\|,.*$//'`
    CERT_FILE="/etc/letsencrypt/live/$DOMAIN/fullchain.pem"

    if [ ! -f $CERT_FILE ]; then
    echo "[ERROR] certificate file not found for domain $DOMAIN."
    fi

    DATE_NOW=$(date -d "now" +%s)
    EXP_DATE=$(date -d "`openssl x509 -in $CERT_FILE -text -noout | grep "Not After" | cut -c 25-`" +%s)
    EXP_DAYS=$(echo \( $EXP_DATE - $DATE_NOW \) / 86400 |bc)

    echo "Checking expiration date for $DOMAIN..."

    if [ "$EXP_DAYS" -gt "$EXP_LIMIT" ] ; then
    echo "The certificate is up to date, no need for renewal ($EXP_DAYS days left)."
    exit 0;
    else
    echo "The certificate for $DOMAIN is about to expire soon. Starting webroot renewal script..."
    $LE_PATH/letsencrypt-auto certonly --agree-tos --renew-by-default --config $CONFIG_FILE
    CERT_NAME="auto_cert_`date +%m-%d-%y_%H-%M-%S`"
    echo "Uploading $CERT_NAME to IAM"
    CERT_RES=$(aws iam upload-server-certificate \
    --server-certificate-name $CERT_NAME \
    --certificate-body file:///etc/letsencrypt/live/$DOMAIN/cert.pem \
    --private-key file:///etc/letsencrypt/live/$DOMAIN/privkey.pem \
    --output json)
    echo $CERT_RES
    CERT_ARN=$(echo $CERT_RES | python -c 'import json,sys;obj=json.load(sys.stdin);print(obj["ServerCertificateMetadata"]["Arn"])')
    echo $CERT_ARN
    echo "Updating ELB IAM cert..."
    sleep 20
    aws elb set-load-balancer-listener-ssl-certificate \
    --load-balancer-name $LOAD_BALANCER_NAME \
    --load-balancer-port 443 \
    --ssl-certificate-id $CERT_ARN
    echo "Renewal process finished for domain $DOMAIN"
    exit 0;
    fi