透過Openssl建立OCSP伺服器

OCSP Server Build By Openssl

前言

在現代網路安全架構中,憑證的有效性驗證是確保通訊安全的關鍵環節。當一張數位憑證因為私鑰洩露、員工離職、或其他安全因素需要提前作廢時,我們需要一個機制讓所有依賴該憑證的系統能夠即時得知這個狀態變更。這就是 OCSP(Online Certificate Status Protocol,線上憑證狀態協議) 的核心價值。

OCSP 是由 IETF 在 RFC 6960 中定義的網際網路協議,用於即時查詢 X.509 數位憑證的撤銷狀態。當客戶端(如瀏覽器)收到一張憑證時,它可以向 OCSP Responder 發送查詢請求,取得該憑證目前是「有效(good)」、「已撤銷(revoked)」還是「未知(unknown)」的狀態。

為什麼需要 OCSP?

在企業環境中,建立自己的 OCSP 伺服器有以下幾個重要的應用場景:

  1. 內部 PKI 基礎設施:企業使用自簽憑證或私有 CA 時,需要自建 OCSP 服務來提供憑證狀態查詢
  2. 即時撤銷響應:當發現憑證遭到濫用或私鑰洩露時,能夠立即通知所有客戶端
  3. 合規性要求:許多安全標準(如 PCI DSS)要求實施憑證撤銷檢查機制
  4. 零信任架構:在零信任安全模型中,持續驗證憑證狀態是重要的一環

OCSP 與 CRL 的比較

在 OCSP 出現之前,憑證撤銷清單(Certificate Revocation List,CRL)是唯一的憑證撤銷檢查機制。以下是兩者的詳細比較:

CRL(憑證撤銷清單)

CRL 是由 CA 定期發布的已撤銷憑證清單。客戶端需要下載整份清單,然後在本地檢查目標憑證是否在清單中。

優點:

  • 可以離線驗證,適合網路不穩定的環境
  • 一次下載可驗證多張憑證
  • 實作相對簡單

缺點:

  • 清單可能很大(大型 CA 的 CRL 可達數 MB)
  • 更新頻率受限(通常每小時或每天更新一次)
  • 存在時間差:憑證撤銷後,客戶端可能要等到下次 CRL 更新才能得知
  • 頻寬消耗大

OCSP(線上憑證狀態協議)

OCSP 採用即時查詢模式,客戶端針對特定憑證發送查詢請求,伺服器即時回應該憑證的狀態。

優點:

  • 即時性高:可在憑證撤銷後立即反映狀態
  • 頻寬效率高:只查詢需要的憑證
  • 回應資料量小(通常只有幾 KB)
  • 支援 OCSP Stapling,可進一步優化效能

缺點:

  • 需要網路連線
  • 對 OCSP Responder 的可用性有依賴
  • 可能有隱私疑慮(CA 可以追蹤使用者瀏覽行為)

選擇建議

情境建議方案
高安全性要求、需即時撤銷OCSP
離線環境或網路不穩定CRL
大規模部署、頻寬有限OCSP + OCSP Stapling
最佳實務同時支援 OCSP 和 CRL(作為備援)

環境準備

安裝 OpenSSL

若您的系統尚未安裝 OpenSSL,請先進行安裝。

CentOS / RHEL:

1
sudo yum install openssl openssl-devel -y

Ubuntu / Debian:

1
2
sudo apt update
sudo apt install openssl libssl-dev -y

驗證安裝:

1
openssl version

確保 OpenSSL 版本至少為 1.1.1 以上,以支援現代的加密演算法。

建立工作目錄

我們將在 /etc/pki/tls 目錄下建立 OCSP 相關的憑證和設定檔。

1
cd /etc/pki/tls

說明/etc/pki/tls 是 Red Hat 系列發行版的標準 PKI 目錄。如果您使用 Debian/Ubuntu,可以改用 /etc/ssl 或自訂目錄。

建立所需的資料夾和檔案

1
2
3
4
mkdir -p demoCA/newcerts
cd demoCA
touch index.txt
echo '01' > serial

