跳到主內容

Nginx 模組擴充 - Debian \ Ubuntu

  BUBU 看到 CentOS 的維護週期出現重大變動,為了讓服務能繼續穩定運行,決定改用其他系統,目前採用較普及的 Debian 與 Ubuntu。兩者的指令大致相同,主要差異在套件名稱,因此本篇依此改寫。內容包含:安裝 Nginx 官方套件、自行編譯加入 Brotli 與 HTTP/3、設定 TLS,以及用 testssl 驗證結果。

運行環境


  • 系統環境:Debian 或 Ubuntu(支援的發行版本以 Nginx 官方套件頁面 為準)
  • Web 服務:Nginx(先安裝官方 stable 或 mainline 套件,再用自行編譯的執行檔替換)
  • 加密函式庫:OpenSSL 3.5 LTS(編譯時隨 Nginx 一併編入)

前置需求


  • 具備 root 或 sudo 權限,且主機可連線至 nginx.org 與 github.com
  • 若要啟用 HTTP/3,防火牆需開放 UDP 443(HTTP/3 走 UDP)
  • 啟用 HTTP/3 的前提是 TLS 必須支援 1.3

安裝或測試過程


流程一:安裝 Nginx 官方套件(deb)

  先從 Nginx 官方 的 deb 套件庫安裝目前的版次,之後再用自行編譯的執行檔替換。

  • 安裝必要套件(Debian)
sudo apt update
sudo apt install -y curl gnupg2 ca-certificates lsb-release debian-archive-keyring
  • 安裝必要套件(Ubuntu)
sudo apt update
sudo apt install -y curl gnupg2 ca-certificates lsb-release ubuntu-keyring
  • 匯入官方簽章金鑰,用來確認套件來源可信(Debian、Ubuntu 相同)
curl -fsSL https://nginx.org/keys/nginx_signing.key | gpg --dearmor \
    | sudo tee /usr/share/keyrings/nginx-archive-keyring.gpg >/dev/null
  • 驗證金鑰是否正確(Debian、Ubuntu 相同)
gpg --dry-run --quiet --no-keyring --import --import-options import-show /usr/share/keyrings/nginx-archive-keyring.gpg

  正確的輸出會包含下列三組金鑰,請核對指紋是否一致;若指紋不符,請刪除該 keyring 檔並停止後續步驟。

pub   rsa4096 2024-05-29 [SC]
      8540A6F18833A80E9C1653A42FD21310B49F6B46
uid                      nginx signing key <[email protected]>

pub   rsa2048 2011-08-19 [SC] [expires: 2027-05-24]
      573BFD6B3D8FBC641079A6ABABF5BD827BD9BF62
uid                      nginx signing key <[email protected]>

pub   rsa4096 2024-05-29 [SC]
      9E9BE90EACBCDE69FE9B204CBCDCD8A38D88A2B3
uid                      nginx signing key <[email protected]>

Nginx 官方頁面的範例只列出 573BFD6B... 這一組,但實際的金鑰檔內含上面三組,輸出三組屬正常。若出現 gpg: Fatal 錯誤,請見「疑難排解」。

  • 新增 Nginx 套件庫:stable(穩定版)與 mainline(主線版)二選一即可。兩組指令都寫入同一個檔案,後執行的會覆蓋先執行的,請依需求擇一執行。

    Debian,穩定版 stable

    echo "deb [signed-by=/usr/share/keyrings/nginx-archive-keyring.gpg] \
    https://nginx.org/packages/debian $(lsb_release -cs) nginx" \
        | sudo tee /etc/apt/sources.list.d/nginx.list
    

    Debian,主線版 mainline

    echo "deb [signed-by=/usr/share/keyrings/nginx-archive-keyring.gpg] \
    https://nginx.org/packages/mainline/debian $(lsb_release -cs) nginx" \
        | sudo tee /etc/apt/sources.list.d/nginx.list
    

    Ubuntu,穩定版 stable

    echo "deb [signed-by=/usr/share/keyrings/nginx-archive-keyring.gpg] \
    https://nginx.org/packages/ubuntu $(lsb_release -cs) nginx" \
        | sudo tee /etc/apt/sources.list.d/nginx.list
    

    Ubuntu,主線版 mainline

    echo "deb [signed-by=/usr/share/keyrings/nginx-archive-keyring.gpg] \
    https://nginx.org/packages/mainline/ubuntu $(lsb_release -cs) nginx" \
        | sudo tee /etc/apt/sources.list.d/nginx.list
    
  • 設定套件庫優先順序,讓 apt 優先採用 Nginx 官方的套件,而不是發行版內建的版本(Debian、Ubuntu 相同)

