feat: 新增 OCRmyPDF 轉換引擎 (v0.1.14)

## 新功能
- OCRmyPDF 轉換引擎:將掃描版 PDF 轉換為可搜尋 PDF
  - 支援 7 種語言:en, zh-TW, zh, ja, ko, de, fr
  - 與 PDFMathTranslate 風格一致的 UI 格式 (pdf-<lang>)
  - 自動偵測頁面方向並旋轉
  - 自動校正傾斜
  - 跳過已有文字層的頁面
  - 詳細的 5 階段處理進度輸出

## 建置
- Dockerfile:安裝 ocrmypdf 與 Tesseract OCR 語言包

## 文件
- 更新 OCR 功能文件
- 文件目錄結構改為中文名稱

## 測試
- 修復 BabelDOC 和 PDFMathTranslate 測試的 OCR mock
- 所有 345 個測試通過
This commit is contained in:
Your Name 2026-01-23 16:28:33 +08:00
parent f24eec070c
commit a06df23b1d
53 changed files with 1427 additions and 675 deletions

View file

@ -0,0 +1,257 @@
# 安全性設定
本文件說明 ConvertX-CN 的安全性設定與最佳實踐。
---
## Cookie 與登入安全
### HTTP_ALLOWED
控制是否允許非 HTTPS 連線。
- `HTTP_ALLOWED=true` — 允許 HTTP不安全僅測試用
- `HTTP_ALLOWED=false` — 僅允許 HTTPS預設
```yaml
- HTTP_ALLOWED=false
```
#### 運作原理
`HTTP_ALLOWED=false`Cookie 會設定 `Secure` 屬性,只在 HTTPS 連線下傳送。
若實際用 HTTP 存取:
- 瀏覽器不會傳送 Cookie
- 每次請求都像未登入
- 造成「登入後又被踢回登入頁」
#### 設定建議
| 情境 | 設定值 |
| ------------------ | ------- |
| `localhost` 測試 | `true` |
| 區網 IP 測試 | `true` |
| 有 HTTPS 憑證 | `false` |
| 透過反向代理 HTTPS | `false` |
---
### TRUST_PROXY
是否信任反向代理傳來的 headers。
- `TRUST_PROXY=true` — 信任 X-Forwarded-\* headers
- `TRUST_PROXY=false` — 不信任(預設)
```yaml
- TRUST_PROXY=false
```
#### 運作原理
當請求經過反向代理時:
- 原始連線:使用者 → Nginx (HTTPS) → ConvertX (HTTP)
- 沒有 TRUST_PROXYConvertX 看到的是 HTTP 連線
- 有 TRUST_PROXYConvertX 讀取 `X-Forwarded-Proto: https`,知道原始是 HTTPS
#### 設定建議
| 情境 | 設定值 |
| ---------------------------- | ------- |
| 直接存取容器(無 Proxy | `false` |
| 透過 Nginx / Traefik / Caddy | `true` |
| 透過 Cloudflare Tunnel | `true` |
> ⚠️ **安全注意**:只在確實有反向代理時才設為 `true`。若直接暴露容器且設為 `true`,攻擊者可偽造 headers。
---
## 帳號安全
### ACCOUNT_REGISTRATION
- `ACCOUNT_REGISTRATION=true` — 開放註冊
- `ACCOUNT_REGISTRATION=false` — 關閉註冊
```yaml
- ACCOUNT_REGISTRATION=false
```
#### 建議流程
1. 首次部署設為 `true`(或不設定)
2. 註冊管理員帳號
3. 改為 `false`
4. 重啟容器
### JWT_SECRET
```yaml
- JWT_SECRET=your-secret-key-at-least-32-chars
```
#### 重要性
- 用於簽署登入 Token
- 不設定:每次重啟產生新密鑰,所有人被登出
- 設定固定值:登入狀態跨重啟保留
#### 產生方式
**Linux / macOS**
```bash
openssl rand -hex 32
```
**Windows PowerShell**
```powershell
-join ((1..32) | ForEach-Object { '{0:x2}' -f (Get-Random -Max 256) })
```
**線上工具:**
- https://generate-secret.vercel.app/32
**Node.js**
```bash
node -e "console.log(require('crypto').randomBytes(32).toString('hex'))"
```
> 💡 產生的密鑰應為 32-64 字元的隨機字串,例如:`a1b2c3d4e5f6789...`
---
## 公開服務安全
### ALLOW_UNAUTHENTICATED
- `ALLOW_UNAUTHENTICATED=true` — 允許未登入使用
- `ALLOW_UNAUTHENTICATED=false` — 必須登入(預設)
```yaml
- ALLOW_UNAUTHENTICATED=false
```
#### 風險
設為 `true` 時:
- 任何人可使用轉換功能
- 消耗伺服器 CPU / 記憶體 / 磁碟
- 可能被惡意利用
#### 緩解措施
若需要公開服務,建議:
- `AUTO_DELETE_EVERY_N_HOURS=1` — 頻繁清理
- `HIDE_HISTORY=true` — 隱藏歷史
- `MAX_CONVERT_PROCESS=2` — 限制同時轉換數
```yaml
environment:
- ALLOW_UNAUTHENTICATED=true
- AUTO_DELETE_EVERY_N_HOURS=1
- HIDE_HISTORY=true
- MAX_CONVERT_PROCESS=2
```
---
## 網路安全
### 防火牆
只開放必要的埠。
**UFW (Ubuntu) 開放單一埠:**
```bash
sudo ufw allow 3000/tcp
```
**只允許特定 IP 範圍:**
```bash
sudo ufw allow from 192.168.1.0/24 to any port 3000
```
### 只允許本機存取
> 💡 `127.0.0.1:3000:3000` 只有本機可存取
```yaml
ports:
- "127.0.0.1:3000:3000"
```
搭配反向代理提供對外服務。
### 限制上傳大小
在反向代理層限制Nginx 範例):
```nginx
client_max_body_size 100M;
```
---
## 資料安全
### 定期清理
> 💡 每 24 小時自動清理過期檔案
```yaml
- AUTO_DELETE_EVERY_N_HOURS=24
```
### 備份
使用 crontab 設定定期備份(每天凌晨 2 點):
```bash
0 2 * * * tar -czvf /backup/convertx-$(date +\%Y\%m\%d).tar.gz /path/to/data
```
### 權限設定
限制資料夾權限,僅允許擁有者存取:
```bash
chmod 700 ./data
```
---
## 安全檢查清單
### 部署前
- [ ] 設定固定的 `JWT_SECRET`
- [ ] 關閉 `ACCOUNT_REGISTRATION`(如果不需要公開註冊)
- [ ] 設定 `TRUST_PROXY=true`(如果使用反向代理)
- [ ] 設定 `HTTP_ALLOWED=false`(如果有 HTTPS
### 部署後
- [ ] 確認只有必要的埠對外開放
- [ ] 確認反向代理有正確設定
- [ ] 確認 HTTPS 憑證有效
- [ ] 設定定期備份
- [ ] 設定定期清理
---
## 相關文件
- [環境變數設定](環境變數.md)
- [反向代理設定](../部署指南/反向代理.md)
- [Docker 部署](../部署指南/Docker.md)