各檔案用途說明:

檔案/目錄用途
demoCA/CA 的主要工作目錄
demoCA/newcerts/存放新簽發的憑證副本
index.txtCA 資料庫,記錄所有已簽發憑證的狀態(有效、撤銷等)
serial序號檔案,記錄下一張憑證的序號

index.txt 是 OCSP Responder 判斷憑證狀態的核心資料來源。當憑證被撤銷時,該檔案中對應的記錄會從 V(Valid)變更為 R(Revoked)。

建立設定檔

複製系統預設的 OpenSSL 設定檔並進行修改:

1
cp /etc/pki/tls/openssl.cnf /etc/pki/tls/validation.cnf

編輯 validation.cnf,需要修改以下幾個區段:

設定檔重點說明

[ CA_default ] 區段

這個區段定義了 CA 的基本設定,包括目錄結構和預設參數:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
[ CA_default ]

dir		= /etc/pki/tls		# 主要目錄
certs		= $dir/certs		# 憑證存放目錄
crl_dir		= $dir/crl		# CRL 存放目錄
database	= $dir/demoCA/index.txt	# CA 資料庫檔案
unique_subject	= no			# 允許相同 Subject 的多張憑證
new_certs_dir	= $dir/demoCA/newcerts	# 新憑證存放目錄

certificate	= $dir/cacert.pem 	# CA 憑證
serial		= $dir/demoCA/serial 	# 序號檔案
crlnumber	= $dir/crlnumber	# CRL 序號
crl		= $dir/crl.pem 		# 目前的 CRL
private_key	= $dir/private/cakey.pem # CA 私鑰
RANDFILE	= $dir/private/.rand	# 亂數種子檔案

x509_extensions	= usr_cert		# 憑證擴展設定

name_opt 	= ca_default		# Subject 名稱選項
cert_opt 	= ca_default		# 憑證欄位選項

default_days	= 365			# 預設憑證有效天數
default_crl_days= 30			# CRL 有效天數
default_md	= sha256		# 預設雜湊演算法(建議使用 SHA-256)
preserve	= no			# 不保留傳入的 DN 順序

policy		= policy_match

[ usr_cert ] 區段

這是最關鍵的區段,需要加入 OCSP 相關設定:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
[ usr_cert ]

# 設定 OCSP Responder 的 URL
# 請將 xxx.xxx.xxx.xxx 替換為您的 OCSP 伺服器 IP 或域名
authorityInfoAccess = OCSP;URI:http://xxx.xxx.xxx.xxx:8080

basicConstraints=CA:FALSE

nsComment			= "OpenSSL Generated Certificate"

subjectKeyIdentifier=hash
authorityKeyIdentifier=keyid,issuer

重要authorityInfoAccess 欄位會被嵌入到憑證中,讓客戶端知道要去哪裡查詢 OCSP 狀態。

[ v3_req ][ v3_OCSP ] 區段

這些區段定義了 OCSP 簽署憑證的擴展:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
[ v3_req ]

basicConstraints = CA:FALSE
keyUsage = nonRepudiation, digitalSignature, keyEncipherment
extendedKeyUsage = OCSPSigning

[ v3_OCSP ]
basicConstraints = CA:FALSE
keyUsage = nonRepudiation, digitalSignature, keyEncipherment
extendedKeyUsage = OCSPSigning

完整設定檔範例

完整的 validation.cnf 設定檔請參考本文末尾的參考區段

建立憑證階層架構

安全性考量:金鑰長度建議

在生產環境中,強烈建議使用 2048 位元或更高的金鑰長度。以下是各種情境的建議:

用途最低建議金鑰長度說明
測試環境2048 bits足夠安全且效能良好
生產環境2048 bits目前業界標準
高安全性需求4096 bits提供更長期的安全性
長期有效的 CA 憑證4096 bitsCA 憑證通常有效期較長

警告:1024 位元金鑰已被認為不安全,自 2013 年起已不被主流瀏覽器和作業系統信任。請勿在生產環境中使用。