echo -e "Package: *\nPin: origin nginx.org\nPin: release o=nginx\nPin-Priority: 900\n" \
    | sudo tee /etc/apt/preferences.d/99nginx
  • 安裝 Nginx,並設定開機自動啟動(Debian、Ubuntu 相同)
sudo apt update && sudo apt install -y nginx
sudo systemctl enable --now nginx

# 確認目前安裝的版次,後面編譯時會用到
nginx -v
流程二:安裝編譯所需套件

  編譯 Nginx 需要下列依賴套件,請先安裝(Debian、Ubuntu 相同)。

sudo apt install -y git wget libpcre2-dev libpcre3 libpcre3-dev zlib1g zlib1g-dev openssl libssl-dev build-essential gcc cmake curl unzip dpkg-dev libexpat-dev libgd-dev libgeoip-dev libhiredis-dev libluajit-5.1-dev libmaxminddb-dev libmhash-dev libpam0g-dev libperl-dev libxslt1-dev ninja-build mercurial libunwind-dev pkg-config libxml2-dev
流程三:下載 ngx_brotli 並建置 Brotli 函式庫

  ngx_brotli 是 Brotli 的 Nginx 模組,原始碼請從 ngx_brotli 的 GitHub 專案 下載。下載後必須先把它內附的 Brotli 建置完成,否則之後編譯 Nginx 時會因缺少檔案而失敗(見「疑難排解」)。

  • 下載原始碼,並建置 Brotli 靜態函式庫
cd ~
git clone https://github.com/google/ngx_brotli.git
cd ngx_brotli
git submodule update --init --recursive

# 建置 Brotli(需要先安裝 cmake)
cmake -S deps/brotli -B deps/brotli/out \
  -DCMAKE_BUILD_TYPE=Release -DBUILD_SHARED_LIBS=OFF
cmake --build deps/brotli/out --config Release --target brotlienc -j"$(nproc)"

# 確認靜態函式庫已經產生
ls -l deps/brotli/out/libbrotlienc.a deps/brotli/out/libbrotlicommon.a
流程四:下載 Nginx 與 OpenSSL 原始碼

  OpenSSL 請到 OpenSSL 官方下載頁 取得正式釋出的版本,不要用 git clone 取得,因為那會是開發中的版本。

2026.10.26 查證:OpenSSL 3.5 為 LTS(長期支援)分支,最新版次為 3.5.9。實際版次請以 OpenSSL 官方下載頁為準。

  • 下載 Nginx 原始碼,並切換到與目前已安裝套件相同的版次
cd ~
git clone https://github.com/nginx/nginx.git
cd nginx

# 取出目前已安裝的版次(例:1.30.6),切換到對應的 release 標籤
git checkout "release-$(nginx -v 2>&1 | sed 's|.*/||')"
  • 下載 OpenSSL 正式版原始碼,解壓後改名為 openssl
cd ~

# 版次請依官方最新的 3.5.x 調整
OPENSSL_VER=3.5.9
wget https://github.com/openssl/openssl/releases/download/openssl-${OPENSSL_VER}/openssl-${OPENSSL_VER}.tar.gz
tar -zxvf openssl-${OPENSSL_VER}.tar.gz
mv openssl-${OPENSSL_VER} openssl

  完成後,家目錄下應有 nginx、openssl、ngx_brotli 三個目錄,下一步的編譯參數是以 ../openssl/ 與 ../ngx_brotli/ 相對路徑引用它們。

