Ubuntu 16.04 + NginX + Lets Encrypt(SSL)

參考網址 https://blog.technologyofkevin.com/?p=591

Step 1: 安裝 letsencrypt

sudo apt update
sudo apt install letsencrypt

Step 2: 取得一個 SSL 證書

1.開啟網頁服務軟體 well-know 功能,並設定網域名稱

編輯nginx的設定檔 。

vi /etc/nginx/sites-available/default

然後在server 後面的大括號中寫入資料。

location ~ /.well-known {
        allow all;
}

設定網域名稱。

server_name _;

將上面改成如下,www.example.com請自行修改為自己的網域名稱。

server_name example.com;

用 nginx 的預設測試指令查看內容有沒有錯誤。

nginx -t

若測試正常提示中會有下方的提示,出錯請再檢查一下設定檔。

nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful

 

2.重新啟動 nginx 網頁服務軟體

/etc/init.d/nginx restart

 

3.製作 SSL 證書,並且使用EMAIL做註冊

首先我們要知道webroot-path的路徑, webroot-path一般如下。

root /var/wwww/html/;

接下來輸入下方指令,example.com請改成自己的網域。

sudo letsencrypt certonly -a webroot --webroot-path=/var/www/html -d example.com

其中會要我們輸入信箱,每個信箱是有上限的,如果信箱已經使用太多次,他就不能繼續申請了。最後同意 Lets Encrypt 使用條款,他就會開始製作 SSL Key,最後完成的資料會顯示如下,基本上看到 Congratulations 就是成功了。

IMPORTANT NOTES:
 - If you lose your account credentials, you can recover through
   e-mails sent to sammy@digitalocean.com
 - Congratulations! Your certificate and chain have been saved at
   /etc/letsencrypt/live/example.com/fullchain.pem. Your
   cert will expire on 2016-03-15. To obtain a new version of the
   certificate in the future, simply run Let's Encrypt again.
 - Your account credentials have been saved in your Let's Encrypt
   configuration directory at /etc/letsencrypt. You should make a
   secure backup of this folder now. This configuration directory will
   also contain certificates and private keys obtained by Let's
   Encrypt so making regular backups of this folder is ideal.
 - 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

這便要記下一個路徑 /etc/letsencrypt/live/example.com/ ,因為伺服器的 SSL Key 就是存在這邊。這路徑之後會使用。

 

4.製作安全性更高的 Diffie-Hellman

為了增加系統安全性,我們產生一個 2048bit 的 Diffie-Hellman

openssl dhparam -out /etc/ssl/certs/dhparam.pem 2048

生成的檔案就會在 /etc/ssl/certs/dhparam.pem 這個也是以後會用到。

 

Step 3: 在Web服務軟體上配置TLS/SSL

1.製作一個檔案裡面會包含 SSL Key,讓 Nginx 讀取

我們要在 /etc/nginx/snippets 的目錄裡面製作檔案,檔案名稱建議為 ssl-domain.conf ,domain 換成大家自己擁有的名稱。

vi /etc/nginx/snippets/ssl-example.com.conf

在這檔案中我們要寫入兩筆資料,ssl_certificate ssl_certificate_key,並且指向檔案的位置,這裡的位置是在上一步我們製作 SSL Key 的位置。不果四個檔案我們只需要使用其中兩個 fullchain.pem, privkey.pem

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

2.製作一個檔案包含一些 Nginx 的 SSL 設定

vi /etc/nginx/snippets/ssl-params.conf

檔案內容的設定我們參照 Remy van Elst 所提出的建議,利用 Cipherli.st 中 Nginx 設定部,然後再加入部分資料就可以了。設定DNS部分交給地 google DNS,並且把上一步製作的 2048bit Diffie-Hellman 在最後一行導入。

# from https://cipherli.st/
# and https://raymii.org/s/tutorials/Strong_SSL_Security_On_nginx.html
 
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;
ssl_session_cache shared:SSL:10m;
ssl_session_tickets off;
ssl_stapling on;
ssl_stapling_verify on;
resolver 8.8.8.8 8.8.4.4 valid=300s;
resolver_timeout 5s;
add_header Strict-Transport-Security "max-age=63072000; includeSubdomains";
add_header X-Frame-Options DENY;
add_header X-Content-Type-Options nosniff;
 
ssl_dhparam /etc/ssl/certs/dhparam.pem;

3.修改 Nginx 的設定檔案,並且讓上面兩個檔案包含進去

將 default 檔案備份,這樣錯誤發生後才有辦法復原,然後在原本 default 寫入 SSL 設定。

cp /etc/nginx/sites-available/default /etc/nginx/sites-available/default.bak

修改檔案

vi /etc/nginx/sites-available/default

檔案一開頭就有監聽 port 號碼,以及 iPv6 支援性的撰寫。這邊有兩種配置寫法,一種是系統只支援加密連接,也就是 443 port 的連接,另外一種是保留 80 以及 443 的服務,也就是可以同時使用加密以及步加密兩種並存,現在會先介紹只有加密連接。這邊可以發現如果要只能有加密連接,那麼就必須寫兩個 server 設定,並將無加密連接轉成加密連接。

server {
    listen 80 default_server;
    listen [::]:80 default_server;
    server_name example.com www.example.com;
    return 301 https://$server_name$request_uri;
}
 
server {
 
    # SSL configuration
 
    listen 443 ssl http2 default_server;
    listen [::]:443 ssl http2 default_server;
    server_name example.com www.example.com;
    include snippets/ssl-example.com.conf;
    include snippets/ssl-params.conf;

下方為兩種連接方式並存,我們不用再設定兩個 server ,把所有資料寫在同一個 server 即可。

server {
    listen 80 default_server;
    listen [::]:80 default_server;
    listen 443 ssl http2 default_server;
    listen [::]:443 ssl http2 default_server;
 
    server_name example.com www.example.com;
    include snippets/ssl-example.com.conf;
    include snippets/ssl-params.conf;
}

Step 4: 啟動Web服務軟體

利用 Nginx 內建指令檢查剛剛的設定是否正確。

nginx -t

如果沒有問題我們就可以重新啟動服務。

/etc/init.d/nginx restart

最後我們可以測試我們的網站,利用 Qualys SSL Labs Report 查看網站的安全性是否可以順利拿到 A+ 的成績。

 

Step 5: 自動更新憑證

letsencrypt 更新指令如下

letsencrypt renew

這邊會有輸出結果,因為安全憑證是剛剛建立的,所以不會更新,不過可以確認這個指令是可行的

Processing /etc/letsencrypt/renewal/example.com.conf
 
The following certs are not due for renewal yet:
  /etc/letsencrypt/live/example.com/fullchain.pem (skipped)
No renewals were attempted.

接下來我們就要讓這個指令自己執行,這樣就不會每三個月一直收到 letsencrypt 提醒信件
這邊我們用了 Linux 下的一個排程系統,可以讓更新動作固定一段時間自動執行。更新有兩件事情,一件事是更新憑證,另外一件事是通知網頁服務軟體憑證已經跟新,請來拿新版的憑證。也就是要重新加載nginx。

vi /etc/crontab

在最下面添加兩行,第一個參數是分鐘,第二個參數是時鐘。

30 2 * * 7 root /usr/bin/letsencrypt renew >> /var/log/le-renew.log
35 2 * * 7 root /bin/systemctl reload nginx

上方的寫法是在每個禮拜天的晚上2點30分,嘗試更新憑證,然後再35分的時候起重新加載nginx。
到這邊整個 HTTPS 已經設定完成。