架設Nginx網頁伺服器與申請Let’s Encrypt的TLS/SSL憑證

nginx and let's encrypt

Nginx(發音為Engine-X)是一款開放原始碼的軟體,屬於非同步框架的網頁伺服器。它以低資源、高性能和高度模組化設計著稱,同時具有反向代理、負載平衡和HTTP快取等功能。Nginx是由俄羅斯程式設計師Igor Sysoev於2004年開發,後來在2011年成立同名公司,提供相對應的支援服務。

我安裝Nginx的主要目的是拿來當做各種服務的反向代理伺服器,並申請一個TLS/SSL憑證(以下簡稱憑證)掛在Nginx上,讓所有服務都可以使用這個單一憑證。在架設Nginx之前,我的Home Assistant透過內建的duckdns附加元件去申請duckdns的免費域名和由Let’s Encrypt頒發的憑證,Synology DSM則是用他們自家的免費域名synology.me以及自我簽署憑證,WireGuard則借用了duckdns做轉址,而Unifi Controller雖然強制使用HTTPS連線但卻沒有對應的憑證,所以每次連線都會跳出隱私權錯誤的訊息,整體上就有亂七八糟的感覺。

隱私權錯誤的訊息

趁著這次架設WordPress,網誌重新開張的同時順便打掉重練,申請了一個新的域名tzungshiun.com、掛上Nginx做各項服務的反向代理並向Let’s Encrypt申請憑證,利用Certbot做憑證的自動更新,這樣從WAN進來的連線都是加密的HTTPS連線,LAN裝置之間互相連線走HTTP即可,降低各項服務用於解密的資源。

反向代理(reverse proxy)

反向代理是一種伺服器架構,它充當客戶端與內部伺服器(通常是網站、應用程式或資源)之間的中繼站。當客戶端向伺服器發送請求時,這個請求不直接被送達給內部伺服器,而是先被發送到反向代理伺服器。

反向代理伺服器根據特定的規則和配置,將客戶端的請求轉發給適當的內部伺服器,然後將內部伺服器的回應再回傳給客戶端。在這個過程中,客戶端不會直接與內部伺服器連線,因此內部伺服器的資源和位置對客戶端來說是看不到的,比起客戶端與內部伺服器直接連線有更高的安全性。

安裝Nginx套件並確認可以正常運作

因為Nginx是長期運作的服務,所以我選擇用套件管理器安裝在Debian 12上

$ sudo apt update
$ sudo apt install nginx

安裝完利用systemctl確認一下Nginx的狀態

$ sudo systemctl status nginx

若Loaded為loaded且Active為active (running)表示Nginx已經在運作中

● nginx.service - A high performance web server and a reverse proxy server
     Loaded: loaded (/lib/systemd/system/nginx.service; enabled; preset: enabled)
     Active: active (running) since Tue 2024-01-02 22:32:01 CST; 11s ago
       Docs: man:nginx(8)
    Process: 3605 ExecStartPre=/usr/sbin/nginx -t -q -g daemon on; master_process on; (code=exited, status=0/SUCCESS)
    Process: 3606 ExecStart=/usr/sbin/nginx -g daemon on; master_process on; (code=exited, status=0/SUCCESS)
   Main PID: 3638 (nginx)
      Tasks: 9 (limit: 37986)
     Memory: 6.2M
        CPU: 58ms
     CGroup: /system.slice/nginx.service
             ├─3638 "nginx: master process /usr/sbin/nginx -g daemon on; master_process on;"
             ├─3640 "nginx: worker process"
             ├─3641 "nginx: worker process"
             ├─3642 "nginx: worker process"
             ├─3643 "nginx: worker process"
             ├─3644 "nginx: worker process"
             ├─3645 "nginx: worker process"
             ├─3646 "nginx: worker process"
             └─3647 "nginx: worker process"

打開瀏覽器並輸入Nginx伺服器的IP,可以看到Nginx的歡迎畫面。

Nginx歡迎畫面