流程五:編譯並替換執行檔

  進入 nginx 目錄,在官方的編譯參數後面加上我們要的模組。其中 --with-openssl=../openssl/ --with-openssl-opt=enable-tls1_3 啟用 TLSv1.3,--add-module=../ngx_brotli/ 加入 Brotli。下面兩組編譯參數二選一:不需要 HTTP/3 就用第一組;需要 HTTP/3 就用第二組(比第一組多一個 --with-http_v3_module)。

  • 加在官方編譯參數後面,簡單修改編譯參數(不含 HTTP/3)
cd ~/nginx
auto/configure \
  --prefix=/etc/nginx \
  --sbin-path=/usr/sbin/nginx \
  --modules-path=/etc/nginx/modules \
  --conf-path=/etc/nginx/nginx.conf \
  --error-log-path=/var/log/nginx/error.log \
  --http-log-path=/var/log/nginx/access.log \
  --pid-path=/var/run/nginx.pid \
  --lock-path=/var/run/nginx.lock \
  --http-client-body-temp-path=/var/cache/nginx/client_temp \
  --http-proxy-temp-path=/var/cache/nginx/proxy_temp \
  --http-fastcgi-temp-path=/var/cache/nginx/fastcgi_temp \
  --http-uwsgi-temp-path=/var/cache/nginx/uwsgi_temp \
  --http-scgi-temp-path=/var/cache/nginx/scgi_temp \
  --user=nginx --group=nginx \
  --with-compat --with-file-aio --with-threads \
  --with-http_addition_module --with-http_auth_request_module \
  --with-http_dav_module --with-http_flv_module \
  --with-http_gunzip_module --with-http_gzip_static_module \
  --with-http_mp4_module --with-http_random_index_module \
  --with-http_realip_module --with-http_secure_link_module \
  --with-http_slice_module --with-http_ssl_module \
  --with-http_stub_status_module --with-http_sub_module \
  --with-http_v2_module \
  --with-mail --with-mail_ssl_module \
  --with-stream --with-stream_realip_module \
  --with-stream_ssl_module --with-stream_ssl_preread_module \
  --with-cc-opt='-O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector-strong --param=ssp-buffer-size=4 -grecord-gcc-switches -m64 -mtune=generic -fPIC' \
  --with-ld-opt='-Wl,-z,relro -Wl,-z,now -pie' \
  --with-openssl=../openssl/ --with-openssl-opt=enable-tls1_3 \
  --add-module=../ngx_brotli/

2024.07.03 支援 HTTP/3 服務:Nginx 從 1.25 起已支援 HTTP/3,下面的編譯參數有加入 HTTP/3 支援。若要使用 HTTP/3,需在防火牆新增 UDP 443,因為 HTTP/3 走 UDP。

  • 新增加 HTTP/3 參數(需要 HTTP/3 時使用這一組)
