Skip to content

Instantly share code, notes, and snippets.

@jomurgel
Last active May 14, 2018 01:09
Show Gist options
  • Save jomurgel/083eaca8559f5391e9d8a514985244af to your computer and use it in GitHub Desktop.
Save jomurgel/083eaca8559f5391e9d8a514985244af to your computer and use it in GitHub Desktop.
Installing Let's Encrypt with Cerbot on DigitalOcean & ServerPilot
## Redirect all HTTP and www to HTTPS
RewriteEngine On
RewriteBase /
RewriteCond %{HTTP_HOST} ^www\.(.*)$ [NC]
RewriteRule ^(.*)$ https://%1/$1 [R=301,L]
RewriteCond %{HTTPS} !=on
RewriteRule ^/?(.*) https://%{SERVER_NAME}/$1 [R,L]

Let's Encrypt

SSH as root into the server

ssh root@SERVER_IP_ADDRESS

Install Certbot

wget https://dl.eff.org/certbot-auto
chmod a+x certbot-auto

Stop NGINX

service nginx-sp stop

Run the certbot-auto Script

./certbot-auto certonly --standalone -d DOMAIN_NAME.com -d www.DOMAIN_NAME.com

The first time you run this command the process will take a few minutes, after it's finished installing, follow on screen instructions and you should get a message similar to:

Congratulations! Your certificate and chain have been saved at /etc/letsencrypt/live/DOMAIN_NAME.com/fullchain.pem.

Add SSL config file

APP_NAME = ServerPilot App Name (eg serverpilot/apps/myapp) DOMAIN_NAME = Domain name (eg myawesomesite.com)

nano /etc/nginx-sp/vhosts.d/APP_NAME.ssl.conf

NOTE: The filename should match the serverpilot app name. Another way to know is to see what ever letsencrypt named what the files here /etc/nginx-sp/vhosts.d/APP_NAME.conf

server {
  listen 443 ssl http2;
  listen [::]:443 ssl http2;
  server_name DOMAIN_NAME.com www.DOMAIN_NAME.com;

  ssl on;

  # LetsEncrypt Certs
  ssl_certificate /etc/letsencrypt/live/DOMAIN_NAME.com/fullchain.pem;
  ssl_certificate_key /etc/letsencrypt/live/DOMAIN_NAME.com/privkey.pem;

  # Verify Chain of Trust of OCSP Repsonse
  # http://nginx.org/en/docs/http/ngx_http_ssl_module.html
  ssl_trusted_certificate /etc/letsencrypt/live/DOMAIN_NAME.com/chain.pem;

  # Secure SSL protocols and ciphers
  ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
  ssl_prefer_server_ciphers on;
  ssl_ciphers 'ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:CAMELLIA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA';
  ssl_session_timeout 1d;
  ssl_session_cache shared:SSL:50m;

  # OCSP Stapling
  ssl_stapling on;
  ssl_stapling_verify on;
  
  # Strict Transport Security
  # https://www.chromium.org/hsts
  add_header Strict-Transport-Security max-age=15768000;

  root   /srv/users/serverpilot/apps/APP_NAME/public;

  access_log  /srv/users/serverpilot/log/APP_NAME/APP_NAME_nginx.access.log  main;
  error_log  /srv/users/serverpilot/log/APP_NAME/APP_NAME_nginx.error.log;

   # Proxy Set
  proxy_set_header Host $host;
  proxy_set_header X-Real-IP $remote_addr;
  proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
  proxy_set_header X-Forwarded-SSL on;
  proxy_set_header X-Forwarded-Proto $scheme;
  
   # Includes
  include /etc/nginx-sp/vhosts.d/APP_NAME.d/*.nonssl_conf;
  include /etc/nginx-sp/vhosts.d/APP_NAME.d/*.conf;
}

Start NGINX

service nginx-sp start

Auto Renewing

Add crontab

crontab -e

# letsencrypt-auto renew command every Monday at 2:30 am
30 2 * * 1 ./letsencrypt/certbot-auto renew --pre-hook "service nginx-sp stop" --post-hook "service nginx-sp start" >> /var/log/letsencrypt-renew.log

Checking if a cert needs to be renewed

./certbot-auto renew

Adding a new subdomain to certs

certbot-auto certonly --standalone -d domain.com -d www.domain.com -d sub.domain.com -d sub2.domain.com --expand

Troubleshooting

Job for nginx-sp.service failed because the control process exited with error code. See "systemctl status nginx-sp.service" and "journalctl -xe" for details.

Might indicate a typo in your APP_NAME.ssl.conf config file. Example DOMAIN_NAME.com.com would break the service nginx-sp start process. Having a domain name that doesn't match one in your added domains would also break the start process.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment