by Rain Chu | 6 月 9, 2025 | Nginx, SERVER
在從網路上取得網頁時,如果想用 Nginx 作為反向代理器來連線一個介由 Cloudflare 保護且介面是 HTTPS 的網站,你可能會遇到一些繁複的錯誤,包括 Cloudflare Error 1001,502 Bad Gateway,或 421 Misdirected Request 等,這邊就分享一下我遇到的經驗以及如何正確設定 Nginx,反向代理一個有 SSL 保護的網站。
環境概要
- Nginx 作為前端 proxy :
shop.example.com 
- Upstream 目標 :
https://target.example.com(Cloudflare 網站) 
- Cloudflare 用於 DNS + CDN + WAF
 
1. Nginx 基礎設定
幾個重點
1.1 要聽 443 port
1.2 要設定 proxy_ssl_name, proxy_ssl_server_name
1.3 DNS 要設定 resolver
upstream secure_pool {
    server target.example.com:443;
    keepalive 16;
}
server {
    listen 443 ssl;
    server_name shop.example.com;
    ssl_certificate /etc/letsencrypt/live/shop.example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/shop.example.com/privkey.pem;
    include /etc/letsencrypt/options-ssl-nginx.conf;
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
    resolver 1.1.1.1 8.8.8.8 valid=300s;
    location / {
        proxy_pass https://secure_pool;
        proxy_ssl_server_name on;
        proxy_ssl_name target.example.com;
        proxy_set_header Host target.example.com;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header User-Agent "Mozilla/5.0 (compatible; Nginx Proxy)";
    }
} 
2. 常見錯誤與解決方案
❌ Error 1001 – DNS Resolution Error (Cloudflare)
- 原因:Cloudflare 無法解析 upstream hostname
 
- 解決:確保 Nginx 加入 
resolver 設定 
❌ 502 Bad Gateway
- 原因:upstream HTTPS 連線失敗
 
- 解決:
proxy_pass 設為 https://... 
proxy_ssl_server_name on; 
- 加入 
proxy_ssl_name + Host 不要用 $host 
 
❌ 421 Misdirected Request
- 原因:SNI 與 Host header 不符
 
- 解決:
proxy_ssl_name target.example.com; 
proxy_set_header Host target.example.com; 
 
3. Debug 技巧
看 error log 解答還原:
用 curl 測試 upstream 是否支援 HTTPS
4. 結論
要用 Nginx 來反向代理一個 SSL 網站,最重要的是使 Nginx 能「知道」你的 upstream 是 HTTPS,且 TLS SNI 與 Host 項目必須一致。
				
					
			
					
				
															
					
					 by rainchu | 12 月 19, 2024 | Nginx, SERVER, wordpress
大前提你要先安裝有支援 webp, avif 的外掛,例如EWWW, Convert Media等等
在 Nginx 配置中加 map 指令:
- 在 Nginx 的主配置文件,通常在 
/etc/nginx/nginx.conf。 
- 在 
http {} 内、server {} 之前,加入以下内容: 
map $http_accept $avif_suffix {
    default "";
    "~*avif" ".avif";
}
map $http_accept $webp_suffix {
    default "";
    "~*webp" ".webp";
} 
- 配置客户端的 
Accept ,來定義 $avif_suffix 和 $webp_suffix 變量,確認是否支持 AVIF 或 WebP 格式。 
Nginx 讀取 AVIF 和 WebP 的 MIME Type:
找到 /etc/nginx/ 的 mime.types 
image/avif  avif;
image/webp  webp;
 
在站點配置中設定重導向:
- 找到 
/etc/nginx/sites-available/yourdomain。 
- 在 
server {} ,加入以下内容: 
location ~* ^/wp-content/.+\.(jpe?g|png|gif)$ {
    add_header Vary Accept;
    add_header Cache-Control "private";
    expires 365d;
    try_files $uri$avif_suffix $uri$webp_suffix $uri =404;
} 
作用是:
- 匹配所有請求的 
.jpg、.jpeg、.png 和 .gif 文件。 
-  
Vary: Accept ,告訴缓存系統按照 Accept 來區分不同的響應。 
- 缓存控制和過期時間。
 
- 使用 
try_files 指令,會先試提供的 .avif 文件,如果不存在,則提供 .webp 文件,若仍不存在,則提供原始文件。 
測試並且重新加載 Nginx 配置:
sudo nginx -t
sudo systemctl reload nginx
 
這些配置假設您的 .avif 和 .webp 文件與原始圖片文件位於相同的目錄,並具有相同的文件名,只是副檔名不同(例如,image.jpg 對應 image.jpg.avif 和 image.jpg.webp)。
此外,請確保您的伺服器上已經存在對應的 .avif 和 .webp 文件,否則 Nginx 將返回 404 錯誤。
有關更多詳細資訊,您可以參考以下資源:
網站圖片無縫兼容 WebP/AVIF
在 Nginx 上提供 WebP 和 AVIF 圖片
圖片優化新選擇!WebP、AVIF 如何提升網站速度
				
					
			
					
				
															
					
					 by rainchu | 12 月 19, 2024 | Nginx, SERVER