cd ~/nginx
auto/configure \
  --prefix=/etc/nginx \
  --sbin-path=/usr/sbin/nginx \
  --modules-path=/etc/nginx/modules \
  --conf-path=/etc/nginx/nginx.conf \
  --error-log-path=/var/log/nginx/error.log \
  --http-log-path=/var/log/nginx/access.log \
  --pid-path=/var/run/nginx.pid \
  --lock-path=/var/run/nginx.lock \
  --http-client-body-temp-path=/var/cache/nginx/client_temp \
  --http-proxy-temp-path=/var/cache/nginx/proxy_temp \
  --http-fastcgi-temp-path=/var/cache/nginx/fastcgi_temp \
  --http-uwsgi-temp-path=/var/cache/nginx/uwsgi_temp \
  --http-scgi-temp-path=/var/cache/nginx/scgi_temp \
  --user=nginx --group=nginx \
  --with-compat --with-file-aio --with-threads \
  --with-http_addition_module --with-http_auth_request_module \
  --with-http_dav_module --with-http_flv_module \
  --with-http_gunzip_module --with-http_gzip_static_module \
  --with-http_mp4_module --with-http_random_index_module \
  --with-http_realip_module --with-http_secure_link_module \
  --with-http_slice_module --with-http_ssl_module \
  --with-http_stub_status_module --with-http_sub_module \
  --with-http_v2_module \
  --with-http_v3_module \
  --with-mail --with-mail_ssl_module \
  --with-stream --with-stream_realip_module \
  --with-stream_ssl_module --with-stream_ssl_preread_module \
  --with-cc-opt='-O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector-strong --param=ssp-buffer-size=4 -grecord-gcc-switches -m64 -mtune=generic -fPIC' \
  --with-ld-opt='-Wl,-z,relro -Wl,-z,now -pie' \
  --with-openssl=../openssl/ --with-openssl-opt=enable-tls1_3 \
  --add-module=../ngx_brotli/
  • 設定完成後,開始編譯
make -j"$(nproc)"
  • 查看編譯完成的 Nginx 版次
./objs/nginx -v

# 輸出範例
nginx version: nginx/1.XX.XX
  • 備份原本安裝的官方版本,改用自行編譯的版本
# 備份官方版本,檔名中的日期會自動帶入當天
sudo mv /usr/sbin/nginx /usr/sbin/nginx.$(date +%Y%m%d).official

# 將編譯完成的版本複製到 /usr/sbin
sudo cp ./objs/nginx /usr/sbin/nginx

# 檢查設定檔並重新啟動
sudo nginx -t && sudo systemctl restart nginx

# 避免 apt 升級時,把自行編譯的版本蓋回官方版本
sudo apt-mark hold nginx

  如果替換後發生問題,可以用備份回復:

sudo mv /usr/sbin/nginx.<日期>.official /usr/sbin/nginx
sudo systemctl restart nginx
流程六:設定 TLS 與 HTTP/3

2024.03.27 調整為只啟用 TLS 1.2、TLS 1.3。2026.03.10 調整加密演算法。

  • 修改 Nginx 設定檔內的 ssl_protocols 與 ssl_ciphers,啟用 TLSv1.3
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ecdh_curve X25519:prime256v1:secp384r1;
    ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-CHACHA20-POLY1305;
    ssl_prefer_server_ciphers off;

2024.07.03 新增 HTTP/3 設定。要使用 HTTP/3,TLS 一定要支援 1.3。

  • 支援 HTTP/3 服務
    # 使用 HTTPS 與 HTTP/2
    listen 443 ssl;
    http2 on;
    http3 on;
    # 同上,IPv6 版本
    listen [::]:443 ssl;

    # 使用 UDP 提供 QUIC + HTTP/3
    listen 443 quic reuseport;
    listen [::]:443 quic reuseport;

    # 以 Alt-Svc 標頭告知客戶端本站支援 HTTP/3
    add_header Alt-Svc 'h3=":443"; ma=86400';
    add_header x-quic 'h3';
    ssl_early_data on;
    ssl_stapling on;
    ssl_stapling_verify on;
  • 檢查設定檔並重新啟動 Nginx,讓剛剛修改的設定生效
sudo nginx -t && sudo systemctl restart nginx
流程七:測試 TLSv1.3 是否生效

  使用 testssl.sh 工具測試。使用前要先安裝它依賴的套件。

  • 安裝依賴套件
sudo apt install -y dnsutils

  如果沒有安裝,會出現以下錯誤訊息:

Fatal error: Neither "dig", "host", "drill" or "nslookup" is present

  • 下載 testssl.sh
git clone --depth 1 https://github.com/testssl/testssl.sh.git
cd testssl.sh
./testssl.sh --help
  • 輸入想要測試的網域(範例以 example.com 代替)
./testssl.sh -p example.com
  • 執行結果如下

  • 想看伺服器實際選用的協定與加密套件,將小寫的 -p 改成大寫的 -P,測試結果如下