生成根 CA 的私鑰

1
openssl genrsa -out rootCA.key 4096

參數說明:

  • genrsa:生成 RSA 私鑰
  • -out rootCA.key:輸出檔案名稱
  • 4096:金鑰長度(位元)

進階選項 - 加密私鑰:

建議在生產環境中對私鑰進行加密保護:

1
openssl genrsa -aes256 -out rootCA.key 4096

這會要求您輸入密碼,之後每次使用該私鑰時都需要提供密碼。

根據私鑰生成根 CA 的憑證

1
openssl req -new -x509 -days 3650 -key rootCA.key -out rootCA.crt -config validation.cnf

參數說明:

  • req -new:建立新的憑證請求
  • -x509:直接輸出自簽憑證(而非 CSR)
  • -days 3650:憑證有效期為 10 年
  • -key rootCA.key:使用的私鑰
  • -out rootCA.crt:輸出的憑證檔案
  • -config validation.cnf:使用自訂設定檔

執行時會要求輸入憑證資訊:

1
2
3
4
5
6
7
Country Name (2 letter code) [TW]:
State or Province Name [Taiwan]:
Locality Name [Taipei]:
Organization Name [My Organization]:
Organizational Unit Name [IT Security]:
Common Name [My Root CA]:
Email Address [admin@example.com]:

生成終端實體(End Entity)的私鑰和憑證

這是要被 OCSP 驗證的用戶端憑證:

1
2
3
4
5
# 生成私鑰(建議使用 2048 位元或以上)
openssl genrsa -out certKey.key 2048

# 生成自簽憑證(暫時的,之後會用 CA 重新簽署)
openssl req -new -x509 -days 3650 -key certKey.key -out certificate.crt -config validation.cnf

生成憑證簽名請求(CSR)

將現有的自簽憑證轉換為 CSR,以便用根 CA 進行簽署:

1
openssl x509 -x509toreq -in certificate.crt -out CSR.csr -signkey certKey.key

參數說明:

  • -x509toreq:將 X.509 憑證轉換為 CSR
  • -signkey:用於簽署 CSR 的私鑰

使用根 CA 簽署用戶端憑證

1
openssl ca -batch -startdate 150813080000Z -enddate 250813090000Z -keyfile rootCA.key -cert rootCA.crt -policy policy_anything -config validation.cnf -notext -out certificate.crt -infiles CSR.csr

參數說明:

  • -batch:非互動模式,自動確認
  • -startdate:憑證生效時間(格式:YYMMDDHHMMSSZ)
  • -enddate:憑證到期時間
  • -keyfile:CA 私鑰
  • -cert:CA 憑證
  • -policy policy_anything:使用寬鬆的策略,不強制要求欄位匹配
  • -notext:不在憑證中包含可讀文字
  • -infiles:輸入的 CSR 檔案

執行成功後,index.txt 會新增一筆記錄,格式如下:

1
V	250813090000Z		01	unknown	/C=TW/ST=Taiwan/O=My Org/CN=My Cert

其中 V 表示憑證狀態為有效(Valid)。

啟動 OCSP 伺服器

基本啟動命令

1
openssl ocsp -index demoCA/index.txt -port 8080 -rsigner rootCA.crt -rkey rootCA.key -CA rootCA.crt -text -out log.txt &

參數說明:

參數說明
-indexCA 資料庫檔案,用於查詢憑證狀態
-portOCSP 服務監聽的埠號
-rsigner用於簽署 OCSP 回應的憑證
-rkey用於簽署 OCSP 回應的私鑰
-CACA 憑證,用於驗證請求中的憑證
-text以文字格式輸出詳細資訊
-out日誌輸出檔案
&在背景執行

進階啟動選項

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
openssl ocsp \
  -index demoCA/index.txt \
  -port 8080 \
  -rsigner rootCA.crt \
  -rkey rootCA.key \
  -CA rootCA.crt \
  -text \
  -out /var/log/ocsp/ocsp.log \
  -nmin 60 \
  -ndays 7 \
  -resp_no_certs &

