在企業內部系統逐步容器化之後,常見會出現這樣的需求:
- 服務全面 Docker 化
- 對外僅開放 單一入口
- 使用 Apache 作為 Reverse Proxy
- Proxy 與後端服務之間 全面 HTTPS
- 後端服務使用 企業自建 CA(Internal CA)
這樣的架構,既安全、又符合企業資安與維運需求,但如果設計不當,也很容易踩到以下地雷:
- 憑證亂放、私鑰外洩
- 容器間 HTTPS 其實沒有驗證
- Internal CA 被當成公開 CA 使用
- Proxy 信任範圍過大,無法控管
這篇文章將從 企業實務角度,完整說明一套可長期維運的 Docker + Apache Reverse Proxy + Internal CA 架構。
一、整體架構目標
這個架構的核心目標有四個:
- 對外僅暴露 Apache
- 所有內部流量皆加密(HTTPS)
- 使用 Internal CA,不依賴公開 CA
- 最小信任、最小暴露面

Internet / Users
│ HTTPS (Public Cert)
▼
+———————-+
| Apache Reverse Proxy |
| (Docker Container) |
+———————-+
│ HTTPS (Internal CA)
▼
+———————-+
| Backend Services |
| (Docker Containers) |
+———————-+
Internal CA
(Offline Root + Intermediate)
三、CA 架構前提(非常重要)
建議 CA 架構(簡述)
Offline Root CA
└─ Intermediate CA
├─ Apache Proxy Certificate
├─ Backend Service A Certificate
└─ Backend Service B Certificate
關鍵原則
- Root CA 永不上線
- Docker 容器中:
- ❌ 不放 Root CA 私鑰
- ❌ 不放 Intermediate 私鑰
- 只有 必要的 CA public cert 才能進容器
四、Apache Reverse Proxy 容器設計
1️⃣ Apache 容器的角色
Apache 在這個架構中同時是:
- 對外:HTTPS Server(Public Cert)
- 對內:HTTPS Client(Internal CA)
👉 這是整個架構的信任核心
2️⃣ Apache 容器內需要哪些憑證?
| 類型 | 用途 |
|---|---|
| Public Cert | 給瀏覽器 |
| Internal CA cert | 驗證後端 |
| ❌ CA 私鑰 | 絕對不能有 |
3️⃣ Apache Reverse Proxy 設定範例
SSLProxyEngine On
# 嚴格驗證後端憑證
SSLProxyVerify require
SSLProxyCheckPeerName on
SSLProxyCheckPeerExpire on
# 信任 Internal CA
SSLProxyCACertificateFile /etc/apache2/ssl/internal-ca.pem
ProxyPreserveHost On
ProxyPass /api https://backend-api:8443/
ProxyPassReverse /api https://backend-api:8443/
📌 重點
backend-api是 Docker network 內的 service name- 憑證 SAN 必須包含
backend-api
五、Backend Service 容器設計
1️⃣ Backend Service 要做什麼?
- 提供 HTTPS
- 使用 Internal CA 簽發的 Server Cert
- 不需要信任 Root CA(除非有雙向 TLS)
2️⃣ Backend 容器憑證配置建議
| 檔案 | 說明 |
|---|---|
| server.crt | Backend 憑證 |
| server.key | Backend 私鑰 |
| ca-chain.pem | Intermediate + Root(如需要) |
⚠️ 私鑰必須:
- 權限最小化
- 僅此服務可讀
六、Docker Network 設計重點
強烈建議:使用獨立內部網路
docker network create internal_net
networks:
internal_net:
internal: true
好處:
- Backend 無法被外部直接連線
- 就算 Backend HTTPS 設定錯誤,也不會對外暴露
七、SNI 與 Service Name 的關係(常被忽略)
為什麼 Docker Service Name 很重要?
- Apache 連後端時使用:
https://backend-api:8443 - Apache 會送出:
SNI = backend-api
👉 Backend 憑證 SAN 必須包含 backend-api
否則就會出現:
- 憑證驗證失敗
- 回到錯誤的 VirtualHost
八、Internal CA 在 Docker 環境的最佳實務
✅ 正確作法
- CA public cert → 只放需要的容器
- CA 管理 → 容器外
- 憑證自動更新 → CI/CD 或管理主機
❌ 錯誤作法
- 把 Root CA 私鑰 build 進 image
- 把整個
/etc/ssl/certs都 COPY 進容器 - 用一張憑證給所有 Backend
九、常見錯誤與實際後果
| 錯誤 | 後果 |
|---|---|
| Proxy 關閉 SSL 驗證 | MITM 無法察覺 |
| Backend 共用憑證 | 憑證外洩即全毀 |
| Root CA 上線 | 無法挽回的信任崩潰 |
| SAN 不一致 | Proxy 無法連線 |
| Docker network 未隔離 | 服務意外對外暴露 |
十、企業實務建議總結
這套架構適合誰?
- 企業內部系統
- ERP / EIP / API 平台
- 郵件、LDAP、內網 Web
- 零信任 / mTLS 的前期基礎
架構價值
- 信任邊界清楚
- 可長期維運
- 憑證可控、可撤銷
- 容器化不犧牲資安
結語:這不是 Docker 技巧,而是信任設計
Docker + Apache Reverse Proxy + Internal CA
不是在「多加一層 HTTPS」,而是在建立一個:
可控、可追蹤、可撤銷的企業信任模型
只要這套基礎打穩,後續你要延伸到:
- mTLS
- Service Mesh
- Zero Trust
- Hybrid Cloud
都會非常順。