確認 Nginx 版本
安裝 Brotli 模組
有安裝的可以跳過這一步驟,但多數 nginx 是預設沒有安裝 brotli 模組的,下載 brotli 並且安裝
cd /path/to/nginx/source
./configure --add-module=/path/to/ngx_brotli
make
sudo make install
 
配置 Nginx 啟用 Brotli 壓縮
找到 nginx 的設定檔,通常位於 /etc/nginx/nginx.conf ,如果是自己編譯的通常位於 /usr/local/nginx/conf/nginx.conf
brotli on;
brotli_comp_level 6;
brotli_static on;
brotli_types text/plain text/css application/javascript application/json text/xml application/xml application/xml+rss text/javascript image/x-icon image/svg+xml;
 
brotli on;:啟用 Brotli 壓縮。
brotli_comp_level 6;:設定壓縮等級,範圍為 0(無壓縮)到 11(最高壓縮),建議值為 6。
brotli_static on;:允許查找預先壓縮的 .br 檔案。
brotli_types ...;:指定需要壓縮的 MIME 類型,可根據實際需求進行調整。
測試並重新載入 Nginx
sudo nginx -t
sudo systemctl reload nginx
 
驗證 Brotli 壓縮是否啟用
curl -I -H "Accept-Encoding: br" https://您的域名
 
如果回應頭中包含 Content-Encoding: br,則表示 Brotli 壓縮已成功啟用。
Brotli 壓縮的關鍵特性
高壓縮率
- Brotli 使用自適應哈夫曼編碼和自定義字典來提高壓縮率,比 Gzip 通常高出 15% 至 25%。
 
- 更高的壓縮率可以減少網頁資源的大小,從而提升網站的載入速度。
 
快速解壓
- 雖然 Brotli 的壓縮過程稍慢,但解壓速度非常快,這對於瀏覽器端非常重要,因為解壓過程是即時進行的。
 
支援範圍廣泛
- Brotli 已被主流的現代瀏覽器(如 Chrome、Firefox、Edge 和 Safari)支援,並且可與 Web 伺服器(如 Nginx 和 Apache)整合。
 
適合靜態和動態內容
- Brotli 特別適合靜態資源(如圖片和腳本)壓縮,對動態生成的內容同樣表現出色。
 
Brotli 與 Gzip 的比較表
| 特性 | Brotli | Gzip | 
|---|
| 壓縮率 | 高,壓縮比更優 | 一般 | 
|---|
| 解壓速度 | 快 | 快 | 
|---|
| 壓縮速度 | 較慢(高壓縮等級下) | 更快 | 
|---|
| 支援的瀏覽器 | 現代瀏覽器全部支援 | 幾乎所有瀏覽器支援 | 
|---|
| 靜態檔案優化 | 優異 | 一般 | 
|---|
 
相關資源
				
					
			
					
				
															
					
					 by Rain Chu | 10 月 19, 2024 | Nginx, SERVER
如果你也是 wordpress 愛用 WP Rocket 的使用者,並且WEB SERVER是用 NGINX 架設的,那肯定要參考這個 GitHub 項目,來作為你 Nginx 以及伺服器上面的最佳設定
安裝
先從 github 中下載下來
cd /etc/nginx
git clone https://github.com/satellitewp/rocket-nginx.git
 
並且利用 PHP 產生預設的配置檔
cd rocket-nginx
cp rocket-nginx.ini.disabled rocket-nginx.ini
php rocket-parser.php
 
設定 Nginx
找到 nginx 的設定檔,通常在 /etc/nginx/sites-available ,並且加入設定
server {
  ...
  
  # Rocket-Nginx configuration
  include rocket-nginx/conf.d/default.conf;
  
  ...
} 
項目位置
GitHub Rocket-nginx
				
					
			
					
				
															
					
					 by Rain Chu | 4 月 17, 2024 | Nginx, NodeJS, SERVER, 程式
如果你有用 Nginx 的快取服務,無論是 fastcgi or proxy cache,都會遇到很難有一套真正好用的清除工具,這邊示範一套自己開發的清除工具,也支援多伺服器使用
安裝必要的套件
你先需要有nodejs,沒有的人先去官網安裝下,安裝完畢的人,先建立一個目錄,並且輸入以下指令,安裝必要的套件
npm init -y
npm install express
 