額外參數說明:

  • -nmin 60:OCSP 回應的 nextUpdate 設定為 60 分鐘後
  • -ndays 7:OCSP 回應有效期為 7 天
  • -resp_no_certs:回應中不包含簽署者憑證(減少回應大小)

驗證 OCSP 服務

查詢憑證狀態

1
openssl ocsp -CAfile rootCA.crt -issuer rootCA.crt -cert certificate.crt -url http://xxx.xxx.xxx.xxx:8080 -resp_text -noverify

成功回應範例(憑證有效):

1
2
3
4
Response verify OK
certificate.crt: good
	This Update: Sep 27 08:00:00 2023 GMT
	Next Update: Sep 27 09:00:00 2023 GMT

撤銷後的回應範例:

1
2
3
4
5
Response verify OK
certificate.crt: revoked
	This Update: Sep 27 10:00:00 2023 GMT
	Next Update: Sep 27 11:00:00 2023 GMT
	Revocation Time: Sep 27 09:30:00 2023 GMT

撤銷憑證

要撤銷一張憑證,使用以下命令:

1
openssl ca -revoke certificate.crt -keyfile rootCA.key -cert rootCA.crt -config validation.cnf

執行後,index.txt 中對應的記錄會從 V 變更為 R

1
R	250813090000Z	230927093000Z	01	unknown	/C=TW/ST=Taiwan/O=My Org/CN=My Cert

OCSP Responder 效能優化

在高流量環境中,OCSP Responder 的效能至關重要。以下是一些優化建議:

1. 使用預先產生的回應(OCSP Response Caching)

對於不常變動的憑證,可以預先產生 OCSP 回應並快取:

1
2
3
4
# 產生預簽署的 OCSP 回應
openssl ocsp -issuer rootCA.crt -cert certificate.crt \
  -respout response.der -resp_key_id \
  -rsigner rootCA.crt -rkey rootCA.key

2. 使用反向代理

在 OCSP Responder 前端部署 Nginx 或 HAProxy 進行:

  • 連線管理
  • 請求快取
  • 負載平衡
  • SSL/TLS 終止

Nginx 設定範例:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
upstream ocsp_backend {
    server 127.0.0.1:8080;
    keepalive 32;
}

server {
    listen 80;
    server_name ocsp.example.com;

    location / {
        proxy_pass http://ocsp_backend;
        proxy_http_version 1.1;
        proxy_set_header Connection "";
        proxy_cache ocsp_cache;
        proxy_cache_valid 200 10m;
        proxy_cache_use_stale error timeout;
    }
}

3. 使用獨立的 OCSP 簽署金鑰

不建議直接使用 CA 私鑰簽署 OCSP 回應。應該建立專用的 OCSP 簽署憑證:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
# 生成 OCSP 簽署者私鑰
openssl genrsa -out ocsp-signer.key 2048

# 生成 OCSP 簽署者 CSR
openssl req -new -key ocsp-signer.key -out ocsp-signer.csr \
  -subj "/CN=OCSP Signer/O=My Organization"

# 用 CA 簽署 OCSP 憑證,加入 OCSP Signing 擴展
openssl ca -in ocsp-signer.csr -out ocsp-signer.crt \
  -extensions v3_OCSP -config validation.cnf \
  -keyfile rootCA.key -cert rootCA.crt

然後使用 OCSP 簽署者憑證啟動服務:

1
2
3
openssl ocsp -index demoCA/index.txt -port 8080 \
  -rsigner ocsp-signer.crt -rkey ocsp-signer.key \
  -CA rootCA.crt -text &

4. 硬體加速

對於高流量環境,考慮使用:

  • HSM(硬體安全模組)進行簽署運算
  • 支援 AES-NI 的 CPU 進行加密運算
  • 專用的負載平衡器

使用 systemd 管理 OCSP 服務

在生產環境中,應該使用 systemd 來管理 OCSP 服務,而非簡單的 shell 腳本。

