Set up SSL/TLS with StartSSL

StartSSL offers free SSL certificates that most browsers accept as a trusted [//en.wikipedia.org/wiki/Certificate_authority Certificate Authority] (CA). This means that sites served using StartSSL certificates will not draw any warnings from nearly all popular browsers when using the subdomains established for the certificate. In addition, StartSSL certificates support [//en.wikipedia.org/wiki/Server_Name_Indication Server Name Indication] (SNI), an extension of TLS that allows accepting more than one certificate from one IP address.

This article explains how to configure SSL/TLS with StartSSL on a LEMP web server configured as per the prior articles in this series. Note that the general procedure and configurations may be used with other Certificate Authorities.

Virtually every step in this article requires root level access:

username@servername:~$ sudo -i

Create domain key set
Installing the domain's key set is an important step in the process. It is important to guard this key as it will be used to encrypt the data transmitted in https sessions.

Create the private key set and signing requests
Create the directory that the key will be stored in. Each domain will have its own key and associated certificates, which should be put into respective directories. The password for the key can be very complex as it will very rarely be entered. Just don't forget it.

root@servername:~# mkdir -p /etc/ssl/private/example.com root@servername:~# openssl genrsa -aes256 -out /etc/ssl/private/example.com/server.key 4096 root@servername:~# openssl rsa -in /etc/ssl/private/example.com/server.key -out /etc/ssl/private/example.com/server.key.insecure root@servername:~# mv /etc/ssl/private/example.com/server.key /etc/ssl/private/example.com/server.key.secure root@servername:~# mv /etc/ssl/private/example.com/server.key.insecure /etc/ssl/private/example.com/server.key root@servername:~# chmod 400 /etc/ssl/private/example.com/{server.key,server.key.secure} root@servername:~# openssl req -sha256 -new -key /etc/ssl/private/example.com/server.key -out /etc/ssl/private/example.com/server.csr

Note that these steps should be performed precisely, as they are crucial to the proper function of the CA certificate. Once StartSSL has issued a certificate, it will be the only one authorized by StartSSL for the domain for 12 months, unless it is revoked. Revoking requires upgrading to Class 2 ($59.90) and paying a revocation fee ($29.90).

Using a different key for each domain allows for the moving of a domain to a different server without having to get a new certificate and without duplicating a private key being used for other domains, which would be a potential security risk should one of the servers be compromised.

At this point, it is a very good idea to back up the server's image or save the private keys in a separate, trusted location. If the keys are somehow lost, the associated certificate issued by StartSSL could no longer be used, thus requiring the above stated fees to recreate a certificate for the domain.

Create an account with StartSSL
Create an account with StartSSL. StartSSL uses certificate login. This certificate is installed into the browser and used to log users into the site.

After setting up the account and logging into the site, use the 'Validations Wizard' to validate the domain. To validate the domain, StartSSL will use the email address in the domain's whois record or a few specific email addresses (webmaster@example.com, postmaster@example.com, or hostmaster@example.com). For owners of domains using privacy protection, it will be required that the privacy protection service provider forward the email if the whois email address is desired for use. Most popular registrars immediately forward emails sent to privacy protected email addresses.

Obtain the certificate
After completing validation, under 'Certificates Wizard' select 'Web Server SSL/TLS Certificate'. Choose 'Skip' for the first step, 'Generate Private Key'. Now get the CSR from the server.

root@servername:~# nano /etc/ssl/private/example.com/server.csr

Highlight and copy absolutely everything from  to. Paste this into the field on the 'Submit Certificate Request (CSR)' page and click 'Continue'. If StartSSL does not accept the pasted CSR, try pasting into a text editor on the local device to make sure it has been copied to the clipboard correctly.

Select the domain and click 'Continue'.

The free StartSSL certificates ('Class 1') are only valid for the domain,  https://example.com , and one subdomain. Those desiring to use more than one subdomain will either have to deal with browser certificate warnings or purchase a 'Class 2' certificate, currently $59.90, which has the bonus of being applied to as many domains and subdomains as desired.

Note that using any subdomain other than www will cause browser certificate warnings in some browsers, alerting users that the certificate is unusual because there is no www subdomain in the certificate, even when the user is navigating to the StartSSL approved subdomain for the certificate.

StartSSL will inform users to wait for their verification email, however, this email often comes long after the domain has been verified. Note that domains 3 days old and younger will not be verified.

On the StartSSL website, go to 'Tool Box', 'Retrieve Certificate, select the domain and click 'Continue'. Highlight and copy everything from  to   then paste into the new file  :

root@servername:~# nano /etc/ssl/private/example.com/server.crt

Create the nginx unified certificate for the StartSSL Class 1 certificate
Add the StartSSL CA certificates to the server and create the domain's nginx unified cert. The StartSSL CA certificates (including the ca-bundle, which may be needed for other SSL usage), will be put into a StartSSL directory. This is convenient when using more than one CA.

root@servername:~# mkdir /etc/ssl/private/startssl root@servername:~# wget -O /etc/ssl/private/startssl/startssl-ca-bundle.pem https://www.startssl.com/certs/ca-bundle.pem root@servername:~# wget -O /etc/ssl/private/startssl/ca.pem https://www.startssl.com/certs/ca.pem root@servername:~# wget -O /etc/ssl/private/startssl/sub.class1.server.ca.pem https://www.startssl.com/certs/sub.class1.server.ca.pem root@servername:~# cat /etc/ssl/private/example.com/server.crt /etc/ssl/private/startssl/sub.class1.server.ca.pem > /etc/ssl/private/example.com/ssl-unified.crt

New StartSSL certificates
Startcom doesn't seem to do a good job at notifying anyone when their certificates change. it is a good idea to download all CA certificates whenever renewing a site's certificates. It is generally not required to update  for sites using certificates created with previous CA certificates - they can be updated at the next renewal.

nginx.conf
Edit :

root@servername:~# nano /etc/nginx/nginx.conf

Add at the bottom of the  block:

ssl_session_cache shared:SSL:10m;

The  will set up a shared cache for SSL sessions across all virtual hosts between all worker processes.

dhparam.pem
The default OpenSSL Diffe-Helman Ephemeral (DHE) parameter is 1024 bits, which is weaker than the key strength of the server's private key, thus clients using DHE will connect with a weaker encryption than non-DHE clients. Generate a strong DHE parameter. Note that this will take some time to complete and will use approximately 100% of one thread (1.00 load) for the duration of the task.

root@servername:~# openssl dhparam -out /etc/ssl/private/dhparam.pem 4096

Root certificate
Combine the StartSSL root certificate with the intermediate certificate into one file:

root@servername:~# cat /etc/ssl/private/startssl/ca.pem /etc/ssl/private/startssl/sub.class1.server.ca.pem > /etc/ssl/private/startssl/ca.sub.class1.pem

HTTPS server common configuration file
Create the HTTPS server file, which includes the common settings for SSL/TLS in an HTTPS server block:

root@servername:~# nano /etc/nginx/global-configs/https_server.conf

Add to the file:

location ~ /\. { access_log off; log_not_found off; deny all; } location ~ ~$ { access_log off; log_not_found off; deny all; } location = /favicon.ico { log_not_found off; access_log off; } location = /robots.txt { allow all; log_not_found off; access_log off; } ssl on; ssl_protocols TLSv1 TLSv1.1 TLSv1.2; ssl_ciphers AES256+EECDH:AES256+EDH:!aNULL; ssl_prefer_server_ciphers on; ssl_ecdh_curve secp521r1; ssl_dhparam /etc/ssl/private/dhparam.pem; ssl_stapling on; ssl_stapling_verify on; resolver  valid=300s; resolver_timeout 5s; ssl_trusted_certificate /etc/ssl/private/startssl/ca.sub.class1.pem; add_header Strict-Transport-Security "max-age=63072000;includeSubDomains"; add_header X-Frame-Options SAMEORIGIN; add_header X-Content-Type-Options nosniff;

SSL/TLS protocols and ciphers
The  are configured to leave out all variants of the SSL protocol and include only TLS. This is to protect against the [//en.wikipedia.org/wiki/POODLE POODLE attack]. The server should still be able to support the vast majority of devices, and given that it is already operating on SNI, most devices that don't support SNI also don't support any of the TLS protocols.

The  used are the strongest ciphers available and will yield a score of 100% on the Qualys SSL Labs SSL Report testing. The  directive instructs   not to use any cipher suites that offer no authentication.

Enabling  instructs the server to prefer server ciphers over client servers.

Setting the  instructs the server to use a stronger curve for ECDHE ciphers from the default curve of.

The  directive tells the server the location of the file to obtain DH parameters for DHE ciphers.

OCSP Stapling
Most clients will verify the validity of a server's certificate through either a [//en.wikipedia.org/wiki/Revocation_list Certificate Revocation List (CRL)] or [//en.wikipedia.org/wiki/Online_Certificate_Status_Protocol Online Certificate Status Protocol (OCSP)]. OCSP is typically preferred because the size of the CRLs is quite huge and pinging a server for a single record is a much faster method. Unfortunately, many OCSP servers are very slow and when a browser fails to look up an OCSP record, it doesn't inform the user and accepts the certificate. OCSP stapling will not work for newly generated certificates from StartSSL until the StartSSL OCSP server is updated, which may take up to 72 hours.

OCSP stapling is configured through several directives.

ssl_stapling
directive enables stapling of OCSP respones

enables verification of the responses by the server;

resolver
The  configures name servers used to resolve names of upstream servers into addresses. This can be either a domain or an IP address (both IPv6 or IPv4) and can be configured to accept only IPv4. Here are some examples:

OpenDNS IPv4: resolver 208.67.222.222 208.67.220.220 valid=300s;

OpenDNS IPv6: resolver 2620:0:ccc::2 valid=300s;

Google Public DNS: resolver 8.8.8.8 8.8.4.4 valid=300s;

A local network gateway using only IPv4: resolver 192.168.1.1 ipv6=off valid=300s;

The  sets a timeout for   name resolution.

ssl_trusted_certificate
OCSP stapling requires that the entire certificate chain be available. For StartSSL, the  directive is used to add the root certificate.

Verification
To verify OSCP stapling is working properly, use either the Qualys SSL Labs SSL Server Test and look in the test results for OCSP stapling Yes or run the following command:

root@servername:~# openssl s_client -connect example.com:443 -tls1 -tlsextdebug -status

Note that this command may not work for servers behind firewalls.

The output of a test failure will include the line:

OCSP response: no response sent

The output of a successful test will include:

OCSP response: ====================================== OCSP Response Data: OCSP Response Status: successful (0x0) ...

The popular SSL server tests performed by Qualys SSL Labs will perform two separate tests for servers that have both an IPv4 address and an IPv6 address. Startcom does not currently support IPv6 lookups, so a warning will be issued for the IPv6 test. See this Startcom forum post for more information.

HTTP headers
Several directives setting the [//en.wikipedia.org/wiki/List_of_HTTP_header_fields HTTP headers] can be used to enhance security.

HSTS
[//en.wikipedia.org/wiki/HTTP_Strict_Transport_Security HTTP Strict Transport Security] (HSTS) protects against downgrade attacks by telling a browser that after it has established a secure connection, it should only communicate using HTTPS.

Clickjacking prevention
This setting can prevent [//en.wikipedia.org/wiki/Clickjacking clickjacking] by setting controls on how a server may be viewed in a frame or an iframe. The example configuration of  will allow the site to be viewed in frames of the same origin server, which is a common feature in various popular PHP tools, including WordPress. Optionally, the  option could be used to prevent framing from any server. Note that there is an option for, but this is not well support by all popular browsers.

[//en.wikipedia.org/wiki/Content_Security_Policy Content Security Policy] (CSP) is being adopted and will replace  with its   option, but this is not yet widely supported.

X-Content-Type-Options
Adding the  prevents MIME-sniffing and is most important on sites that host user-uploaded content.

Add HTTPS server block to sites-available file
Open the sites-available file and add the HTTPS server block.

root@servername:~# nano /etc/nginx/sites-available/example.com

Add below the HTTP server block:

server { listen 443 ssl; listen [::]:443 ssl; root /var/www/example.com/public; access_log /var/www/example.com/logs/access.log; error_log /var/www/example.com/logs/error.log; server_name www.example.com; include global-configs/https_server.conf; ssl_certificate /etc/ssl/private/example.com/ssl-unified.crt; ssl_certificate_key /etc/ssl/private/example.com/server.key; location / { try_files $uri $uri/ =404; } }
 * 1) HTTPS server

Test then restart nginx.

root@servername:~# nginx -t nginx: the configuration file /etc/nginx/nginx.conf syntax is ok nginx: configuration file /etc/nginx/nginx.conf test is successful root@servername:~# service nginx reload * Reloading nginx configuration nginx                                  [ OK ]

Navigating to  https://example.com  (or  https://subdomain.example.com </tt>) should load  in a secure session.

Note that if the the local device's ISP has not yet updated to the new DNS records for the server, entering the IP address of the server should bring up the page, but with the browser's certificate warnings. Proceeding through these warnings should allow the user to view the certificate and verify its settings are correct. Presumably, once the DNS records have updated, the certificates should function normally.

Install ntp
The ntp package maintains the system clock instead of having only the default method for time synchronization,, which runs only once, when Ubuntu starts up. It is important for the clock to be synchronized because, theoretically, if a server goes a long time without being restarted, or a motherboard battery failure causes system clock malfunctions, it may end up having issues with the certificate authority.

root@servername:~# aptitude install ntp

Common configurations
The HTTPS server block is just as configurable as the HTTP server block, but some configurations are commonly desired by adminstrators.

Require location to load in HTTPS
To require a file or directory to load only in HTTPS, perform the following.

root@servername:~# nano /etc/nginx/sites-available/example.com

In the HTTP server block, add the following:

location ^~ /path/to/directory/or/file { return 301 https://$server_name$request_uri; }

Require subdomain or site to load in HTTPS
To require a subdomain or site to load only HTTPS, perform the following:

root@servername:~# nano /etc/nginx/sites-available/example.com

Add the following server block:

server { listen 80; listen [::]:80; server_name example.com www.example.com; access_log off; error_log /var/www/example.com/logs/error.log; return 301 https://subdomain.example.com$request_uri ; }

Next step
Install PHP, that oh-so-popular server-side scripting language.