建立一個 Node.js App
可以命名為 app.js,內容如下,會建立一個小型的伺服器,用來處理 http 的請求,並且刪除指定的目錄
const express = require('express');
const { exec } = require('child_process');
const fs = require('fs');
const app = express();
const PORT = 3000;
const logFile = 'application.log';
function log(message) {
    const timestamp = new Date().toISOString();
    fs.appendFileSync(logFile, `${timestamp} - ${message}\n`);
}
app.get('/delete-dir', (req, res) => {
    let dir = req.query.dir;
    if (!dir || /[^a-zA-Z0-9_\-\/]/.test(dir)) {
        log('提供的路徑不合法!');
        return res.status(400).send('提供的路徑不合法!');
    }
    const command = `sudo find /run/proxy_cache/${dir} -mindepth 1 -type d -exec rm -rf {} +`;
    exec(command, (error, stdout, stderr) => {
        if (error) {
            log(`执行错误: ${error}`);
            return res.status(500).send('删除子目錄失敗!');
        }
        log('子目錄删除成功!');
        res.send('子目錄删除成功!');
    });
});
app.listen(PORT, () => {
    log(`服务器正在运行于 http://localhost:${PORT}`);
}); 
其中我把能刪除的資料定義在只有這個目錄下的才行 /run/proxy_cache/ ,避免權限過大問題
配置 sudo 權限
打開 sudoers 文件
加入指令,記得把 <username> 改成自己的名字,或是 www-data
<username> sudo find /run/proxy_cache/ -mindepth 1 -type d -exec rm -rf {} + 
完成後的測試
可以利用 CURL 呼叫 API ,成功就會看到 “子目錄删除成功!” 的訊息
curl "http://localhost:3000/delete-dir?dir=cache_directory"
 
結論與注意事項
要記得別讓外部的人可以輕易地存取這項服務,防火牆要記得把port鎖好,執行權限要小心設定,這樣就可以搭配 Nginx Cache 使用,之後再來出對應的刪除功能。
開機時候自動執行
要讓 Node.js 應用在系統開機時由特定使用者(例如 www-data)啟動,需要配置一個 systemd 服務單元。在這個情況中,我們將創建一個服務單元文件來確保 Node.js 應用作為 www-data 使用者運行。
創建 systemd 服務文件
建立一個新的 systemd 服務文件。 
sudo nano /etc/systemd/system/nodeapp.service
 
加入以下配置
[Unit] 
Description=Node.js Web Application 
After=network.target 
[Service] 
Type=simple 
User=www-data 
Group=www-data 
WorkingDirectory=/path/to/your/app 
ExecStart=/usr/bin/node /path/to/your/app/app.js 
Restart=on-failure 
[Install] 
WantedBy=multi-user.target
 
參數意思如下
Description: 服務的描述。
After: 這個單元應該在網絡服務可用之後啟動。
User 和 Group: 指定運行此服務的使用者和組。
WorkingDirectory: 指定 Node.js 應用的工作目錄。
ExecStart: 指定啟動應用的命令。
Restart: 指定何時重新啟動服務,on-failure 表示只在程序異常退出時重啟。
啟用和啟動服務
重新加載 systemd 配置以讀取新的服務文件:
sudo systemctl daemon-reload
 
啟用剛創建的服務,使其在開機時自動啟動:
sudo systemctl enable nodeapp.service
 
啟動服務以檢查它是否運行正常:
sudo systemctl start nodeapp.service
 
檢查服務的狀態來確認一切正常:
sudo systemctl status nodeapp.service
 
				
					
			
					
				
															
					
					 by Rain Chu | 4 月 16, 2024 | Nginx, SERVER, web, wordpress, 程式
sudoers 檔案控制了使用者及群組在使用 sudo 指令時的權限。為了安全編輯這個檔案,應該使用 visudo 指令,因為它會檢查語法錯誤,避免創建一個無法使用的 sudoers 檔案。
更新 sudoers 檔案的步驟:
開啟終端機: 
開啟你的伺服器的命令行介面。
使用 visudo 編輯 sudoers 檔案: 輸入以下指令以安全方式編輯 sudoers 檔案:
新增規則: 
在編輯器中,新增一條規則,允許 www-data 使用者無需密碼執行特定指令。
www-data ALL=(ALL) NOPASSWD: /usr/bin/rm -rf /path/to/nginx/cache/*
 
指令的意義是:
www-data:指定的使用者。
ALL=(ALL):這表示 www-data 使用者可以從任何主機以任何使用者身份執行指令。
NOPASSWD:允許 www-data 使用者在執行指定的指令時不需要輸入密碼。
/usr/bin/rm -rf /path/to/nginx/cache/*:指定 www-data 使用者無密碼可以執行的指令。
儲存並退出編輯器:
如果你使用的是 nano,按 Ctrl+X 來退出,然後按 Y 鍵儲存更改,最後按 Enter 鍵確認檔案名稱。
測試配置: 
為了確保設定正確無誤,可以用 www-data 份執行指令:
sudo -u www-data sudo /usr/bin/rm -rf /path/to/nginx/cache/*
 
如果不需要密碼且指令執行成功,代表 sudoers 檔案配置正確。
安全注意事項:
- 最小權限原則:只授權必要的最小權限,避免給予 
www-data 使用者太廣泛的權限。 
- 明確指令路徑:使用完整的指令路徑(如 
/usr/bin/rm),避免安全風險。 
- 定期審計:定期檢查 
sudoers 檔案,確保所有條目仍然符合組織的安全政策和操作需要。 
				
					
						 
近期留言