建立Nginx的server blocks

在/etc/nginx/sites-available/下新增一個檔案,通常用網域命名,比如說tzungshiun.com

$ sudo nano /etc/nginx/sites-available/tzungshiun.com

先給個基本設定就好,並將server_name要改成要用的域名

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

        server_name tzungshiun.com www.tzungshiun.com;
}

做一個symbolic link到sites-enabled資料夾底下,Nginx啟動時會讀取sites-enabled下的server block

$ sudo ln -s /etc/nginx/sites-available/tzungshiun.com /etc/nginx/sites-enabled/

若檢查/etc/nginx/sites-enabled/路徑下會有二個server block,一個是剛建立的tzungshiun.com,另一個則是default,其中default會負責處理不符合其他server blocks的HTTP連線。

再來為了避免hash bucket memory的問題,我們需要修改/etc/nginx/nginx.conf的部分內容

$ sudo nano /etc/nginx/nginx.conf

找到http區塊下的# server_names_hash_bucket_size 64;並將前面的#移除後存檔

http {

        ##
        # Basic Settings
        ##

        sendfile on;
        tcp_nopush on;
        types_hash_max_size 2048;
        # server_tokens off;

        server_names_hash_bucket_size 64;
        # server_name_in_redirect off;
        .....
}

檢查Nginx設定是否正確可以用下面指令檢查

$ sudo nginx -t

若出現下面的訊息表示設定沒有問題,可以重新啟動

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

重新啟動Nginx讓設定生效

$ sudo systemctl restart nginx

安裝Let’s Encrypt憑證

以前如果需要SSL/TLS憑證是需要付費購買的,到了2014年9月,由Internet Security Research Group(ISRG)創辦的非營利性組織Let’s Encrypt成立了,其目標是推動更安全的網際網路,提供免費的SSL/TLS憑證,從而促進網絡安全和隱私保護。

安全通訊端層

安全通訊端層(SSL/Secure Sockets Layer)是一種加密技術,在使用網際網路時可以更安全地傳輸資訊。它確保在瀏覽器和網站伺服器之間的資料傳輸是加密的,防止第三方對資料的竊聽或修改。SSL通常用於保護個人資料、信用卡交易、登入資訊等敏感資訊的傳輸,當你在瀏覽器中看到網址開頭是https://而不是http://時,就表示該網站正在使用SSL加密連線,提供更安全的瀏覽環境。

傳輸層安全性

傳輸層安全性(TLS/Transport Layer Security)是SSL的後續版本,兩者通常被混用,但TLS已成為SSL的主要後續發展版本。TLS協議的第一個版本於 1999 年發佈,最新版本是 TLS 1.3,發佈於 2018 年。

Let’s Encrypt通過提供自動化的流程,讓網站管理員可以輕鬆地實現HTTPS加密連線,HTTPS能夠確保用戶與網站之間的通信是加密的,以提高了數據傳輸的安全性和隱私保護。通常,Let’s Encrypt的憑證有效期為90天,但由於其自動化的特性,可以通過工具(例如Certbot)輕鬆地自動更新憑證,使網站持續保持加密連接。

安裝Certbot與Certbox Nginx插件

$ sudo apt install certbot python3-certbot-nginx

為網域取得憑證,這裡的網域要和Nginx server block的名稱相同,這樣Nginx插件才能改寫設定

$ sudo certbot --nginx -d tzungshiun.com -d www.tzungshiun.com

會要求填入E-mail

Saving debug log to /var/log/letsencrypt/letsencrypt.log
Enter email address (used for urgent renewal and security notices)
 (Enter 'c' to cancel): 

詢問是否同意服務協議

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Please read the Terms of Service at
https://letsencrypt.org/documents/LE-SA-v1.3-September-21-2022.pdf. You must
agree in order to register with the ACME server. Do you agree?
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
(Y)es/(N)o:

詢問是否同意在取得憑證後將E-mail分享給EFF,EFF是Let’s Encrypt計劃的創始合作夥伴,同時也是發展Certbot的非營利組織。

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Would you be willing, once your first certificate is successfully issued, to
share your email address with the Electronic Frontier Foundation, a founding
partner of the Let's Encrypt project and the non-profit organization that
develops Certbot? We'd like to send you email about our work encrypting the web,
EFF news, campaigns, and ways to support digital freedom.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
(Y)es/(N)o:

若成功的話會出現

Saving debug log to /var/log/letsencrypt/letsencrypt.log
Requesting a certificate for tzungshiun.com

Successfully received certificate.
Certificate is saved at: /etc/letsencrypt/live/tzungshiun.com/fullchain.pem
Key is saved at:         /etc/letsencrypt/live/tzungshiun.com/privkey.pem
This certificate expires on 2024-04-01.
These files will be updated when the certificate renews.
Certbot has set up a scheduled task to automatically renew this certificate in the background.

Deploying certificate
Successfully deployed certificate for tzungshiun.com to /etc/nginx/sites-enabled/tzungshiun.com
Congratulations! You have successfully enabled HTTPS on https://tzungshiun.com

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
If you like Certbot, please consider supporting our work by:
 * Donating to ISRG / Let's Encrypt:   https://letsencrypt.org/donate
 * Donating to EFF:                    https://eff.org/donate-le
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

成功之後Certbot會自動幫你改寫server block的檔案內容

server {

        server_name tzungshiun.com www.tzungshiun.com;

    listen [::]:443 ssl ipv6only=on; # managed by Certbot
    listen 443 ssl; # managed by Certbot
    ssl_certificate /etc/letsencrypt/live/tzungshiun.com/fullchain.pem; # managed by Certbot
    ssl_certificate_key /etc/letsencrypt/live/tzungshiun.com/privkey.pem; # managed by Certbot
    include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot

}
server {
    if ($host = tzungshiun.com) {
        return 301 https://$host$request_uri;
    } # managed by Certbot


        listen 80;
        listen [::]:80;

        server_name tzungshiun.com www.tzungshiun.com;
    return 404; # managed by Certbot


}

確認憑證更新時程

利用systemctl檢查certbot.timer是否有運行

$ sudo systemctl status certbot.timer

Certbot每天會做二次憑證的有效期限檢查,若需要更新時Certbot會自行更新憑證。

● certbot.timer - Run certbot twice daily
     Loaded: loaded (/lib/systemd/system/certbot.timer; enabled; preset: enabled)
     Active: active (waiting) since Sun 2023-12-31 09:38:20 CST; 3 days ago
    Trigger: Thu 2024-01-04 09:43:54 CST; 9h left
   Triggers: ● certbot.service

Dec 31 09:38:20 debian-pc systemd[1]: Started certbot.timer - Run certbot twice daily.

如果需要測試憑證更新是否有問題,可以輸入下列指令

$ sudo certbot renew --dry-run

後記:Nginx常用的檔案與資料夾

  • /etc/nginx/ : Nginx相關設定都在這個資料夾內。
  • /etc/nginx/nginx.conf : Nginx主要的設定檔,屬於基礎且全域的設定。
  • /etc/nginx/sites-available/ : 儲存「可能會使用到」的server blocks的相關設定,這裡可以有多個設定檔案,每個檔案代表一個server blocks的配置,Nginx啟動時不會讀取這個資料夾內的檔案。
  • /etc/nginx/sites-enabled/ : 儲存「實際使用」的server blocks的相關設定,Nginx在啟動時會讀取這個資料夾的內容,只有在這個目錄下的配置檔才會被 Nginx 實際載入和使用。。

這樣的架構可以讓你在/etc/nginx/sites-available/目錄中管理所有可能的server blocks設定,當需要啟用或停用特定的server blocks時,只需處理二個資料夾之間的symbolic link即可,不需要修改或刪除原始配置檔案。這種設計使得管理多個server blocks變得更加靈活和容易。

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *

返回頂端