NGINX 設定 HTTPS 網頁加密連線,建立自行簽署的 SSL 憑證

STEP 1
在設定之前,請先確認自己的 NGINX 伺服器已經安裝好了,基本的安裝設定可以參考 Ubuntu Linux 安裝與設定 LEMP 網頁伺服器步驟教學

STEP 2
建立一個放置憑證的目錄,目錄的路徑可以自由選擇,放在哪裡都可以,而考量到這個憑證是 NGINX 專用的,所以跟 NGINX 的設定檔放在一起可能會比較好管理。

cd /etc/ssl

STEP 3
使用 openssl 產生自行簽署的 SSL 憑證,並且將憑證的存放路徑設成剛剛上面建立的目錄:

openssl req -new -newkey rsa:2048 -nodes -keyout name.key -out name.csr

以下是這裡使用到的參數與簡略說明:

  • req:使用 X.509 Certificate Signing Request(CSR) Management 產生憑證。
  • -x509:建立自行簽署的憑證。
  • -nodes:不要使用密碼保護,因為這個憑證是 NGINX 伺服器要使用的,如果設定密碼的話,會讓伺服器每次在啟動時書需要輸入密碼。
  • -days 365:設定憑證的使用期限,單位是天,如果不想時常重新產生憑證,可以設長一點。
  • -newkey rsa:2048:同時產生新的 RSA 2048 位元的金鑰。
  • -keyout:設定金鑰儲存的位置。
  • -out:設定憑證儲存的位置。

這裡我們會同時建立憑證與金鑰,建立的過程中會需要填寫一些基本的資料:

Country Name (2 letter code) [AU]:HK
State or Province Name (full name) [Some-State]:Hong Kong
Locality Name (eg, city) []:Hong Kong
Organization Name (eg, company) [Internet Widgits Pty Ltd]:Easco Ltd
Organizational Unit Name (eg, section) []:Online
Common Name (e.g. server FQDN or YOUR name) []:*.ewholesale.com.hk
Email Address []:joe.chan@easco.com.hk

1 國家代碼,台灣就填 TW

2 州或省,台灣就填 Taiwan

3 城市,例如台北就填 Taipei

4 公司名稱。

5 部門名稱。

6 伺服器的 FQDN,這個一定要填寫正確,如果沒有申請網域名稱的話,也可以用 IP 位址替代。

7 E-mail 信箱。

填寫完成之後,憑證與金鑰的建立就完成了,而存放位置就在 /etc/nginx/ssl 目錄中。

STEP 4
設定 NGINX 伺服器,在原本的設定檔中加上 SSL 的設定,並且設定憑證與金鑰的路徑:

server {
  listen 80 default_server;
  listen [::]:80 default_server;

  # 加入 SSL 設定
  listen 443 ssl default_server;
  listen [::]:443 ssl default_server;

  # 憑證與金鑰的路徑
  ssl_certificate /etc/nginx/ssl/nginx.crt;
  ssl_certificate_key /etc/nginx/ssl/nginx.key;

  # ...
}

STEP 5
接著重新啟動 NGINX 伺服器:

sudo service nginx restart

STEP 6
開啟 HTTPS 的網址,正常來說瀏覽器會有憑證授權不可靠的警告,而如果憑證的 FQDN 跟伺服器的 FQDN 沒有符合的話,也會出現網址不符的警告:
網址不符的警告只要修改伺服器的網址或是重新產生一張符合網址的憑證就可以解決,而憑證授權的問題是由於我們使用的憑證是自行簽署的,所以這個憑證授權的警告是一定會出現的。

STEP 7
如果希望所有的使用者都使用加密的 HTTPS 連線,不要使用沒有加密的 HTTP 的話,可以修改一下 NGINX 的設定,讓所有的 HTTP 的網址自動導向至 HTTPS 的網址:

server {
  listen 80 default_server;
  listen [::]:80 default_server;

  # 導向至 HTTPS
  rewrite ^(.*) https://$host$1 permanent;
}
server {
  # SSL 設定
  listen 443 ssl default_server;
  listen [::]:443 ssl default_server;

  # 憑證與金鑰的路徑
  ssl_certificate /etc/nginx/ssl/nginx.crt;
  ssl_certificate_key /etc/nginx/ssl/nginx.key;

  # ...
}

這樣就算使用者輸入的是 HTTP 這種未加密的網址,也會自動導向至對應的 HTTPS 網址,確保所有的網頁資料都一定會經過 HTTPS 來傳輸,降低資料被竊取的風險。