Skip to content

Instantly share code, notes, and snippets.

@harshpatel991
Last active August 2, 2017 14:08
Show Gist options
  • Save harshpatel991/aa7c060029df83d04a3c744474e98d4a to your computer and use it in GitHub Desktop.
Save harshpatel991/aa7c060029df83d04a3c744474e98d4a to your computer and use it in GitHub Desktop.
AWS Elastic Beanstalk config for signed SSL certificate using a single instance with Lets Encrypt certbot and apache.
# This will setup a hardened SSL/TLS for an Elastic Beanstalk application configured to use a single EC2 instance using Apache
# This configuration should get you an A on the Qualys SSL Server Test.
# This configuration will continue to serve unsecure requests on port 80.
# Be sure to verify you are using the latest version of your platform in Elastic Beanstalk.
# The following Environment Properties are *required* to be set:
# CERT_EMAIL - this is the email address passed to certbot-auto
# SERVER_DOMAIN - the DNS name that will be assoicated with the certificate (ex: domain.com)
# SERVER_ALIAS - an alternate DNS name that will also be assoicated with the certificate (ex: www.domain.com)
# Optionally you can set:
# CERT_BOT_ADDITIONAL_FLAGS - any addtional flags to cert bot (ex. if you are testing, set this to --staging)
# This will also setup your certificate to auto-check renewal twice a day.
# This configuration does not setup certificate backup. If you are terminating your application servers multiple times a week,
# you should backup and restore your SSL cert and key to prevent running into any Lets Encrypt rate limits. Normally,
# Elastic Beanstalk application deploys don't terminate the server so this may not be required for your setup.
# What this does
# 1. Modifies the instance's security group to allow incomming connections on port 443.
# 2. Installs the Apache module mod_ssl (this creates /etc/httpd/conf.d/ssl.conf, a certificate, and a key)
# 3. Overwrites ssl.conf with options to harden SSL/TLS against known vulnerabilities
# 4. Downloads certbot-auto
# 5. Adds your ServerName and ServerAlias to ssl.conf so that certbot knows which VirtualHosts to modify
# 6. Runs certbot-auto to get and install your certificate if there is not one already installed
# 7. Sets up a cron to renew certs if necessary.
# Resources
# http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/SSL-on-an-instance.html#letsencrypt
# http://docs.aws.amazon.com/elasticbeanstalk/latest/dg/https-singleinstance-php.html
Resources:
sslSecurityGroupIngress:
Type: AWS::EC2::SecurityGroupIngress
Properties:
GroupId: {"Fn::GetAtt" : ["AWSEBSecurityGroup", "GroupId"]}
IpProtocol: tcp
ToPort: 443
FromPort: 443
CidrIp: 0.0.0.0/0
packages:
yum:
mod24_ssl : []
epel-release: []
files:
/etc/httpd/conf.d/ssl.conf:
mode: "000644"
owner: root
group: root
content: |
Listen 443 https
SSLPassPhraseDialog exec:/usr/libexec/httpd-ssl-pass-dialog
SSLSessionCache shmcb:/run/httpd/sslcache(512000)
SSLSessionCacheTimeout 300
SSLRandomSeed startup file:/dev/urandom 256
SSLRandomSeed connect builtin
SSLCryptoDevice builtin
<VirtualHost _default_:443>
ErrorLog logs/ssl_error_log
TransferLog logs/ssl_access_log
LogLevel warn
SSLEngine on
# these will be replaced by the 40_getcert command below
SSLCertificateFile "/etc/pki/tls/certs/localhost.crt"
SSLCertificateKeyFile "/etc/pki/tls/private/localhost.key"
SSLCipherSuite ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:AES:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA
SSLProxyCipherSuite ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:AES:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA
SSLHonorCipherOrder On
SSLProtocol -SSLv2 -SSLv3 -TLSv1 -TLSv1.1 +TLSv1.2
SSLProxyProtocol -SSLv2 -SSLv3 -TLSv1 -TLSv1.1 +TLSv1.2
<Files ~ "\.(cgi|shtml|phtml|php3?)$">
SSLOptions +StdEnvVars
</Files>
<Directory "/var/www/cgi-bin">
SSLOptions +StdEnvVars
</Directory>
BrowserMatch "MSIE [2-5]" \
nokeepalive ssl-unclean-shutdown \
downgrade-1.0 force-response-1.0
CustomLog logs/ssl_request_log \
"%t %h %{SSL_PROTOCOL}x %{SSL_CIPHER}x \"%r\" %b"
# these will be filled in by 20_add_server_name and 30_add_server_alias below
ServerName
ServerAlias
</VirtualHost>
container_commands:
00_createdir:
command: "sudo mkdir /opt/certbot || true"
10_installcertbot:
command: "sudo wget -O /opt/certbot/certbot-auto https://dl.eff.org/certbot-auto ;sudo chmod a+x /opt/certbot/certbot-auto"
20_add_server_name:
command: 'sudo sed /etc/httpd/conf.d/ssl.conf -e "s;ServerName.*;ServerName ${SERVER_DOMAIN};" -i'
30_add_server_alias:
command: 'sudo sed /etc/httpd/conf.d/ssl.conf -e "s;ServerAlias.*;ServerAlias ${SERVER_ALIAS};" -i'
40_getcert:
command: "sudo /opt/certbot/certbot-auto --debug --non-interactive --apache --email ${CERT_EMAIL} --agree-tos --domains ${SERVER_DOMAIN},${SERVER_ALIAS} --keep-until-expiring --apache-vhost-root /etc/httpd/conf.d/ssl.conf ${CERT_BOT_ADDITIONAL_FLAGS}"
50_cronjob_renew:
command: "echo -e \"30 2,14 * * * root /opt/certbot/certbot-auto renew --no-self-upgrade\n\" > /etc/cron.d/certificate_renew && chmod 644 /etc/cron.d/certificate_renew"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment