Fix OCSP Stapling Failed: OCSP response has expired / ssl_stapling unauthorized (Nginx & Apache)

intermediate🔒 SSL/TLS2026-03-23| Nginx 1.14+, Apache 2.4+, Ubuntu 20.04/22.04, Debian 11/12, CentOS 7/8, Let's Encrypt / chứng chỉ SSL thương mại

Error Message

OCSP response has expired — ssl_stapling: OCSP response not successful (6: unauthorized)
#ssl#ocsp#stapling#nginx#apache

Chuyện gì đang xảy ra

Trong quá trình TLS handshake, máy chủ của bạn cố gửi sẵn một phản hồi OCSP đã được tải trước đến các client — đó chính là OCSP stapling. Vấn đề ở đây: phản hồi được lưu trong bộ nhớ cache đã hết hạn, hoặc OCSP responder trả về lỗi khi máy chủ cố tải phản hồi mới. Các client hoặc từ chối kết nối ngay lập tức, hoặc tự tải trạng thái OCSP, gây tăng độ trễ.

Hai dòng log dẫn bạn đến đây:

ssl_stapling: OCSP response not successful (6: unauthorized)
OCSP response has expired

Mã lỗi 6: unauthorized nghĩa là OCSP responder từ chối yêu cầu. Điều này thường xảy ra vì một trong ba lý do: yêu cầu bị sai định dạng, máy chủ của bạn truy vấn sai endpoint của CA, hoặc extension AIA (Authority Information Access) trong chứng chỉ trỏ đến một responder mà máy chủ không thể kết nối tới.

Chuẩn đoán nhanh

Chạy lệnh này từ bất kỳ máy nào có OpenSSL để xem client thực sự nhận được gì:

# Kiểm tra OCSP stapling từ phía client
openssl s_client -connect yourdomain.com:443 -status 2>/dev/null | grep -A 10 'OCSP response'

Một staple hoạt động đúng trông như thế này:

OCSP Response Status: successful (0x0)
Cert Status: good

Stapling bị lỗi sẽ hiển thị no response sent hoặc unauthorized. Kiểm tra log tiếp theo:

# Nginx
tail -n 100 /var/log/nginx/error.log | grep -i ocsp

# Apache
tail -n 100 /var/log/apache2/error.log | grep -i ocsp

Cách sửa 1: Xóa bộ nhớ cache OCSP cũ

Nginx lưu cache phản hồi OCSP trong bộ nhớ RAM, không phải trên đĩa. Khi phản hồi đã cache hết hạn mà máy chủ không thể làm mới, mọi TLS handshake mới đều gặp lỗi này. Reload sẽ xóa cache trong bộ nhớ và buộc tải lại phản hồi mới vào lần yêu cầu tiếp theo:

sudo nginx -t && sudo systemctl reload nginx

Với Apache:

sudo apachectl configtest && sudo systemctl reload apache2

Nếu lỗi biến mất sau khi reload nhưng quay lại trong vòng 24–48 giờ, cache không phải nguyên nhân gốc rễ — máy chủ của bạn không thể kết nối đến OCSP responder để tự động làm mới. Chuyển sang Cách sửa 2.

Cách sửa 2: Kiểm tra kết nối đến OCSP responder

Lấy URL OCSP trực tiếp từ chứng chỉ của bạn:

openssl x509 -in /path/to/your/cert.pem -noout -text | grep -A 3 'Authority Information'

Ví dụ đầu ra với chứng chỉ Let's Encrypt:

Authority Information Access:
    OCSP - URI:http://r10.o.lencr.org
    CA Issuers - URI:http://r10.i.lencr.org/

Bây giờ kiểm tra kết nối từ máy chủ của bạn:

curl -v http://r10.o.lencr.org

Nếu bị timeout, OCSP responder đang bị chặn ở tầng mạng. OCSP chạy qua HTTP thông thường trên cổng 80 — nhiều quy tắc firewall quên cho phép HTTP outbound từ chính máy chủ web. Mở nó ra:

# iptables
sudo iptables -A OUTPUT -p tcp --dport 80 -j ACCEPT

# ufw
sudo ufw allow out 80/tcp

Đứng sau proxy công ty? Đặt http_proxy trong môi trường trước khi khởi động Nginx hoặc Apache, hoặc dùng resolver có thể kết nối đến CA (xem Cách sửa 4).

Cách sửa 3: Xác minh chuỗi chứng chỉ đầy đủ

