# Nginx 反向代理 + SSL 設置指南 本指南說明如何使用 Nginx 設置反向代理並啟用 SSL (HTTPS)。 ## 前置需求 - 已安裝 Nginx - 已註冊的域名(例如:hackmd.example.com) - 域名已指向你的伺服器 IP ## 快速設置 ### 步驟 1:安裝 Certbot (Let's Encrypt) **Ubuntu/Debian:** ```bash sudo apt update sudo apt install certbot python3-certbot-nginx -y ``` **CentOS/RHEL:** ```bash sudo yum install certbot python3-certbot-nginx -y ``` **macOS (開發測試):** ```bash brew install certbot ``` ### 步驟 2:創建 Nginx 配置文件 複製 `nginx-example.conf` 到 Nginx 配置目錄: ```bash # 複製配置文件 sudo cp nginx-example.conf /etc/nginx/sites-available/codimd # 編輯配置,替換 your-domain.com 為你的實際域名 sudo nano /etc/nginx/sites-available/codimd ``` 修改以下內容: - `your-domain.com` → 你的實際域名(例如 `hackmd.example.com`) ### 步驟 3:創建 Certbot 驗證目錄 ```bash sudo mkdir -p /var/www/certbot ``` ### 步驟 4:測試並啟用配置 ```bash # 測試配置語法 sudo nginx -t # 啟用站點 sudo ln -s /etc/nginx/sites-available/codimd /etc/nginx/sites-enabled/ # 重新載入 Nginx sudo systemctl reload nginx ``` ### 步驟 5:取得 SSL 證書 ```bash # 自動取得並配置證書 sudo certbot --nginx -d your-domain.com # 或者先取得證書,手動配置 sudo certbot certonly --webroot -w /var/www/certbot -d your-domain.com ``` Certbot 會自動: 1. 取得免費的 SSL 證書 2. 配置 Nginx 使用 HTTPS 3. 設置自動續期 ### 步驟 6:更新 CodiMD 環境變數 編輯 `.env` 文件: ```bash nano .env ``` 更新以下變數: ```env # 改為你的域名 CMD_DOMAIN=your-domain.com # 啟用 HTTPS CMD_PROTOCOL_USESSL=true # 端口設定 (使用反向代理時設為 false) CMD_URL_ADDPORT=false ``` 重啟 CodiMD: ```bash docker-compose restart codimd ``` ### 步驟 7:驗證 SSL 設置 訪問你的域名: - https://your-domain.com 檢查 SSL 評分:https://www.ssllabs.com/ssltest/ ## 自動續期 SSL 證書 Let's Encrypt 證書有效期为 90 天,需要自動續期。 ### 設置自動續期 **Ubuntu/Debian (systemd timer):** ```bash sudo certbot renew --dry-run sudo systemctl status certbot.timer ``` **CentOS/RHEL (cron):** ```bash # 添加 cron job echo "0 0,12 * * * root certbot renew --quiet" | sudo tee -a /etc/crontab ``` **手動續期:** ```bash sudo certbot renew sudo systemctl reload nginx ``` ## 防火牆設定 確保開放必要的端口: ```bash # UFW (Ubuntu) sudo ufw allow 80/tcp sudo ufw allow 443/tcp sudo ufw enable # firewalld (CentOS) sudo firewall-cmd --permanent --add-service=http sudo firewall-cmd --permanent --add-service=https sudo firewall-cmd --reload # iptables sudo iptables -A INPUT -p tcp --dport 80 -j ACCEPT sudo iptables -A INPUT -p tcp --dport 443 -j ACCEPT ``` ## 修改 CodiMD Port 綁定 使用反向代理後,建議將 CodiMD 改回只綁定本地: 修改 `docker-compose.yml`: ```yaml ports: - "127.0.0.1:3000:3000" # 只允許本地存取 ``` 然後重啟: ```bash docker-compose down docker-compose up -d ``` ## 故障排除 ### 證書取得失敗 ```bash # 檢查域名 DNS 是否正確指向伺服器 nslookup your-domain.com # 檢查 80 port 是否開放 sudo netstat -tlnp | grep :80 # 查看 Certbot 日誌 sudo cat /var/log/letsencrypt/letsencrypt.log ``` ### WebSocket 連線失敗 確認 Nginx 配置包含以下設定: ```nginx proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; proxy_http_version 1.1; ``` ### 混合內容警告 確保 CodiMD 環境變數設定正確: ```env CMD_DOMAIN=your-domain.com CMD_PROTOCOL_USESSL=true ``` ## 進階配置 ### 強制 HTTPS 重定向 ```nginx # 在 HTTP server block 添加 if ($host != your-domain.com) { return 301 https://$host$request_uri; } ``` ### 限制上傳大小 ```nginx # 在 server block 添加 client_max_body_size 100M; ``` ### 啟用壓縮 ```nginx # 在 http block 或 server block 添加 gzip on; gzip_vary on; gzip_min_length 1024; gzip_types text/plain text/css text/xml text/javascript application/x-javascript application/xml+rss application/json; ``` ## 安全檢查清單 - [ ] SSL 證書已正確安裝 - [ ] HTTP 自動重定向到 HTTPS - [ ] WebSocket 連線正常 - [ ] CodiMD 環境變數已更新 - [ ] 防火牆規則已設置 - [ ] 自動續期已啟用 - [ ] SSL 測試獲得 A 或 A+ 評分 ## 相關連結 - [Let's Encrypt 官方文件](https://letsencrypt.org/docs/) - [Nginx SSL 配置指南](https://nginx.org/en/docs/http/configuring_https_servers.html) - [Mozilla SSL Configuration Generator](https://ssl-config.mozilla.org/) - [SSL Labs 測試工具](https://www.ssllabs.com/ssltest/)