tinyapps.org / docs / Migrating nginx from HTTP to HTTPS


  1. Research SSL certificates and authorities. Time required: an hour or two
  2. Purchase SSL certificate (DigiCert SSL Plus). Time required: a minute or two
  3. Generate command-line for CSR creation using OpenSSL CSR Wizard. Paste result into server's terminal, creating tinyapps_org.key and tinyapps_org.csr in /etc/ssl/. Paste tinyapps_org.csr into form in my DigiCert control panel. Time required: a few minutes
  4. Validate organization info with DigiCert. (They asked via email for a photo ID via email or fax; I later found out from phone support that they have a secure web form for submissions. I also later discovered that the cert was issued in my name instead of the corporation's; they verified the corp online with the DCCA and reissued the certificate.) Time required: 30 minutes from time of sending ID (plus another 30 minutes or so to receive the corrected certificate)
  5. Receive tinyapps_org.pem file from DigiCert and copy to /etc/ssl/. Time required: 'twas but the work of a moment
  6. Update iptables to allow incoming traffic on port 443 by adding
    -A INPUT -i eth0 -p tcp -m tcp --dport 443 -j ACCEPT
    to /etc/iptables.up.rules and reload iptables:
    iptables-restore < /etc/iptables.up.rules
    Time required: a few minutes to dig through my notes and Google
  7. Update OpenSSL (Time required: Longer than it should have; with these direction, should only take a few minutes):
    1. # wget https://www.openssl.org/source/openssl-1.0.1j.tar.gz | tar xvf && cd openssl-1.0.1j && ./config && make && make install
    2. The old version had not been replaced:
      # which openssl
      # openssl version
      OpenSSL 0.9.8g 19 Oct 2007
    3. Archive the old version and symlink the new one:
      # mv /usr/bin/openssl /path/to/ancients/openssl_old
      # ln -s /usr/local/ssl/bin/openssl /usr/bin/openssl
      # openssl version
      OpenSSL 1.0.1j 15 Oct 2014
  8. Update nginx (Time required: Way longer than it should have; with these direction, should only take a few minutes):
    1. # wget http://nginx.org/download/nginx-1.6.2.tar.gz | tar xvf nginx-1.6.2.tar.gz && cd nginx-1.6.2
    2. Checked configure arguments from previous install (nginx -V)
    3. Ran ./configure with previous arguments, adding:
      --with-openssl=/temp/openssl-1.0.1j \
      --with-http_ssl_module \
      --with-http_secure_link_module \

      (I had to explicitly point nginx to the OpenSSL source folder in order to get SSL working)
    4. # make
    5. Backup the current working nginx binary:
      # cp /usr/sbin/nginx /path/to/ancients/nginx_old
    6. # /etc/init.d/nginx stop
    7. # make install
    8. # /etc/init.d/nginx start
  9. Configure and test nginx (Time required: Way, way longer than it should have; with this example, it should be much faster):
    1. Below are the relevant bits from the nginx.conf file I ended up with in order to receive the coveted A+ rating from Qualys SSL Labs. To generate the ca-certs.pem file necessary for OCSP stapling, see Creating a .pem File for SSL Certificate Installations.
        server {
          # redirect www to non-www
          server_name www.tinyapps.org;
          return 301 $scheme://tinyapps.org$request_uri;
        server {
          # redirect http to https
          listen 80;
          server_name tinyapps.org;
          return 301 https://tinyapps.org$request_uri;
        server {
          listen 443 default_server ssl spdy;
          server_name tinyapps.org;
          ssl_certificate     /etc/ssl/tinyapps_org.pem;
          ssl_certificate_key /etc/ssl/tinyapps_org.key;
          # DHE parameter generated via: openssl dhparam -out /etc/ssl/dhparam.pem 4096
          ssl_dhparam /etc/ssl/dhparam.pem;
          # disable SSLv3 ref: POODLE
          ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
          # strong cipher suites only
          ssl_ciphers 'AES256+EECDH:AES256+EDH';
          ssl_prefer_server_ciphers on;
          keepalive_timeout    70;
          ssl_session_cache    shared:SSL:10m;
          ssl_session_timeout  10m;
          # HSTS (ngx_http_headers_module is required) (15768000 seconds = 6 months)
          add_header Strict-Transport-Security max-age=15768000;
          # enable OCSP stapling
          ssl_stapling on;
          ssl_stapling_verify on;
          ssl_trusted_certificate /etc/ssl/ca-certs.pem;

Resources and notes

created: 2014.12.23, updated: 2015.10.20