建立 systemd 服務單元檔案

建立 /etc/systemd/system/ocsp-responder.service

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
[Unit]
Description=OpenSSL OCSP Responder
Documentation=man:openssl-ocsp(1)
After=network.target

[Service]
Type=simple
User=ocsp
Group=ocsp
WorkingDirectory=/etc/pki/tls

# 主要執行命令
ExecStart=/usr/bin/openssl ocsp \
    -index /etc/pki/tls/demoCA/index.txt \
    -port 8080 \
    -rsigner /etc/pki/tls/rootCA.crt \
    -rkey /etc/pki/tls/rootCA.key \
    -CA /etc/pki/tls/rootCA.crt \
    -text \
    -out /var/log/ocsp/ocsp.log \
    -nmin 60

# 自動重啟設定
Restart=always
RestartSec=10

# 安全性設定
NoNewPrivileges=yes
ProtectSystem=strict
ProtectHome=yes
ReadOnlyPaths=/etc/pki/tls
ReadWritePaths=/var/log/ocsp

# 資源限制
LimitNOFILE=65535

[Install]
WantedBy=multi-user.target

建立專用使用者和目錄

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
# 建立 OCSP 專用使用者
sudo useradd -r -s /sbin/nologin ocsp

# 建立日誌目錄
sudo mkdir -p /var/log/ocsp
sudo chown ocsp:ocsp /var/log/ocsp

# 設定憑證檔案權限
sudo chown ocsp:ocsp /etc/pki/tls/rootCA.key
sudo chmod 400 /etc/pki/tls/rootCA.key

啟用並啟動服務

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
# 重新載入 systemd 設定
sudo systemctl daemon-reload

# 啟用服務(開機自動啟動)
sudo systemctl enable ocsp-responder

# 啟動服務
sudo systemctl start ocsp-responder

# 檢查服務狀態
sudo systemctl status ocsp-responder

設定日誌輪替

