docs: add Nginx reverse proxy configuration with SSL guide
- Add nginx-example.conf with complete SSL configuration - Add SSL-SETUP.md with step-by-step setup guide - Include Let's Encrypt certbot instructions - Add WebSocket support for real-time collaboration - Include security headers and best practices - Add troubleshooting section Co-Authored-By: Claude Sonnet 4 <noreply@anthropic.com>
This commit is contained in:
253
SSL-SETUP.md
Normal file
253
SSL-SETUP.md
Normal file
@@ -0,0 +1,253 @@
|
|||||||
|
# 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/)
|
||||||
83
nginx-example.conf
Normal file
83
nginx-example.conf
Normal file
@@ -0,0 +1,83 @@
|
|||||||
|
# Nginx 反向代理配置範例 (含 SSL)
|
||||||
|
# 放置位置:/etc/nginx/sites-available/codimd
|
||||||
|
|
||||||
|
# HTTP - 自動重定向到 HTTPS
|
||||||
|
server {
|
||||||
|
listen 80;
|
||||||
|
listen [::]:80;
|
||||||
|
server_name your-domain.com;
|
||||||
|
|
||||||
|
# Let's Encrypt 驗證目錄
|
||||||
|
location /.well-known/acme-challenge/ {
|
||||||
|
root /var/www/certbot;
|
||||||
|
}
|
||||||
|
|
||||||
|
# 其他 HTTP 流量重定向到 HTTPS
|
||||||
|
location / {
|
||||||
|
return 301 https://$server_name$request_uri;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# HTTPS - 主要服務
|
||||||
|
server {
|
||||||
|
listen 443 ssl http2;
|
||||||
|
listen [::]:443 ssl http2;
|
||||||
|
server_name your-domain.com;
|
||||||
|
|
||||||
|
# SSL 證書配置 (Let's Encrypt)
|
||||||
|
ssl_certificate /etc/letsencrypt/live/your-domain.com/fullchain.pem;
|
||||||
|
ssl_certificate_key /etc/letsencrypt/live/your-domain.com/privkey.pem;
|
||||||
|
|
||||||
|
# SSL 安全配置
|
||||||
|
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:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384';
|
||||||
|
ssl_prefer_server_ciphers off;
|
||||||
|
ssl_session_cache shared:SSL:10m;
|
||||||
|
ssl_session_timeout 10m;
|
||||||
|
ssl_session_tickets off;
|
||||||
|
|
||||||
|
# HSTS (HTTP Strict Transport Security)
|
||||||
|
add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload" 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 Referrer-Policy "no-referrer-when-downgrade" always;
|
||||||
|
|
||||||
|
# 用戶端上傳大小限制
|
||||||
|
client_max_body_size 50M;
|
||||||
|
|
||||||
|
# 反向代理到 CodiMD
|
||||||
|
location / {
|
||||||
|
proxy_pass http://127.0.0.1:3000;
|
||||||
|
proxy_http_version 1.1;
|
||||||
|
|
||||||
|
# WebSocket 支援 (CodiMD 即時協作需要)
|
||||||
|
proxy_set_header Upgrade $http_upgrade;
|
||||||
|
proxy_set_header Connection "upgrade";
|
||||||
|
|
||||||
|
# 標準代理標頭
|
||||||
|
proxy_set_header Host $host;
|
||||||
|
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 X-Forwarded-Host $host;
|
||||||
|
proxy_set_header X-Forwarded-Port $server_port;
|
||||||
|
|
||||||
|
# 超時設定
|
||||||
|
proxy_connect_timeout 60s;
|
||||||
|
proxy_send_timeout 60s;
|
||||||
|
proxy_read_timeout 60s;
|
||||||
|
|
||||||
|
# 緩衝設定
|
||||||
|
proxy_buffering off;
|
||||||
|
proxy_request_buffering off;
|
||||||
|
}
|
||||||
|
|
||||||
|
# 健康檢查端點 (可選)
|
||||||
|
location /health {
|
||||||
|
access_log off;
|
||||||
|
proxy_pass http://127.0.0.1:3000;
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user