這篇文章會以 nginx 架在 Digital Ocean 上的 Ubuntu 14.04.4 LTS 為範例,講解如何使用 Let’s Encrypt 套件裝上免費的 SSL 憑證,參考自 Digital Ocean 的教學。

這篇文章包括:
第一步:建立基本 Server
在看這篇文章之前,必須要先有個域名 (Domain Name),可以在 Godaddy 購買三十元台幣一年的便宜域名。也要有一台主機,這邊是用 Digital Ocean 的機器,如果你是學生,那 Github 有送你 1500 元免費額度。
在架 HTTPS Server 前,先把一般 HTTP Server 架起來。基本 nginx 設定如下,以下範例以 example.com 作為域名,複製貼上時記得更改成自己的。
server { listen 80; server_name example.com www.example.com; location ~ / { proxy_pass http://127.0.0.1:good-port; } }
|
上面程式會把 example.com
進來的請求導向至 http://127.0.0.1:good-port
架設的伺服器。如果不能了解以上程式碼,可以參考 Nginx 教學。
第二步:安裝 Let’s Encrypt
更新套件清單
安裝相關套件
sudo apt-get -y install git bc
|
下載 letsencrypt 套件至 /opt/letsencrypt
sudo git clone https://github.com/letsencrypt/letsencrypt /opt/letsencrypt
|
第三步:安裝憑證
這邊會用到 Webroot plugin 來安裝憑證,而 Webroot plugin 會去找伺服器的 /.well-known
這個目錄,所以要在 nginx config 加入
location ~ /.well-known { allow all; }
|
現在 /etc/nginx/site-available/default
應該變成
server { listen 80; server_name example.com www.example.com; location ~ / { proxy_pass http://127.0.0.1:good-port; } location ~ /.well-known { allow all; } }
|
更改設定完讓 nginx 重新載入
sudo service nginx reload
|
現在就可以用 Let’s Encrypt 的 webroot 插件來安裝憑證了
cd /opt/letsencrypt sudo ./letsencrypt-auto certonly -a webroot --webroot-path=/your/website/root -d example.com -d www.example.com
|
其中 webroot-path 要設定伺服器公開路徑下的根目錄,Let’s Encrypt 會在目錄下產生 .well-known
這個資料夾。
如果是安裝遇到 cryptography
錯誤,可以參考 cryptography 錯誤排解。
如果步驟中有要輸入信箱的地方,可以輸入常用信箱,Let’s Encrypt 會在憑證快要到期前寄信通知。目前憑證期限是三個月,不過 Let’s Encrypt 也可以利用 crontab
自動續約,文末會講到。
如果成功了,就可以看到:
IMPORTANT NOTES: - Congratulations! Your certificate and chain have been saved at /etc/letsencrypt/live/example.com/fullchain.pem. Your cert will expire on XXXX-XX-XX. To obtain a new version of the certificate in the future, simply run Let's Encrypt again. - If you 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
|
如此憑證就申請好了,接下來為了安全性考量,可以來產生一把 Diffie-Hellman 密鑰,產生密鑰可能會花上一段時間。
sudo openssl dhparam -out /etc/ssl/certs/dhparam.pem 2048
|
第四步:更新 Nginx Server 設定
現在要把原本的 HTTP 改成 HTTPS,所以把原本的 80 port 設定改成 443,並加上 SSL 憑證的設定
listen 443 ssl; server_name example.com www.example.com; ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
|
為了讓 SSL 更安全,加上剛剛產生的 Diffie-Hellman 密鑰
ssl_protocols TLSv1 TLSv1.1 TLSv1.2; ssl_prefer_server_ciphers on; ssl_dhparam /etc/ssl/certs/dhparam.pem; 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:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:CAMELLIA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA'; ssl_session_timeout 1d; ssl_session_cache shared:SSL:50m; ssl_stapling on; ssl_stapling_verify on; add_header Strict-Transport-Security max-age=15768000;
|
現在 /etc/nginx/site-available/default
應該會長得像這樣
server { listen 443 ssl; server_name example.com www.example.com; ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem; ssl_protocols TLSv1 TLSv1.1 TLSv1.2; ssl_prefer_server_ciphers on; ssl_dhparam /etc/ssl/certs/dhparam.pem; 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:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:CAMELLIA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA'; ssl_session_timeout 1d; ssl_session_cache shared:SSL:50m; ssl_stapling on; ssl_stapling_verify on; add_header Strict-Transport-Security max-age=15768000; location ~ / { proxy_pass http://127.0.0.1:good-port; } location ~ /.well-known { allow all; } }
|
這樣 HTTPS 伺服器的設定就完成了,不過為了讓原本連上 HTTP 的使用者可以自動轉向 HTTPS,可以加上
server { listen 80; server_name example.com www.example.com; return 301 https://$host$request_uri; }
|
更改設定完讓 Nginx 重新載入
sudo service nginx reload
|
做到這一步,就可以成功看到網站前面多出來的 HTTPS 啦!

可以看看網站的 SSL 測試,做出來應該會是 A+。

第五步:設定自動更新憑證
Let’s Encrypt 可以更新憑證,renew 會檢查當前憑證,如果快要過期就會自動續約
/opt/letsencrypt/letsencrypt-auto renew
|
所以只要把自動更新設定在 crontab 裡就好了
Let’s Encrypt 是三個月過期,可以設定每週一早上 2:30 檢查憑證,2:35 重啟 nginx server,這樣就不怕憑證過期了
編輯 crontab,設定排程
30 2 * * 1 /opt/letsencrypt/letsencrypt-auto renew >> /var/log/le-renew.log 35 2 * * 1 /etc/init.d/nginx reload
|
若是遇到問題還是有其他指教,都歡迎留言。