建立 /etc/logrotate.d/ocsp

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
/var/log/ocsp/*.log {
    daily
    rotate 30
    compress
    delaycompress
    missingok
    notifempty
    create 0644 ocsp ocsp
    postrotate
        systemctl reload ocsp-responder 2>/dev/null || true
    endscript
}

故障排除指南

常見問題及解決方案

1. OCSP Responder 無法啟動

症狀: 執行啟動命令後沒有任何回應或立即退出

排查步驟:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
# 檢查埠號是否被占用
netstat -tlnp | grep 8080
# 或
ss -tlnp | grep 8080

# 檢查檔案權限
ls -la /etc/pki/tls/rootCA.key
ls -la /etc/pki/tls/demoCA/index.txt

# 在前景執行以查看錯誤訊息
openssl ocsp -index demoCA/index.txt -port 8080 -rsigner rootCA.crt -rkey rootCA.key -CA rootCA.crt -text

常見原因:

  • 埠號被其他程式占用
  • 私鑰檔案權限不正確
  • index.txt 檔案格式錯誤

2. 客戶端收到 “unauthorized” 回應

症狀: OCSP 查詢返回 unauthorized 狀態

可能原因:

  • 查詢的憑證不是由該 CA 簽發
  • index.txt 中沒有該憑證的記錄
  • OCSP Responder 憑證沒有 OCSP Signing 擴展

解決方案:

1
2
3
4
5
6
7
8
# 確認憑證的簽發者
openssl x509 -in certificate.crt -issuer -noout

# 檢查 index.txt 內容
cat demoCA/index.txt

# 確認 OCSP 簽署者憑證的擴展
openssl x509 -in rootCA.crt -text | grep -A2 "Extended Key Usage"

3. “response signature verification failure”

症狀: 客戶端報告 OCSP 回應簽章驗證失敗

排查步驟:

1
2
3
4
5
6
# 使用 -noverify 暫時跳過驗證,確認基本通訊正常
openssl ocsp -CAfile rootCA.crt -issuer rootCA.crt -cert certificate.crt \
  -url http://localhost:8080 -noverify

# 檢查 CA 憑證鏈是否完整
openssl verify -CAfile rootCA.crt rootCA.crt

4. 連線逾時

症狀: OCSP 查詢超時沒有回應

排查步驟:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
# 確認 OCSP 服務正在執行
pgrep -a openssl

# 確認防火牆設定
sudo iptables -L -n | grep 8080
# 或
sudo firewall-cmd --list-ports

# 測試網路連通性
telnet localhost 8080
# 或
nc -zv localhost 8080

解決方案:

1
2
3
4
5
6
# 開放防火牆埠號(firewalld)
sudo firewall-cmd --permanent --add-port=8080/tcp
sudo firewall-cmd --reload

# 或使用 iptables
sudo iptables -A INPUT -p tcp --dport 8080 -j ACCEPT

5. index.txt 格式錯誤

症狀: OCSP Responder 啟動失敗,提示資料庫錯誤

正確的 index.txt 格式:

每行包含以下欄位(以 Tab 分隔):

  1. 狀態標記(V=有效, R=撤銷, E=過期)
  2. 到期時間(YYMMDDHHMMSSZ 格式)
  3. 撤銷時間(僅撤銷的憑證有此欄位)
  4. 序號(十六進位)
  5. 檔案名稱或 “unknown”
  6. Distinguished Name

範例:

1
2
V	250813090000Z		01	unknown	/C=TW/ST=Taiwan/O=My Org/CN=Test
R	250813090000Z	230927120000Z	02	unknown	/C=TW/ST=Taiwan/O=My Org/CN=Revoked

日誌分析

檢視 OCSP 服務日誌:

1
2
3
4
5
6
7
8
# 查看即時日誌
tail -f /var/log/ocsp/ocsp.log

# 查看 systemd 日誌
journalctl -u ocsp-responder -f

# 搜尋錯誤訊息
grep -i error /var/log/ocsp/ocsp.log

完整 validation.cnf 範例

以下是完整的設定檔內容:

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
[ CA_default ]

dir		= /etc/pki/tls		# Where everything is kept
certs		= $dir/certs		# Where the issued certs are kept
crl_dir		= $dir/crl		# Where the issued crl are kept
database	= $dir/demoCA/index.txt	# database index file.
unique_subject	= no			# Set to 'no' to allow creation of
					# several ctificates with same subject.
new_certs_dir	= $dir/demoCA/newcerts		# default place for new certs.

certificate	= $dir/cacert.pem 	# The CA certificate
serial		= $dir/demoCA/serial 		# The current serial number
crlnumber	= $dir/crlnumber	# the current crl number
					# must be commented out to leave a V1 CRL
crl		= $dir/crl.pem 		# The current CRL
private_key	= $dir/private/cakey.pem# The private key
RANDFILE	= $dir/private/.rand	# private random number file

x509_extensions	= usr_cert		# The extentions to add to the cert

# Comment out the following two lines for the "traditional"
# (and highly broken) format.
name_opt 	= ca_default		# Subject Name options
cert_opt 	= ca_default		# Certificate field options

# Extension copying option: use with caution.
# copy_extensions = copy

# Extensions to add to a CRL. Note: Netscape communicator chokes on V2 CRLs
# so this is commented out by default to leave a V1 CRL.
# crlnumber must also be commented out to leave a V1 CRL.
# crl_extensions	= crl_ext

default_days	= 365			# how long to certify for
default_crl_days= 30			# how long before next CRL
default_md	= sha256		# use SHA-256 by default
preserve	= no			# keep passed DN ordering

# A few difference way of specifying how similar the request should look
# For type CA, the listed attributes must be the same, and the optional
# and supplied fields are just that :-)
policy		= policy_match

# For the CA policy


[ usr_cert ]

# These extensions are added when 'ca' signs a request.

# This goes against PKIX guidelines but some CAs do it and some software
# requires this to avoid interpreting an end user certificate as a CA.

authorityInfoAccess = OCSP;URI:http://xxx.xxx.xxx.xxx:8080

basicConstraints=CA:FALSE

# Here are some examples of the usage of nsCertType. If it is omitted
# the certificate can be used for anything *except* object signing.

# This is OK for an SSL server.
# nsCertType			= server

# For an object signing certificate this would be used.
# nsCertType = objsign

# For normal client use this is typical
# nsCertType = client, email

# and for everything including object signing:
# nsCertType = client, email, objsign

# This is typical in keyUsage for a client certificate.
# keyUsage = nonRepudiation, digitalSignature, keyEncipherment

# This will be displayed in Netscape's comment listbox.
nsComment			= "OpenSSL Generated Certificate"

# PKIX recommendations harmless if included in all certificates.
subjectKeyIdentifier=hash
authorityKeyIdentifier=keyid,issuer

# This stuff is for subjectAltName and issuerAltname.
# Import the email address.
# subjectAltName=email:copy
# An alternative to produce certificates that aren't
# deprecated according to PKIX.
# subjectAltName=email:move

# Copy subject details
# issuerAltName=issuer:copy

#nsCaRevocationUrl		= http://www.domain.dom/ca-crl.pem
#nsBaseUrl
#nsRevocationUrl
#nsRenewalUrl
#nsCaPolicyUrl
#nsSslServerName

# This is required for TSA certificates.
# extendedKeyUsage = critical,timeStamping

[ v3_req ]

basicConstraints = CA:FALSE
keyUsage = nonRepudiation, digitalSignature, keyEncipherment
extendedKeyUsage = OCSPSigning

[ v3_OCSP ]
basicConstraints = CA:FALSE
keyUsage = nonRepudiation, digitalSignature, keyEncipherment
extendedKeyUsage = OCSPSigning

維持 OCSP 服務常駐(傳統方式)

如果您的環境不支援 systemd,可以使用以下 shell 腳本作為替代方案:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
#!/bin/bash

# OCSP 監控腳本
# 檔案名稱:monitor_ocsp.sh

OCSP_PORT=8080
LOG_FILE="/var/log/ocsp/monitor.log"
WORK_DIR="/etc/pki/tls"

log_message() {
    echo "$(date '+%Y-%m-%d %H:%M:%S') - $1" >> "$LOG_FILE"
}

start_ocsp() {
    cd "$WORK_DIR"
    nohup openssl ocsp \
        -index demoCA/index.txt \
        -port $OCSP_PORT \
        -rsigner rootCA.crt \
        -rkey rootCA.key \
        -CA rootCA.crt \
        -text \
        -out /var/log/ocsp/ocsp.log &
    log_message "OCSP Responder started with PID $!"
}

while true; do
    # 檢查 OCSP 程式是否正在執行
    if ! pgrep -f "openssl ocsp.*$OCSP_PORT" > /dev/null; then
        log_message "OCSP Responder not running, attempting to start..."
        start_ocsp
    fi

    # 每 60 秒檢查一次
    sleep 60
done

將以上程式碼存檔為 monitor_ocsp.sh,並執行以下命令:

1
2
3
4
5
# 給予執行權限
chmod +x monitor_ocsp.sh

# 在背景執行
nohup ./monitor_ocsp.sh &

總結

本文詳細介紹了如何使用 OpenSSL 建立 OCSP 伺服器,從基本概念到實際部署都有涵蓋。重點回顧:

  1. OCSP 的重要性:提供即時的憑證狀態查詢,比 CRL 更有效率
  2. 安全性考量:使用 2048 位元以上的金鑰長度,保護私鑰
  3. 生產環境部署:使用 systemd 管理服務,設定適當的權限和日誌輪替
  4. 效能優化:考慮使用反向代理、快取和專用簽署金鑰
  5. 故障排除:掌握常見問題的診斷和解決方法

建議在正式部署前,先在測試環境中進行完整的功能驗證,確保 OCSP 服務能夠正確回應各種憑證狀態查詢。

參考資料

comments powered by Disqus
Built with Hugo
Theme Stack designed by Jimmy