Chín trên mười trường hợp, lỗi ssl_stapling: OCSP response not successful (6: unauthorized) là do thiếu chứng chỉ trung gian. OCSP stapling yêu cầu chuỗi chứng chỉ đầy đủ — máy chủ cần nó để xác minh phản hồi đã staple trước khi gửi cho client.

Với Nginx

Trỏ ssl_certificate vào file fullchain, không chỉ chứng chỉ domain của bạn. Sau đó thêm ssl_trusted_certificate — nếu thiếu, Nginx không thể xác thực phản hồi OCSP nhận được từ CA:

server {
    listen 443 ssl;
    ssl_certificate /etc/letsencrypt/live/yourdomain.com/fullchain.pem;  # bao gồm intermediate
    ssl_certificate_key /etc/letsencrypt/live/yourdomain.com/privkey.pem;
    ssl_trusted_certificate /etc/letsencrypt/live/yourdomain.com/chain.pem;  # bắt buộc cho stapling

    ssl_stapling on;
    ssl_stapling_verify on;
    resolver 1.1.1.1 8.8.8.8 valid=300s;
    resolver_timeout 5s;
}

Với Apache

<VirtualHost *:443>
    SSLEngine on
    SSLCertificateFile /etc/letsencrypt/live/yourdomain.com/cert.pem
    SSLCertificateKeyFile /etc/letsencrypt/live/yourdomain.com/privkey.pem
    SSLCertificateChainFile /etc/letsencrypt/live/yourdomain.com/chain.pem

    SSLUseStapling on
</VirtualHost>

# Bên ngoài khối VirtualHost, trong cấu hình chính hoặc ssl.conf:
SSLStaplingCache shmcb:/tmp/stapling_cache(128000)

Reload sau mỗi lần thay đổi cấu hình:

sudo nginx -t && sudo systemctl reload nginx
# hoặc
sudo apachectl configtest && sudo systemctl reload apache2

Cách sửa 4: Thêm DNS resolver cho Nginx

Nginx không thể staple phản hồi OCSP nếu không phân giải được hostname của responder. Không có chỉ thị resolver đồng nghĩa với thất bại âm thầm — không có lỗi, không có staple. Thêm nó vào khối http (không chỉ server):

http {
    resolver 1.1.1.1 8.8.8.8 valid=300s;
    resolver_timeout 10s;
    # ... phần cấu hình còn lại
}

Reload Nginx sau khi thêm. Giá trị resolver_timeout là 10s khá an toàn — trên mạng nhanh, 5s thường là đủ.

Cách sửa 5: Tải trước phản hồi OCSP bằng cron job

Responder kết nối được, nhưng thời điểm gia hạn chứng chỉ tạo ra khoảng trống? Tải trước phản hồi theo lịch để Nginx luôn có sẵn staple mới:

#!/bin/bash
# /usr/local/bin/refresh-ocsp.sh

CERT=/etc/letsencrypt/live/yourdomain.com/cert.pem
CHAIN=/etc/letsencrypt/live/yourdomain.com/chain.pem
OCSP_URL=$(openssl x509 -in $CERT -noout -ocsp_uri)

openssl ocsp \
  -issuer $CHAIN \
  -cert $CERT \
  -url $OCSP_URL \
  -respout /tmp/ocsp.der \
  -no_nonce 2>&1

echo "Đã làm mới OCSP lúc $(date)"

Lên lịch chạy mỗi 12 giờ — phản hồi OCSP của Let's Encrypt có hiệu lực 7 ngày, nhưng làm mới thường xuyên giúp bạn luôn nằm trong khoảng thời gian an toàn:

0 */12 * * * /usr/local/bin/refresh-ocsp.sh >> /var/log/ocsp-refresh.log 2>&1

Xác minh sau khi sửa

Sau khi reload, chạy lại kiểm tra OpenSSL:

openssl s_client -connect yourdomain.com:443 -status 2>/dev/null | grep -A 10 'OCSP Response'

Bạn muốn thấy kết quả này:

OCSP Response Status: successful (0x0)
This Update: Mar 23 10:00:00 2026 GMT
Next Update: Mar 30 10:00:00 2026 GMT
Cert Status: good

SSL Labs cũng báo cáo trạng thái OCSP stapling — submit domain của bạn và tìm OCSP Stapling: Yes trong kết quả.

Vẫn thấy lỗi trong log Nginx ngay sau khi reload? Hãy đợi 60–90 giây. Nginx tải phản hồi OCSP bất đồng bộ vào lần yêu cầu đầu tiên sau reload, nên một vài kết nối đầu tiên có thể đến trước khi staple sẵn sàng.

Related Error Notes