Nginx开启OCSP

修订:2025-09-14

2025-08-6 Let’s Encrypt 彻底关闭OCSP OCSP已成过去式,该教程已成过去式

国内证书和国外证书区别在于OCSP地址不同,国外OCSP延迟太大会导致用户访问HTTPS加载缓慢 对于国外证书很有必要 下图介绍开启和未开启区别

但这种又存在另一个问题 开启OSCP会在内存保存10分钟,过期后需要从远程服务器获取,下面以 2个证书品牌 为例 解决过期问题。

把 中间证书 域名证书 保存到本地

R10.crt 中间证书
erw.cc.crt 域名证书

Web使用OpenResty属于Nginx的衍生版本 如原版Nginx 请自行修改

新建一个chain.crt 把 域名证书和中间证书内容保存到 chain.crt openssl请求测试

openssl ocsp -CAfile /usr/local/openresty/nginx/conf/chain.crt -issuer /usr/local/openresty/nginx/conf/R10.crt -cert /usr/local/openresty/nginx/conf/erw.crt -no_nonce -text -url http://r10.o.lencr.org

效果如下

[root@VM-24-15-centos home]# openssl ocsp -CAfile /usr/local/openresty/nginx/conf/chain.crt -issuer /usr/local/openresty/nginx/conf/R10.crt -cert /usr/local/openresty/nginx/conf/erw.crt -no_nonce -text -url http://r10.o.lencr.org
OCSP Request Data:
    Version: 1 (0x0)
    Requestor List:
        Certificate ID:
          Hash Algorithm: sha1
          Issuer Name Hash: 690FE41567ED6F7
          Issuer Key Hash: 74A476291718548
          Serial Number: 0466DCF9B1EA1BF0
OCSP Response Data:
    OCSP Response Status: successful (0x0)
    Response Type: Basic OCSP Response
    Version: 1 (0x0)
    Responder Id: C = US, O = Let's Encrypt, CN = R10
    Produced At: Feb 11 03:40:00 2025 GMT
    Responses:
    Certificate ID:
      Hash Algorithm: sha1
      Issuer Name Hash: 690FE41567ED6F7F
      Issuer Key Hash: 74A476291718548
      Serial Number: 0466DCF9B1EA1BF0F
    Cert Status: good
    This Update: Feb 11 03:40:00 2025 GMT
    Next Update: Feb 18 03:39:58 2025 GMT

    Signature Algorithm: sha256WithRSAEncryption
    Signature Value:
        c3:e7:d0:a6:0e:a7:35:ca:ac:b3:64:1f:a7:1b:d5:0a:9b:cb:
        20:a6:af:f1:7d:65:83:da:e1:6c:9b:32:03:e1:09:65:74:34:
        62:96:37:e3:7f:17:a2:e0:d0:87:ad:48:74:ae:73:67:e2:58:
        59:f2:21:15:13:fc:e8:0b:c9:48:40:bb:32:95:1e:3a:fc:02:
        7d:c5:ca:99:e5:a2:03:34:6a:89:26:c0:bf:02:6b:2a:09:45:
        58:35:c9:45
Response verify OK
/usr/local/openresty/nginx/conf/erw.crt: good
        This Update: Feb 11 03:40:00 2025 GMT
        Next Update: Feb 18 03:39:58 2025 GMT

编写python 保存OCSP到文件以便OpenResty加载 (路径可能和你的不一样,请自行修改)

mkdir -p /usr/local/openresty/nginx/conf/oscp
import subprocess, time
from datetime import datetime

CAfile = '/usr/local/openresty/nginx/conf/chain.crt'
issuer = '/usr/local/openresty/nginx/conf/R10.crt'
cert = '/usr/local/openresty/nginx/conf/erw.crt'
url = 'http://r10.o.lencr.org'
respout = '/usr/local/openresty/nginx/conf/oscp/ocsp_response.der'

