把「HTTPS 有加密」升級為「HTTPS 有驗證」
在企業內部導入 Internal CA / PKI 後,最常遇到的一個關鍵問題是:
要怎麼讓 Apache / Nginx「正確且安全地」信任 Internal CA?
很多環境看似已經做到:
- 全面 HTTPS
- 憑證由自建 CA 簽發
但實際上卻存在以下隱性風險:
- Proxy 根本沒有驗證後端憑證
- CA 被過度信任(整包系統 CA)
- SAN / SNI 不一致導致驗證被關掉
- 為了「先跑起來」,直接關 SSL 驗證
這篇文章將從 實戰角度,一步一步說明
Apache 與 Nginx 在企業環境中,如何安全、可控地信任 Internal CA。
一、先釐清一個關鍵觀念
在 Reverse Proxy 架構中:
Client ──HTTPS──> Proxy ──HTTPS──> Backend
- 對 Client:Proxy 是 TLS Server
- 對 Backend:Proxy 是 TLS Client
👉 Internal CA 的價值,幾乎全部發揮在「Proxy → Backend」這一段
如果 Proxy 沒有驗證 Backend 憑證:
HTTPS 只剩加密,沒有身分驗證
二、典型企業架構示意

User
│ HTTPS (Public Cert)
▼
Apache / Nginx Reverse Proxy
│ HTTPS (Internal CA)
▼
Backend Services
安全與否,不取決於「有沒有 HTTPS」,
而取決於:
Proxy 是否真的信任「正確的 CA」,並驗證「正確的身分」
三、Internal CA 準備原則(非常重要)
在設定 Apache / Nginx 前,請先確認:
✅ 你應該擁有的 CA 檔案
- Internal Root CA(公鑰)
- 或 Intermediate CA(公鑰)
❌ 絕對不該出現的東西
- Root / Intermediate 私鑰
- 整包系統 CA bundle(除非你很清楚風險)
👉 Proxy 只需要「信任誰」,不需要「能簽憑證」
四、Apache:安全信任 Internal CA(實戰)
1️⃣ Apache 的設計哲學(PKI 友善)
Apache 在 Reverse Proxy → HTTPS Backend 的行為是:
把自己當成真正的 TLS Client
因此只要設定正確,Apache 的行為:
- 明確
- 可預期
- 容易稽核
2️⃣ Apache 正確設定範例
SSLProxyEngine On
# 強制驗證後端憑證
SSLProxyVerify require
SSLProxyCheckPeerName on
SSLProxyCheckPeerExpire on
# 只信任 Internal CA
SSLProxyCACertificateFile /etc/apache2/ssl/internal-ca.pem
ProxyPreserveHost On
ProxyPass /api https://backend-api.internal/
ProxyPassReverse /api https://backend-api.internal/
Apache 實際驗證的項目
- 憑證是否由 Internal CA 簽發
- SAN 是否包含
backend-api.internal - 憑證是否過期
👉 這是「完整 PKI 驗證」,不是形式上的 HTTPS
3️⃣ Apache 常見錯誤
❌ 使用 IP 當 ProxyPass 目標(SNI 失效)
❌ SAN 與 hostname 不一致
❌ 把整個系統 CA bundle 都信任
五、Nginx:安全信任 Internal CA(必須小心)
1️⃣ 重要事實:Nginx 預設不驗證後端憑證
這代表:
如果你沒特別設定,Nginx 只加密、不驗證
在 Internal PKI 環境中,這是高風險狀態。
2️⃣ Nginx 正確設定(缺一不可)
proxy_ssl_verify on;
proxy_ssl_trusted_certificate /etc/nginx/internal-ca.pem;
proxy_ssl_server_name on;
每一行的意義
proxy_ssl_verify on;
👉 開啟憑證驗證proxy_ssl_trusted_certificate
👉 指定「只信任哪個 CA」proxy_ssl_server_name on;
👉 啟用 SNI,避免憑證錯誤
3️⃣ Nginx 常見實務陷阱
❌ 只設定 CA,卻忘了 proxy_ssl_verify on
❌ 用 IP 連 backend(SNI 失效)
❌ CA 檔案放太多、不清楚信任範圍
👉 Nginx 的自由度高,但也更容易「默默不安全」
六、Apache vs Nginx:Internal CA 行為差異總結
| 項目 | Apache | Nginx |
|---|---|---|
| 預設驗證後端憑證 | 偏嚴謹 | 預設不驗證 |
| Internal CA 設定 | 清楚、直覺 | 必須手動補齊 |
| SAN / SNI 驗證 | 明確 | 容易忽略 |
| 誤用風險 | 低 | 高 |
| PKI 稽核友善度 | 高 | 視團隊成熟度 |
七、企業級最佳實務建議
✅ 一定要做
- Proxy → Backend 強制驗證憑證
- 使用 hostname,不用 IP
- CA 信任最小化
- 憑證 SAN 精準
❌ 絕對不要做
- 關閉 SSL 驗證
- 信任所有 CA
- 用萬用憑證
- 把憑證問題當成「先跳過」
八、Zero Trust 視角的一句話結論
Zero Trust 的核心是:
每一次連線,都必須驗證身分
如果 Apache / Nginx:
- 沒有驗證 Internal CA
- 只是轉發加密流量
那這條連線:
不符合 Zero Trust,也不符合企業資安要求
結語:信任,是一條要「刻意設計」的路
讓 Apache / Nginx 安全信任 Internal CA,
不是多寫幾行設定,而是在做一件事:
明確定義:誰值得被信任、信任到什麼程度
只要這一步做好,你後續在:
- Reverse Proxy
- Docker / K8s
- mTLS
- Zero Trust
都會輕鬆很多。