Sửa lỗi chuỗi SSL 'unable to verify the first certificate'

intermediate🔒 SSL/TLS2026-04-20| Nginx, Apache, Node.js, Python, Docker, Ubuntu, CentOS, Android Browsers

Error Message

unable to verify the first certificate — SSL certificate problem: unable to get local issuer certificate
#ssl#nginx#apache#devops#bảo mật

TL;DR: Cách khắc phục nhanh

Bạn gặp lỗi này vì máy chủ web chỉ đang cung cấp chứng chỉ của trang web mà bỏ qua các chứng chỉ trung gian. Trong khi các trình duyệt máy tính hiện đại thường tự xử lý vấn đề này, các công cụ CLI như curl, script Node.js và các trình duyệt Android cũ sẽ thất bại ngay lập tức.

Để khắc phục, hãy gộp chứng chỉ tên miền và chứng chỉ CA trung gian vào một tệp duy nhất:

# Kết hợp chứng chỉ của bạn và gói bundle do CA cung cấp
cat your_domain_cert.crt intermediate.crt > fullchain.pem

Cuối cùng, cập nhật cấu hình máy chủ web để trỏ đến tệp fullchain.pem này thay vì chứng chỉ độc lập.

Tại sao chuỗi chứng chỉ bị đứt gãy

Các tổ chức phát hành chứng chỉ (CAs) như Let's Encrypt, Sectigo, hoặc DigiCert thường không ký trực tiếp chứng chỉ của bạn từ chứng chỉ "Root" gốc. Thay vào đó, họ sử dụng các chứng chỉ trung gian để tạo ra một chuỗi tin cậy. Điều này giúp tăng thêm một lớp bảo mật bằng cách giữ cho chứng chỉ Root luôn ngoại tuyến và an toàn.

Nếu bạn chỉ cài đặt chứng chỉ "leaf" (chứng chỉ tên miền của bạn), chuỗi tin cậy sẽ bị đứt. Các phiên bản Chrome và Firefox trên máy tính sử dụng tính năng gọi là AIA Fetching để tự động tải xuống các chứng chỉ trung gian còn thiếu. Tuy nhiên, openssl, thư viện requests của Python và nhiều ứng dụng di động không làm điều này. Chúng yêu cầu máy chủ phải cung cấp đầy đủ đường dẫn đến Root.

unable to verify the first certificate — SSL certificate problem: unable to get local issuer certificate

Điều này giải thích tại sao trang web của bạn có thể hiển thị hoàn hảo trên MacBook nhưng lại gặp lỗi bên trong một Docker container hoặc trên một điện thoại Android đã dùng 3 năm.

Cấu hình Nginx đúng cách

Nginx yêu cầu toàn bộ chuỗi chứng chỉ phải nằm trong một tệp .pem hoặc .crt duy nhất. Thứ tự ở đây rất quan trọng. Chứng chỉ tên miền của bạn phải xuất hiện đầu tiên, sau đó là các chứng chỉ trung gian.

  • Tạo tệp gộp (bundled file):
cat example_com.crt intermediate.crt > /etc/nginx/ssl/fullchain.pem
  • Cập nhật khối server trong /etc/nginx/sites-available/default:
server {
    listen 443 ssl;
    server_name example.com;

    ssl_certificate /etc/nginx/ssl/fullchain.pem;
    ssl_certificate_key /etc/nginx/ssl/example_com.key;
    
    # ... các cài đặt khác
}
  • Kiểm tra cú pháp và khởi động lại: nginx -t && systemctl reload nginx

Cấu hình Apache

Cấu hình của Apache phụ thuộc vào phiên bản bạn đang dùng. Kể từ phiên bản 2.4.8 (phát hành năm 2013), Apache xử lý chứng chỉ tương tự như Nginx.

Apache hiện đại (2.4.8+)

Sử dụng tệp fullchain.pem mà chúng ta đã tạo trước đó. Nó giúp đơn giản hóa cấu hình đáng kể.

SSLCertificateFile /etc/apache2/ssl/fullchain.pem
SSLCertificateKeyFile /etc/apache2/ssl/example_com.key

Apache cũ (Trước bản 2.4.8)

Bạn phải chỉ định tệp trung gian riêng biệt bằng cách sử dụng chỉ thị SSLCertificateChainFile.

SSLCertificateFile /etc/apache2/ssl/example_com.crt
SSLCertificateKeyFile /etc/apache2/ssl/example_com.key
SSLCertificateChainFile /etc/apache2/ssl/intermediate.crt

Xử lý lỗi Client trong Node.js

Khi ứng dụng Node.js của bạn gọi một API có chuỗi SSL bị hỏng, bạn có thể muốn thiết lập NODE_TLS_REJECT_UNAUTHORIZED = '0'. Đừng làm vậy. Việc vô hiệu hóa bảo mật là một lối tắt nguy hiểm, tạo điều kiện cho các cuộc tấn công man-in-the-middle.

Cách tốt hơn là trỏ Node đến chứng chỉ trung gian cụ thể bằng cách sử dụng biến môi trường:

export NODE_EXTRA_CA_CERTS="/path/to/intermediate.crt"
node app.js

Điều này cho phép Node.js xác minh máy chủ cụ thể mà không làm ảnh hưởng đến toàn bộ lớp bảo mật của bạn.

Kiểm tra các thay đổi

Đừng chỉ dựa vào trình duyệt cá nhân để xác nhận việc sửa lỗi. Hãy sử dụng các công cụ kiểm tra cụ thể độ sâu của chuỗi chứng chỉ.

1. Kiểm tra bằng OpenSSL trong Terminal

Chạy lệnh sau để xem dữ liệu chuỗi thô. Bạn cần thấy độ sâu (depth) là 1 hoặc 2 trong kết quả đầu ra.

openssl s_client -connect example.com:443 -showcerts

Nếu kết quả bao gồm Verify return code: 21, chuỗi của bạn vẫn chưa hoàn chỉnh.

2. Qualys SSL Labs

Để kiểm tra toàn diện, hãy sử dụng SSL Labs Server Test. Nếu chuỗi bị lỗi, bạn sẽ thấy cảnh báo rõ ràng: "Chain issues: Incomplete". Một máy chủ được cấu hình đúng cách sẽ đạt điểm "A".

3. Tại sao lỗi này xảy ra sau khi gia hạn?

Các CA thường xuyên cập nhật chứng chỉ trung gian của họ. Ngay cả khi cấu hình của bạn không thay đổi trong nhiều năm, một chứng chỉ mới được cấp có thể yêu cầu một tệp intermediate.crt khác với tệp bạn đã sử dụng trước đó. Luôn tải xuống gói bundle mới nhất do CA cung cấp trong quá trình gia hạn.

Related Error Notes