Commands Only - Raspberry Pi Nginx HTTPS & SPDY Secure Web Server
Commands Only - For Professionals Only
Why and how you'd get the very latest Nginx installed on Raspbian (or Debian) & how to serve your site securely over HTTPS/SPDY
The default Nginx installed via apt-get is very old
Existing Nginx users
sudo cp -r /etc/nginx ~/Desktop/apt-get-nginx
Those of you who aren't yet running Nginx on your Pi
sudo apt-get install nginx
Everyone
sudo apt-get remove nginx
cd ~
wget https://gist.githubusercontent.com/MaXwellFalstein/eecfe12be81ef4698610/raw/c66aca57dc56a9241801f99f8175a477aba4c05c/build_nginx.sh
(You don't have to type all that, just copy and paste it into your Terminal)
Go to the following URLs and just check what the latest versions are:
https://www.openssl.org/source/
http://www.pcre.org/
http://nginx.org/en/download.html
sudo chmod +x build_nginx.sh
sudo ./build_nginx.sh
This will take quite a long time on the Pi – as in 20min or more.
If you did not have nginx installed previously, you're now set to go, you just need to start nginx (see the next section). You can set up a website in the normal way – if you don't know 'the normal way', try following my Setting up a (reasonably) secure home web server with Raspberry Pi tutorial, but skip the setting up the Pi and installation of nginx parts.
If you had nginx installed previously everything should just work for you now. However it might not. If not it's likely that the new version of nginx might be reading your existing config files expecting some form of new option, or be seeing an option in your configuration files that's no longer valid. You could tinker about and google until you know what's different, or you could 'revert' your /etc/nginx directory to the default contents nginx last compiled with, and then manually re-configure those while referencing your old files.
sudo mv /etc/nginx /etc/nginx-broken
sudo mv /etc/nginx-default /etc/nginx
Refer to the files in your nginx-broken directory and amend the ones in /etc/nginx.
sudo service nginx start
If you want to go down the selft-signed certificate route, follow this tutorial on how to create a self-signed certificate.
Once you have completed signing up for an SSL Certificate you should be in possession of three files:
yourdomain.key
yourdomain.pem
ca-bundle.pem
sudo mkdir /etc/nginx/my_ssl_certs
You need to get all of those files onto your pi and in that folder. If you've registered for the SSL Cert directly on your Pi you can just download them in the normal way. If you've been registering via a different machine and are using the Pi through Terminal only, you're going to need to download the files onto the machine you've been using for registering and then use scp to move them from that machine onto your pi, e.g., On the machine you've downloaded the files onto…
scp yourdomain.key yourdomain.pem ca-bundle.pem pi@IPOFYOURPI:~/
Now, ssh onto your Pi and move those files into the directory we want. We didn't copy them directly there as the pi user shouldn't have permission to write files into /etc/nginx.
On your Pi:
sudo mv ~/yourdomain.key ~/yourdomain.pem ~/ca-bundle.pem /etc/nginx/my_ssl_certs
Last thing, we need to create one more file for use when Perfect Forward Secrecy algorithms are used (which we absolutely want).
Again, on the pi, and inside the /etc/nginx/my_ssl_certs directory;
Warning: this command will take a long time to complete!
sudo openssl dhparam -rand - 4096 >> dhparam.pem
When you run this, the program means what it says; it's going to take a long time, almost 24hrs for a 4096bit value. If you want, change that to 2048 instead and it'll lop the time off considerably (but be less secure). Now might be a good time to read a few chapters of a decent book (I can recommend anything by Brandon Sanderson, if you're interested). Or you could go learn why big prime numbers make things secure (that's what this is doing; making a huge prime number).
With all files now on your pi and in the /etc/nginx/my_ssl_certs directory you can use them to secure your site!
In the nginx file that defines your site (/etc/nginx/sites-available/yoursite) you'll need to set the following (adjusting to your needs, this is a basic set-up which forbids HTTP and enforces HTTPS, using SPDY if SPDY is available on the browser that's trying to connect):
server {
# REDIRECT HTTP TO HTTPS
server_name yourdomain.com;
add_header Strict-Transport-Security max-age=15768000;
return 301 https://yourdomain.com$request_uri;
}
server {
# SET THE SITE UP FOR SSL
listen 443 ssl spdy;
# Get SSL setup
ssl on;
ssl_certificate /etc/nginx/my_ssl_certs/yourdomain.pem;
ssl_certificate_key /etc/nginx/my_ssl_certs/yourdomain.key;
ssl_dhparam /etc/nginx/my_ssl_certs/dhparam.pem;
ssl_session_timeout 5m;
ssl_protocols SSLv3 TLSv1 TLSv1.1 TLSv1.2;
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:ECDHE-RSA-RC4-SHA:ECDHE-ECDSA-RC4-SHA:AES128:AES256:RC4-SHA:HIGH:!aNULL:!eNULL:!EXPORT:!DES:!3DES:!MD5:!PSK';
ssl_prefer_server_ciphers on;
ssl_session_cache shared:SSL:50m;
# Enable HSTS
add_header Strict-Transport-Security max-age=15768000;
# OCSP Stapling
ssl_stapling on;
ssl_stapling_verify on;
ssl_trusted_certificate /etc/nginx/my_ssl_certs/ca-bundle.pem;
resolver 8.8.8.8;
# NOW CONFIGURE YOUR SITE BELOW, e.g,
server_name yourdomain.com;
root /path/to/your/website/files;
index index.html index.htm;
access_log /path/to/your/website/logs/access.log;
error_log /path/to/your/website/logs/error.log;
error_page 404 /404.html;
location / {
try_files $uri $uri/;
}
Be sure to replace the list of ssl_ciphers from this example with whatever the latest recommended cipher-suite from Mozilla is – choosing good ciphers in a good order is complex; you can render your server far less secure by doing this bit wrong – so just grab what the experts have compiled and use that.
Restart nginx as follows:
sudo service nginx restart
Your site should now be serving over HTTPS. To test it, run your domain through https://www.ssllabs.com/ssltest/