HTTP/3 是最新一代的超文字傳輸協定,基於 QUIC 協定運作,為網站帶來更快速、更可靠的連線體驗。本文將介紹如何在 Ubuntu 22.04 上設定 Nginx 以支援 HTTP/3。
HTTP/3 與 QUIC 概述
HTTP/3 是 HTTP 協定的第三個主要版本,與前代最大的不同在於它使用 QUIC(Quick UDP Internet Connections)作為傳輸層協定,而非傳統的 TCP。
QUIC 最初由 Google 開發,後來被 IETF 標準化。它具有以下特點:
- 基於 UDP 協定運作
- 內建 TLS 1.3 加密
- 支援連線多工(Multiplexing)
- 減少連線建立的延遲時間
- 改善封包遺失時的效能表現
HTTP/3 優勢
1. 更快的連線建立
傳統的 HTTPS 連線需要經過 TCP 三次握手和 TLS 握手,共需要 2-3 個 RTT(Round-Trip Time)。HTTP/3 使用 QUIC,將這個過程縮短到 1 個 RTT,甚至在重複連線時可達到 0-RTT。
2. 解決隊頭阻塞問題
HTTP/2 雖然支援多路復用,但因為基於 TCP,當一個封包遺失時,所有串流都會被阻塞。HTTP/3 使用 QUIC,每個串流獨立處理,一個串流的封包遺失不會影響其他串流。
3. 連線遷移
QUIC 使用連線 ID 而非 IP 位址來識別連線,當使用者切換網路(如從 WiFi 切換到行動網路)時,連線可以無縫遷移,不需要重新建立。
4. 改進的壅塞控制
QUIC 實作了更先進的壅塞控制演算法,能更好地適應網路狀況的變化。
Nginx HTTP/3 支援狀態
從 Nginx 1.25.0 開始,HTTP/3 支援已進入穩定版本。在此之前,HTTP/3 功能需要使用實驗性的 nginx-quic 分支。
Ubuntu 22.04 預設的 Nginx 版本可能不支援 HTTP/3,因此我們需要從源碼編譯或使用第三方套件庫來取得支援 HTTP/3 的 Nginx 版本。
編譯支援 HTTP/3 的 Nginx
安裝編譯依賴
首先安裝必要的編譯工具和函式庫:
1
2
3
| sudo apt update
sudo apt install -y build-essential git libpcre3 libpcre3-dev zlib1g zlib1g-dev \
libssl-dev libgd-dev libgeoip-dev libxslt1-dev libperl-dev
|
安裝 BoringSSL 或 OpenSSL 3.x
HTTP/3 需要支援 QUIC 的 TLS 函式庫。推薦使用 BoringSSL:
1
2
3
4
5
6
7
8
9
10
| # 安裝 cmake 和 golang(BoringSSL 編譯需要)
sudo apt install -y cmake golang
# 下載並編譯 BoringSSL
cd /usr/local/src
sudo git clone https://github.com/google/boringssl.git
cd boringssl
sudo mkdir build && cd build
sudo cmake ..
sudo make -j$(nproc)
|
下載並編譯 Nginx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
| # 下載最新版 Nginx(1.25.0 或更新版本)
cd /usr/local/src
sudo wget https://nginx.org/download/nginx-1.25.4.tar.gz
sudo tar -xzf nginx-1.25.4.tar.gz
cd nginx-1.25.4
# 設定編譯選項
sudo ./configure \
--prefix=/etc/nginx \
--sbin-path=/usr/sbin/nginx \
--modules-path=/usr/lib64/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 \
--with-http_ssl_module \
--with-http_v2_module \
--with-http_v3_module \
--with-cc-opt="-I/usr/local/src/boringssl/include" \
--with-ld-opt="-L/usr/local/src/boringssl/build/ssl -L/usr/local/src/boringssl/build/crypto"
# 編譯並安裝
sudo make -j$(nproc)
sudo make install
|
驗證安裝
確認輸出中包含 --with-http_v3_module。
設定 HTTP/3
編輯 Nginx 設定檔以啟用 HTTP/3:
1
| sudo nano /etc/nginx/nginx.conf
|
基本 HTTP/3 設定
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
| http {
# 啟用 QUIC 和 HTTP/3 日誌
log_format quic '$remote_addr - $remote_user [$time_local] '
'"$request" $status $body_bytes_sent '
'"$http_referer" "$http_user_agent" '
'$http3';
server {
# HTTP/1.1 和 HTTP/2(TCP)
listen 443 ssl;
listen [::]:443 ssl;
# HTTP/3(QUIC over UDP)
listen 443 quic reuseport;
listen [::]:443 quic reuseport;
server_name example.com www.example.com;
# SSL 憑證設定
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
# TLS 設定
ssl_protocols TLSv1.3;
ssl_prefer_server_ciphers off;
# QUIC 設定
ssl_early_data on;
quic_retry on;
# 回應標頭:告知瀏覽器支援 HTTP/3
add_header Alt-Svc 'h3=":443"; ma=86400';
# 使用 QUIC 日誌格式
access_log /var/log/nginx/access.log quic;
root /var/www/html;
index index.html;
location / {
try_files $uri $uri/ =404;
}
}
}
|
完整的生產環境設定範例
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
| user www-data;
worker_processes auto;
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
use epoll;
multi_accept on;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
# 日誌格式
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
log_format quic '$remote_addr - $remote_user [$time_local] '
'"$request" $status $body_bytes_sent '
'"$http_referer" "$http_user_agent" '
'quic=$http3 early_data=$ssl_early_data';
# 效能優化
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 2048;
# Gzip 壓縮
gzip on;
gzip_vary on;
gzip_proxied any;
gzip_comp_level 6;
gzip_types text/plain text/css text/xml application/json application/javascript
application/rss+xml application/atom+xml image/svg+xml;
# HTTP 重導向至 HTTPS
server {
listen 80;
listen [::]:80;
server_name example.com www.example.com;
return 301 https://$server_name$request_uri;
}
# HTTPS + HTTP/3 設定
server {
listen 443 ssl;
listen [::]:443 ssl;
listen 443 quic reuseport;
listen [::]:443 quic reuseport;
server_name example.com www.example.com;
# SSL 憑證
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
ssl_trusted_certificate /etc/letsencrypt/live/example.com/chain.pem;
# TLS 設定
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384;
ssl_prefer_server_ciphers off;
ssl_session_timeout 1d;
ssl_session_cache shared:SSL:50m;
ssl_session_tickets off;
# OCSP Stapling
ssl_stapling on;
ssl_stapling_verify on;
resolver 8.8.8.8 8.8.4.4 valid=300s;
resolver_timeout 5s;
# HTTP/3 和 QUIC 設定
ssl_early_data on;
quic_retry on;
quic_gso on;
# Alt-Svc 標頭
add_header Alt-Svc 'h3=":443"; ma=86400' always;
# 安全標頭
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-XSS-Protection "1; mode=block" always;
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
access_log /var/log/nginx/access.log quic;
error_log /var/log/nginx/error.log;
root /var/www/html;
index index.html index.htm;
location / {
try_files $uri $uri/ =404;
}
}
}
|
Alt-Svc 標頭
Alt-Svc(Alternative Services)標頭是告知瀏覽器伺服器支援 HTTP/3 的關鍵機制。
1
| add_header Alt-Svc 'h3=":443"; ma=86400' always;
|
參數說明:
h3=":443":表示在連接埠 443 上提供 HTTP/3 服務ma=86400:max-age,快取時間為 86400 秒(24 小時)always:確保此標頭在所有回應中都會發送
瀏覽器首次訪問時會使用 HTTP/1.1 或 HTTP/2,收到 Alt-Svc 標頭後,後續請求會嘗試使用 HTTP/3。
防火牆設定(UDP 443)
HTTP/3 使用 UDP 協定在 443 連接埠運作,因此需要開放 UDP 443:
使用 UFW
1
2
3
4
5
6
7
8
| # 允許 TCP 443(HTTP/1.1 和 HTTP/2)
sudo ufw allow 443/tcp
# 允許 UDP 443(HTTP/3)
sudo ufw allow 443/udp
# 查看防火牆規則
sudo ufw status
|
使用 iptables
1
2
3
4
5
6
7
8
| # 允許 TCP 443
sudo iptables -A INPUT -p tcp --dport 443 -j ACCEPT
# 允許 UDP 443
sudo iptables -A INPUT -p udp --dport 443 -j ACCEPT
# 儲存規則
sudo iptables-save | sudo tee /etc/iptables/rules.v4
|
雲端平台安全群組
如果您的伺服器位於 AWS、GCP 或 Azure 等雲端平台,請確保在安全群組或防火牆規則中同時允許 TCP 443 和 UDP 443 的輸入流量。
測試 HTTP/3 連線
驗證設定並重啟 Nginx
1
2
3
4
5
6
7
8
| # 測試設定檔語法
sudo nginx -t
# 重新啟動 Nginx
sudo systemctl restart nginx
# 查看服務狀態
sudo systemctl status nginx
|
使用 curl 測試
如果您的 curl 版本支援 HTTP/3(需要 curl 7.66.0 以上並使用 HTTP/3 支援編譯):
1
2
3
4
5
| # 測試 HTTP/3 連線
curl --http3 -I https://example.com
# 強制使用 HTTP/3
curl --http3-only -I https://example.com
|
使用線上工具測試
瀏覽器開發者工具
在 Chrome 或 Firefox 的開發者工具中,網路分頁的 Protocol 欄位會顯示 h3 表示正在使用 HTTP/3。
效能考量
1. 適用場景
HTTP/3 在以下場景效益最明顯:
- 高延遲網路環境
- 網路狀況不穩定的行動裝置使用者
- 需要頻繁建立新連線的應用
- 大量小檔案的傳輸
2. 資源消耗
QUIC 的加密和解密在用戶端進行,可能增加 CPU 使用率。確保伺服器有足夠的運算資源。
3. 監控指標
建議監控以下指標:
- QUIC 連線數
- 0-RTT 使用率
- 連線遷移次數
- UDP 封包遺失率
4. 回退機制
確保 HTTP/1.1 和 HTTP/2 仍然可用,以便在 HTTP/3 連線失敗時能夠回退:
1
2
| listen 443 ssl; # HTTP/1.1 和 HTTP/2
listen 443 quic; # HTTP/3
|
疑難排解
常見問題
無法建立 QUIC 連線
- 檢查防火牆是否允許 UDP 443
- 確認 SSL 憑證有效且正確設定
Alt-Svc 標頭未發送
- 確認
add_header 指令包含 always 參數 - 檢查是否有其他 location 區塊覆蓋了標頭設定
效能未改善
- HTTP/3 在低延遲網路中的優勢較不明顯
- 檢查是否正確啟用了 0-RTT
查看 QUIC 連線日誌
1
2
| # 查看 QUIC 相關日誌
sudo tail -f /var/log/nginx/access.log | grep -E 'h3|quic'
|
參考資料