Add a Free SSL Certificate to Your Website

Monday, May 9, 2016 🌐中文

http2

Why add an SSL certificate / use HTTPS?

The HTTP protocol commonly used on the internet transmits data in plaintext. Traffic is “transparent” on the network and can be abused by a man-in-the-middle.

In recent years, ISP hijacking has become more frequent and the barrier to launching attacks has gotten lower. For better security, use HTTPS to access your website. HTTPS provides strong encrypted transport and helps prevent transmitted data from being leaked or tampered with.

Preparation & environment

Server environment: DigitalOcean VPS, SG region, Debian Jessie, AMH hosting panel.

You’ll need:

Installation

Install & upgrade to OpenSSL 1.0.2

To enable HTTP/2 in NGINX, you must use this version of OpenSSL.

Note that accepting HTTP/2 connections over TLS requires the “Application-Layer Protocol Negotiation” (ALPN) TLS extension support, which is available only since OpenSSL version 1.0.2. Using the “Next Protocol Negotiation” (NPN) TLS extension for this purpose (available since OpenSSL version 1.0.1) is not guaranteed.

Download the OpenSSL source from the official site or GitHub:

wget https://github.com/openssl/openssl/archive/OpenSSL_1_0_2h.tar.gz
tar -zxvf ./OpenSSL_1_0_2h.tar.gz
cd ./openssl-OpenSSL_1_0_2h/

Choose an installation directory. If you’re upgrading, set the --prefix parameter to the directory where OpenSSL is installed:

./config --prefix=/usr/local/openssl --openssldir=/usr/local/ssl
make
make install
mv /usr/bin/openssl /usr/bin/openssl.OFF
mv /usr/include/openssl /usr/include/openssl.OFF
ln -s /usr/local/openssl/bin/openssl /usr/bin/openssl
ln -s /usr/local/openssl/include/openssl /usr/include/openssl
echo "/usr/local/openssl/lib">>/etc/ld.so.conf

Verify the OpenSSL version is now 1.0.2h:

openssl version -a

Install the Let’s Encrypt client

Fetch source code:

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

Install:

./letsencrypt-auto --help

Issue a certificate. Use -w for your website root path and -d for domain names. The certificate is based on the first domain. See the official documentation for details:

./letsencrypt-auto certonly --webroot -w /www/blog/ -d gorgiaxx.com -d blog.gorgiaxx.com

The certificate is valid for 3 months; you can renew it via a script (cron job):

0 0 1 * * /usr/local/nginx/sbin/nginx -s stop && /opt/letsencrypt-auto certonly --renew-by-default --webroot -w /www/blog/ -d gorgiaxx.com -d blog.gorgiaxx.com && /usr/local/nginx/sbin/nginx

Certificates are generated under this directory by default. NGINX will use the last two files:

root@gorgiaxx-ubuntu:~/tmp# ls /etc/letsencrypt/live/gorgiaxx.com
cert.pem  chain.pem  fullchain.pem  privkey.pem

Enable Certificate Transparency (CT)

Certificate Transparency was led by Google and standardized by the IETF as RFC 6962. The goal of CT is to provide an open auditing and monitoring system that enables any domain owner or CA to verify whether a certificate was mis-issued or maliciously used, thereby improving the security of HTTPS websites.

At the time of writing, CT is only supported by Chrome. Chrome also “knows” that CT adoption is not yet widespread, so the impact for HTTPS sites that don’t provide SCT information is not significant.

For details, see Certificate Transparency 那些事.

With the ct-submit module, you can conveniently submit certificates to CT log servers and obtain SCT responses:

apt-get install golang
wget -O ct-submit.zip -c https://github.com/grahamedgecombe/ct-submit/archive/v1.0.0.zip
unzip ct-submit.zip
cd ct-submit-1.0.0
go build

After building, execute and submit. Known CT log servers can be found here (blocked in some regions):

./ct-submit-1.0.0 ct.googleapis.com/aviator
</etc/letsencrypt/live/gorgiaxx.com/fullchain.pem
>/etc/letsencrypt/live/gorgiaxx.com/scts/aviator.sct
./ct-submit-1.0.0 ct.googleapis.com/pilot
</etc/letsencrypt/live/gorgiaxx.com/fullchain.pem
>/etc/letsencrypt/live/gorgiaxx.com/scts/pilot.sct
./ct-submit-1.0.0 ct.googleapis.com/rocketeer
</etc/letsencrypt/live/gorgiaxx.com/fullchain.pem
>/etc/letsencrypt/live/gorgiaxx.com/scts/rocketeer.sct

Install & upgrade NGINX

Download and extract NGINX and the nginx-ct module:

wget -O nginx-ct.zip https://github.com/grahamedgecombe/nginx-ct/archive/master.zip
unzip nginx-ct.zip

http://nginx.org/download/nginx-1.10.0.tar.gz
tar -zxvf nginx-1.10.0.tar.gz

/usr/local/nginx is my existing NGINX directory. I put installation files under /tmp/ temporarily.

Add brotli compression support for a better compression ratio (compatible with gzip):

git clone https://github.com/google/ngx_brotli.git
cd ngx_brotli
git submodule update --init
./configure --prefix=/usr/local/nginx --user=www --group=www --with-http_ssl_module --with-http_gzip_static_module --with-http_v2_module --with-http_stub_status_module --add-module=../nginx-ct-1.3.2 --add-module=../ngx_brotli
make

If make fails, add this to configure:

--with-openssl=/tmp/openssl-1.0.2h/

Replace the old binary:

cp -f objs/nginx /usr/local/nginx/sbin/nginx

Upgrade:

make upgrade

Configure NGINX

Change the listen port to 443 and add ssl and http2:

listen 443 ssl http2 default; #listen end

Enable ssl and ssl_ct, and add the SCT directory plus the certificate paths:

ssl on;
ssl_ct on;
ssl_ct_static_scts /etc/letsencrypt/live/gorgiaxx.com/scts/;
ssl_certificate /etc/letsencrypt/live/gorgiaxx.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/gorgiaxx.com/privkey.pem;

Reload NGINX:

/usr/local/nginx/sbin/nginx -s reload

As shown below, HTTP/2 and the CT policy have been enabled:

http2

CT is enabled:

ssl-ct

——————— Update (Nov 12, 2016): —————————

Newer versions of Let’s Encrypt use certbot to deploy certificates:

./certbot-auto certonly --standalone --email [email protected] -d gorgiaxx.com -d www.gorgiaxx.com -d blog.gorgiaxx.com -d api.gorgiaxx.com

Automatic renewal:

0 0 1 * * /usr/local/nginx/sbin/nginx -s stop && /opt/certbot-auto renew && /usr/local/nginx/sbin/nginx

——————— Update (Feb 9, 2017): —————————–

I kept getting expiration reminders (╯‵□′)╯︵┻━┻ — turns out certbot auto-updates itself on startup and depends on virtualenv. Since virtualenv wasn’t installed on the VPS, automatic renewal failed.

TinkeringcertbotSSLcertificate

Lenovo Y410p BIOS Recovery Notes

First Hardware Mod: OpenWrt on a Router