Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save JPKCom/f34be0ecc00e5a530b10 to your computer and use it in GitHub Desktop.
Save JPKCom/f34be0ecc00e5a530b10 to your computer and use it in GitHub Desktop.
Letsencrypt Ubuntu 14.04 Nginx

#Letsencrypt Ubuntu 14.04 Nginx Letsencrypt (https://letsencrypt.org) is an initative which aims to increase the use of encryption for websites. It basically allows people to apply for free certificates provided that they prove the they control the requested domain.

Note: As of 7th Dec 2015 letsencrypt is still in public beta.

##Installation To install the client, clone the repostiory from github.

git clone https://github.com/letsencrypt/letsencrypt.git
cd letsencrypt

##Configure Nginx To prove that you have control of the domain for the requested certificate you need to show that you can allow letsencrypt.org to access a given file over the web. Therefore when you ask for a certificate the client will generate a unique id which should be put in a file on the web server. This is then accessed over the web to show that you control the domain.

The fist step is to setup nginx so that it will serve up the requested file when asked. letsencrypt.org is expecting to find the file in domain/.well-known/acme-challenge/ location (eg www.example.com/.well-known/acme-challenge). To setup this location, first setup the physical location. Since the default location for nginx is /usr/share/nginx/html, that is a good place. Create a specific location for each site (ie /usr/share/nginx/html/www.example.com).

cd /usr/share/nginx/html/www.example.com
mkdir -p .well-known/acme-challenge
cd .well-known/acme-challenge

This is the location where the file will need to be created, once the cert is requested.

To enable nginx to serve up the site we will need to edit the virtual site which is normally located in /etc/nginx/sites-available/

nano /etc/nginx/sites-available/www.example.com

The config file should be like this:

server {
    listen   80;
    listen   [::]:80;

    root /usr/share/nginx/html/www.example.com;
    server_name www.example.com;

    location /.well-known/acme-challenge {
        default_type text/plain;
    }

    error_page 404 /404.html;
}

Don't forget to reload the web server configuration (service nginx reload or systemctl reload nginx).

##Request the Certificate

./letsencrypt-auto certonly -a manual --rsa-key-size 4096 -d www.example.com

You can request more than one domain

./letsencrypt-auto certonly -a manual --rsa-key-size 4096 -d www.example.com -d example.com

##Verify Domain Ownership

The next step is to provide a file with certain content available under a special URL ie (www.example.com/.well-known/acme-challenge).

The request will generate a similar response like:

Make sure your web server displays the following content at                                                                                                                    
http://api.recinal.com/.well-known/acme-challenge/A-xjoIljw52X2SSQWqf9P5TQU9vv4HuPDBXN4qFDoRU before continuing:

A-xjoI1jw52X2SSQWqf9P5TQU9vv4HuPDBXN4qFDoRU.eefJYv1muREVb9TpEb3qjr9AQsM8IurTn-Svykj0wN0

If you don't have HTTP server configured, you can run the following
command on the target server (as root):

mkdir -p /tmp/letsencrypt/public_html/.well-known/acme-challenge
cd /tmp/letsencrypt/public_html
printf "%s" A-xjoI1jw52X2SSQWqf9P5TQU9vv4HuPDBXN4qFDoRU.eefJYv1muREVb9TpEb3qjr9AQsM8IurTn-Svykj0wN0 > .well-known/acme-challenge/A-xjoI1jw52X2SSQWqf9P5TQU9vv4HuPDBXN4qFDoRU
# run only once per server:
$(command -v python2 || command -v python2.7 || command -v python2.6) -c \
"import BaseHTTPServer, SimpleHTTPServer; \
s = BaseHTTPServer.HTTPServer(('', 80), SimpleHTTPServer.SimpleHTTPRequestHandler); \
s.serve_forever()" 
Press ENTER to continue

##Create the Verification File To create the file you will need a new terminal session. Do not click ENTER or it will try and find the file. In a new terminal session:

cd /usr/share/nginx/html
printf "%s" A-xjoI1jw52X2SSQWqf9P5TQU9vv4HuPDBXN4qFDoRU.eefJYv1muREVb9TpEb3qjr9AQsM8IurTn-Svykj0wN0 > .well-known/acme-challenge/A-xjoI1jw52X2SSQWqf9P5TQU9vv4HuPDBXN4qFDoRU

This will create the required file. Now click ENTER in the original terminal session. The correct response will look like:

IMPORTANT NOTES:
 - Congratulations! Your certificate and chain have been saved at
   /etc/letsencrypt/live/www.example.com/fullchain.pem. Your cert will
   expire on 2016-03-06. To obtain a new version of the certificate in
   the future, simply run Let's Encrypt again.
 - If like Let's Encrypt, please consider supporting our work by:

   Donating to ISRG / Let's Encrypt:   https://letsencrypt.org/donate
   Donating to EFF:                    https://eff.org/donate-le

##Configuring Nginx to use the SSL Certificate. The www.example.com configuration file should look like:

# NON-SSL
server {
    listen   80;
    listen   [::]:80;
    
    root /usr/share/nginx/html/www.example.com;

    server_name www.example.com;
    if ($scheme = http) {
        return 301 https://$server_name$request_uri;
    }   
}

# SSL
server {
    root /usr/share/nginx/html/www.example.com;

    listen 443 ssl spdy;
    server_name www.example.com;

    ssl on;
    ssl_certificate /etc/letsencrypt/live/www.example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/www.example.com/privkey.pem;

    ssl_stapling on;
    ssl_stapling_verify on;

    ssl_protocols 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$
    #ssl_dhparam /etc/nginx/ssl/dhparams.pem;
    ssl_prefer_server_ciphers on;
    ssl_session_cache shared:SSL:10m;
    
    
    add_header Strict-Transport-Security "max-age=31536000; includeSubdomains";            
              
	location ~* /\.\./ {
        deny all;
        return 404;
    }

    location / {
        proxy_pass http://127.0.0.1:4000; #app_servers 
        proxy_set_header Host      $host;
	proxy_set_header X-Real-IP $remote_addr;
    }
    
    location /.well-known/acme-challenge {
        default_type text/plain;
    }

    error_page 404 /404.html;
}

##SSL Check You can use https://www.ssllabs.com/ssltest to test your SSL configuration. The best result is an A+. To get a score higher than a B you will need to setup dhparams.

##dhparams To create a dhparams.pem certificate, first create the directory.

mkdir /etc/nginx/ssl
cd /etc/nginx/ssl

Then run the command to create the cert. Note I have choosen a 4096 bit certificate to make it future proof. This can take a while to run depending on the server.

openssl dhparam -out dhparams.pem 4096

Then add the following to the www.example.com configuration file.

ssl_dhparam /etc/nginx/ssl/dhparams.pem;

You should then be able to get a A+ rating.

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