補充說明


OpenSSL 版本釋出紀錄

  下列為 OpenSSL 下載頁 的釋出紀錄,僅供查閱。1.1.1 及更早版本已不再支援,請勿用於正式環境,建議使用 LTS 分支。

  • 2019.06.15 OpenSSL 釋出新版 openssl-1.1.1c
  • 2019.09.10 OpenSSL 釋出新版 openssl-1.1.1d
  • 2020.03.31 OpenSSL 釋出新版 openssl-1.1.1f
  • 2020.04.21 OpenSSL 釋出新版 openssl-1.1.1g
  • 2020.12.08 OpenSSL 釋出新版 openssl-1.1.1i
  • 2021.05.25 OpenSSL 釋出新版 openssl-1.1.1k
  • 2022.03.15 OpenSSL 釋出新版 openssl-1.1.1n
  • 2022.05.03 OpenSSL 釋出新版 openssl-1.1.1o
  • 2022.07.05 OpenSSL 釋出新版 openssl-1.1.1q
  • 2022.07.05 OpenSSL 釋出新版 openssl-3.0.5
  • 2022.11.01 OpenSSL 釋出新版 openssl-3.0.7
  • 2023.03.14 OpenSSL 釋出新版 openssl-3.1.0
  • 2023.05.30 OpenSSL 釋出新版 openssl-3.1.1
  • 2023.08.01 OpenSSL 釋出新版 openssl-3.1.2
  • 2023.10.27 OpenSSL 釋出新版 openssl-3.1.4
  • 2024.01.30 OpenSSL 釋出新版 openssl-3.2.1
  • 2024.06.06 OpenSSL 釋出新版 openssl-3.2.2
  • 2024.06.06 OpenSSL 釋出新版 openssl-3.3.1
  • 2024.09.03 OpenSSL 釋出新版 openssl-3.3.2
  • 2025.09.30 OpenSSL 釋出長期支援版 LTS openssl-3.5.4
  • 2026.01.27 OpenSSL 釋出長期支援版 LTS openssl-3.5.5
  • 2026.06.09 OpenSSL 釋出長期支援版 LTS openssl-3.5.7
  • 2026.09.29 OpenSSL 釋出長期支援版 LTS openssl-3.5.9

疑難排解


  • 錯誤訊息: gpg: Fatal: /root/.gnupg: directory does not exist! 解決方式: 在驗證金鑰時,若 gpg 的設定目錄不存在就會出現此錯誤。先建立目錄再重新執行驗證指令:mkdir -p ~/.gnupg && chmod 700 ~/.gnupg

  • 錯誤訊息: 編譯 Nginx 時,因為 brotli 缺少檔案而失敗(2026.10.26 遇到,錯誤畫面如下) 解決方式: 原因是 ngx_brotli 內附的 brotli 尚未先建置。請回到「流程三」完成 Brotli 的建置,確認 libbrotlienc.a、libbrotlicommon.a 已經產生,再回到 nginx 目錄重新執行 make -j"$(nproc)"。

備註


  • 更新 Nginx 簽章金鑰:重新執行流程一的「匯入官方簽章金鑰」指令覆蓋原檔,再執行 sudo apt update 即可。
  • 舊文章常見的 apt-key add、apt-key del 已不建議使用,本篇一律以 signed-by 指定 keyring 檔的方式處理。

版本紀錄


  • 2022.08.14:OpenSSL 改用 3.0 版本,往後記錄以 3.0 或更高版本為主
  • 2024.03.27:調整為只啟用 TLS 1.2、TLS 1.3
  • 2024.07.03:新增 HTTP/3 編譯參數與設定
  • 2026.03.10:調整加密演算法
  • 2026.10.26:補充 Brotli 建置步驟;修正 OpenSSL 下載指令;改用 https 套件庫;新增套件庫優先順序設定;整併 Debian/Ubuntu 重複步驟;核對參考連結並移除已失效者;潤稿

參考相關網頁