log_file = '/home/wwwlogs/oscp.log'
max_retries = 3
retry_delay = 5
count = 0
success = False
while count < max_retries:
    command = [
        'openssl', 'ocsp', 
        '-CAfile', CAfile, 
        '-issuer', issuer, 
        '-cert', cert, 
        '-no_nonce', 
        '-text', 
        '-url', url, 
        '-respout', respout
    ]
    
    try:
        subprocess.run(command, check=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
        subprocess.run(['service', 'nginx', 'restart'], check=True)
        with open(log_file, 'a') as log:
            log.write(f"[{datetime.now().strftime('%Y-%m-%d')}] OCSP response generated successfully. Nginx restarted.\n")
        
        success = True
        break
    except subprocess.CalledProcessError:
        count += 1
        with open(log_file, 'a') as log:
            log.write(f"[{datetime.now().strftime('%Y-%m-%d')}] Attempt {count} failed. Retrying...\n")
        time.sleep(retry_delay)
if not success:
    with open(log_file, 'a') as log:
        log.write(f"[{datetime.now().strftime('%Y-%m-%d')}] Failed to generate OCSP response after {max_retries} attempts.\n")
    raise Exception(f"Failed to generate OCSP response after {max_retries} attempts.")

执行python后 Nginx配置增加如下

ssl_stapling on;
ssl_stapling_verify on;
ssl_stapling_file /usr/local/openresty/nginx/conf/oscp/ocsp_response.der;

重启Nginx 测试是否成功

systemctl restart nginx
openssl s_client -connect erw.cc:443 -servername erw.cc -status -tlsextdebug < /dev/null 2>&1 | grep -i "OCSP response"
[root@VM-24-15-centos home]# openssl s_client -connect erw.cc:443 -servername erw.cc -status -tlsextdebug < /dev/null 2>&1 | grep -i "OCSP response"
OCSP response: 
OCSP Response Data:
    OCSP Response Status: successful (0x0)
    Response Type: Basic OCSP Response

OCSP证书默认7天过期需在过期前请求保存可以使用系统自带的定时任务6天执行一次

crontab -e

增加如下命令 (国外和国内有时间差 推荐设置为北京时间的白天)

20 14 */6 * * /usr/bin/python3 /home/oscp.py

方法和上面类似 新建chain.pem 把 中间证书 根证书 合成一个chain.pem(先中间证书在根证书顺序不能乱否则失败)

openssl ocsp -issuer /usr/local/openresty/nginx/conf/chain.pem -cert /usr/local/openresty/nginx/conf/erw.cc_bundle.crt -url http://subca.ocsp-certum.com -respout /usr/local/openresty/nginx/conf/oscp/ocsp_response.der

输出内容为 Response verify OK 代表成功 Python代码如下

import subprocess, time
from datetime import datetime

issuer = '/usr/local/openresty/nginx/conf/chain.pem'
cert = '/usr/local/openresty/nginx/conf/erw.cc_bundle.crt'
url = 'http://subca.ocsp-certum.com'
respout = '/usr/local/openresty/nginx/conf/oscp/ocsp_response.der'

max_retries = 3
retry_delay = 5
log_file = '/home/wwwlogs/oscp.log'
count = 0
while count < max_retries:
    command = [
        'openssl', 'ocsp', 
        '-issuer', issuer, 
        '-cert', cert, 
        '-url', url, 
        '-respout', respout
    ]
    
    try:
        subprocess.run(command, check=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
        subprocess.run(['service', 'nginx', 'restart'], check=True)
        with open(log_file, 'a') as log:
            log.write(f"[{datetime.now().strftime('%Y-%m-%d')}] OCSP response generated successfully. Nginx restarted.\n")
        break
    except subprocess.CalledProcessError:
        count += 1
        time.sleep(retry_delay)
if count == max_retries:
    with open(log_file, 'a') as log:
        log.write(f"[{datetime.now().strftime('%Y-%m-%d')}] Failed to generate OCSP response after {max_retries} attempts.\n")
    raise Exception(f"Failed to generate OCSP response after {max_retries} attempts.")

还是一样7天过期时间 需在过期前从新获取一次OCSP 定时任务 Nginx 与上面一样不在重复写了 第三方验证是否装订成功

https://myssl.com

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注