# 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 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 SSLOptions +StdEnvVars SSLOptions +StdEnvVars 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 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"