本篇文章簡介 Let’s Encrypt 這個「證書頒發機構」(Certificate authority, CA),並使用他和 Nginx 架設 HTTPS 伺服器。

參考申請Let’s Encrypt 憑證與啟用 https (Nginx) 官方文獻

Let’s Encrypt 介紹

Let’s Encrypt 提供哪些服務

Let’s Encrypt 是一家全球性的憑證頒發機構 (Certificate Authority, CA)
Let’s Encrypt 提供域名驗證型憑證 (Domain Validation, DV)

如何設定 https 的流程

流程分為兩個步驟:

  1. 管理軟體會先向 CA 證明伺服器擁有網域的所有權。
  2. 管理系統就可以替該網域申請、更新或註銷憑證。

證明網域的所有權

憑證管理軟體: 自己的伺服器上的軟體

憑證管理軟體首次向 Let’s Encrypt 溝通

  • 產生一組公私金鑰
  • 向 CA 證明自己管理一或多個網域

Let’s Encrypt CA 會考驗

  1. Let’s Encrypt 還提供了一個隨機,要求憑證管理軟體必須用它所產生的私鑰,對隨機數進行簽名

  2. CA 會檢查隨機數上的簽名,並且下載在放網頁伺服器上的文件,以確認文件內容。

憑證的頒發和註銷

憑證的頒發: 只需要發送憑證管理請求,並用授權金鑰對簽名

快速入門頁面

採用 Certbot 這個 ACME 客戶端,它可以自動執行憑證的頒發、安裝,甚至不需要停止你的伺服器。

專業術語

  • ACME (Automatic Certificate Management Environment) : 自動憑證管理環境。
  • Boulder : 由 Let’s Encrypt 開發和使用,以實作 ACME 協議的軟體。GitHub
  • CA Issuers : CA 頒發者。
  • Certificate : 憑證。一個使用 X.509 格式的文件,內容包含公鑰和如何使用這把公鑰的資訊。
  • Certificate Authority (CA) : 憑證頒發機構。Let’s Encrypt、IdenTrust、Sectigo 和 DigiCert 都是憑證頒發機構。
  • DNS-based Authentication of Named Entities (DANE) : 基於 DNS 的域名實體認證。一個網路安全協定,使用 DNS 來告訴客戶端該如何驗證憑證真偽,以及是否有提供加密公鑰。
  • ECDSA (Elliptic Curve Digital Signature Algorithm) : 橢圓曲線數位簽名演算法。
  • Ed25519 : 一種特殊類型的 EdDSA,類似還的還有 Ed448。
  • EdDSA (Edwards-curve Digital Signature Algorithm) : 現代基於橢圓曲線的公鑰簽名演算法,
  • Extended Validation (EV) : 擴展驗證。一種憑證驗證方式,CA 會驗證法律實體是否有網站的控制權。

使用 Let’s Encrypt 架設 HTTPS 伺服器 (NGINX)

安裝 nginx

1
2
sudo apt-get update
sudo apt install nginx

安裝 Certbot

1
2
3
sudo add-apt-repository ppa:certbot/certbot
sudo apt-get update
sudo apt-get install certbot

修改 Nginx 設定

1
sudo vim /etc/nginx/sites-available/default

在 server block 新增 well-known 路徑

1
2
3
4
5
6
7
8
9
server {
listen 80 default_server;
listen [::]:80 default_server;

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

驗證 Nginx 設定檔並重啟

驗證設定檔案

成功訊息: nginx: configuration file /etc/nginx/nginx.conf test is successful
失敗訊息: nginx: configuration file /etc/nginx/nginx.conf test failed

1
sudo nginx -t

驗證成功後重新啟動

1
sudo systemctl restart nginx

申請憑證

要替換成自己的網域,例如: example.com

1
sudo certbot certonly --webroot --register-unsafely-without-email --webroot-path=/var/www/html -d DOMAIN

增加安全性使用指令產生 /etc/ssl/certs/dhparam.pem

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

設定 Nginx 憑證

設定 /etc/nginx/snippets/ssl-DOMAIN.conf

要替換成自己的網域,例如: example.com

開啟檔案輸入 /etc/nginx/snippets/ssl-DOMAIN.conf 以下內容

1
sudo vim /etc/nginx/snippets/ssl-DOMAIN.conf
1
2
ssl_certificate /etc/letsencrypt/live/DOMAIN/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/DOMAIN/privkey.pem;

設定 /etc/nginx/snippets/ssl-params.conf

開啟檔案輸入 /etc/nginx/snippets/ssl-params.conf 以下內容

1
sudo vim /etc/nginx/snippets/ssl-params.conf

路徑 /etc/ssl/certs/dhparam.pem 要修改與上面對應路徑相同
resolver 設定 8.8.8.8 和 8.8.4.4 是 Google 的 DNS IP

1
2
3
4
5
6
7
8
9
10
11
12
13
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 X-Frame-Options DENY;
add_header X-Content-Type-Options nosniff;
ssl_dhparam /etc/ssl/certs/dhparam.pem;

設定 /etc/nginx/sites-available/default

設定原本的 server 區塊為

1
2
3
4
5
6
7
8
server {
listen 443 ssl http2 default_server;
listen [::]:443 ssl http2 default_server;
include snippets/ssl-domain.com.conf;
include snippets/ssl-params.conf;

...
}

在外面區塊新增一個 server 區塊

1
2
3
4
5
6
server {
listen 80 default_server;
listen [::]:80 default_server;
server_name domain.com www.domain.com;
return 301 https://$server_name$request_uri;
}

驗證 Nginx 設定檔並重啟

驗證設定檔案

成功訊息: nginx: configuration file /etc/nginx/nginx.conf test is successful
失敗訊息: nginx: configuration file /etc/nginx/nginx.conf test failed

1
sudo nginx -t

驗證成功後重新啟動

sudo systemctl restart nginx