This article demonstrate how to Get SSL certificate from a free SSL certificate authority Let’s Encrypt. Install to nginx server, and get a A+ ranking on SSL Labs.

使用免費公益組織 ISRG 提供的 SSL 憑證服務 Let’s Encrypt,將 nginx web server 加上 HTTPS 的 SSL 安全連線機制。並且在第三方SSL安全測試機制 SSL Labs 的測試中獲得 A+ 等級評價。

img

References - 參考了下面幾個資源:

  1. SSL 精闢的整體說明 by huangiyang
  2. 安裝過程說明
  3. 更多在 nginx 上的 SSL 細節

Steps - 安裝過程

$ cd /opt
$ curl -LO https://github.com/lukas2511/dehydrated/archive/v0.6.2.tar.gz
$ tar -zxvf v0.6.2.tar.gz
$ ln -s /opt/dehydrated-0.6.2 /opt/dehydrated
$ chmod a+x /opt/dehydrated/dehydrated
$ mkdir -p /var/www/dehydrated/

Add configuration to corresponding vhost in nginx. 在 nginx 設定中對應的 vhost ,加入認證要用的網站路徑,認證完就可以刪除了。
注意 這個憑證有效期是 90 天,到期前需要更新憑證;更新憑證時,仍然需要這個網站路徑設定。

$ vim /etc/nginx/sites-available/default 

# add 3 lines:
location /.well-known/acme-challenge/ {
    alias /var/www/dehydrated/;
}

Generate SSL certificates. Replace ‘mysite.org’ by your real domain name. 產生 SSL certificates, 請自行替換真實的域名

# restart nginx to make configuration take effect.
$ sudo systemctl restart nginx

# Accept terms of service of letsencrypt.org
$ /opt/dehydrated/dehydrated --register --accept-terms

# Generate certificats for first time
$ /opt/dehydrated/dehydrated -c -d mysite.org
# If you have multiple subdomains, use this command instead:
$ /opt/dehydrated/dehydrated -c -d mysite.org -d sub1.mysite.org -d sub2.mysite.org

# If it works, there shouble be cert files under folder: /opt/dehydrated/certs/mysite.org/
$ ls -al /opt/dehydrated/certs/mysite.org/
total 32
drwx------ 2 root root 4096 Dec 26 14:31 .
drwx------ 4 root root 4096 Dec 26 12:24 ..
-rw------- 1 root root 1659 Dec 26 12:24 cert-1488328510.csr
-rw------- 1 root root 2151 Dec 26 12:24 cert-1488328510.pem
lrwxrwxrwx 1 root root   19 Dec 26 12:24 cert.csr -> cert-1488328510.csr
lrwxrwxrwx 1 root root   19 Dec 26 12:24 cert.pem -> cert-1488328510.pem
-rw------- 1 root root 1647 Dec 26 12:24 chain-1488328510.pem
lrwxrwxrwx 1 root root   20 Dec 26 12:24 chain.pem -> chain-1488328510.pem
-rw------- 1 root root 3798 Dec 26 12:24 fullchain-1488328510.pem
lrwxrwxrwx 1 root root   24 Dec 26 12:24 fullchain.pem -> fullchain-1488328510.pem
-rw------- 1 root root 3243 Dec 26 12:24 privkey-1488328510.pem
lrwxrwxrwx 1 root root   22 Dec 26 12:24 privkey.pem -> privkey-1488328510.pem

# Make a strong DHE (Diffie-Hellman) parameter to replace nginx's default OpenSSL 1024 bit key
# This process will take about 10 minutes...
$ openssl dhparam -out /opt/dehydrated/certs/mysite.org/dhparam.pem 4096

Add certificates configuration to nginx,the parameters can be found here: cipherli.st

        listen *:443 ssl;
        ssl_certificate /opt/dehydrated/certs/mysite.org/fullchain.pem;
        ssl_certificate_key /opt/dehydrated/certs/mysite.org/privkey.pem;
        ssl_dhparam /opt/dehydrated/certs/mysite.org/dhparam.pem;

        ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
        ssl_prefer_server_ciphers on;
        ssl_ciphers "EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH";
        ssl_ecdh_curve secp384r1; # Requires nginx >= 1.1.0
        ssl_session_cache shared:SSL:10m;
        ssl_session_tickets off; # Requires nginx >= 1.5.9
        ssl_stapling on; # Requires nginx >= 1.3.7
        ssl_stapling_verify on; # Requires nginx => 1.3.7
        resolver_timeout 5s;
        add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload";
        add_header X-Frame-Options DENY;
        add_header X-Content-Type-Options nosniff;

Since my nginx serve as reversed proxy for r-server running on localhost:8000, my nginx config file looks like this:

CAUTION !!!

DO NOT add this header: add_header X-Frame-Options DENY;, because this header will cause RStudio failed to show document, upload file, etc… in the iframe.

        listen *:443 ssl;
        ssl_certificate /opt/dehydrated/certs/mysite.org/fullchain.pem;
        ssl_certificate_key /opt/dehydrated/certs/mysite.org/privkey.pem;
        ssl_dhparam /opt/dehydrated/certs/mysite.org/dhparam.pem;

        server_name mysite.org;

        root /var/www/mysite.org;
        index index.html;

        location / {
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_pass http://localhost:8000;
        }

        ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
        ssl_prefer_server_ciphers on;
        ssl_ciphers "EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH";
        ssl_ecdh_curve secp384r1; # Requires nginx >= 1.1.0
        ssl_session_cache shared:SSL:10m;
        ssl_session_tickets off; # Requires nginx >= 1.5.9
        ssl_stapling on; # Requires nginx >= 1.3.7
        ssl_stapling_verify on; # Requires nginx => 1.3.7
        resolver_timeout 5s;
        add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload";
        # DO NOT add this header !!!! DENY will cause R-Studio UI fail
        # to show document, upload, etc in the iframe.
        # add_header X-Frame-Options DENY;
        add_header X-Content-Type-Options nosniff;

restart nginx:

sudo systemctl restart nginx

Use SSL Labs to test your website,you should get a rank of A+.

Update the certificate

The certificate is only valid for 3 months. You need to update it before before it expires. Here’s how to do this:

/opt/dehydrated/dehydrated -c -d your.domain.name
/usr/sbin/service nginx reload