Khắc phục nhanh trong 60 giây
Khi quá trình bắt tay TLS thất bại với lỗi alert unknown ca, bên nhận về cơ bản đang nói rằng: "Tôi thấy chứng chỉ của bạn, nhưng tôi không biết ai đã xác nhận nó." Điều này thường xảy ra khi máy nhận chứng chỉ không nhận diện được Cơ quan chứng thực (Certificate Authority - CA) đã ký chứng chỉ đó.
Bạn có khả năng sẽ gặp lỗi này trong quá trình thiết lập mTLS (Mutual TLS) hoặc khi sử dụng chứng chỉ tự ký cho các API nội bộ.
- Phía client: Truyền gói CA một cách rõ ràng bằng cách sử dụng
--cacerthoặc cài đặt CA vào kho lưu trữ tin cậy (trust store) của hệ thống. - Phía server (mTLS): Kiểm tra xem cấu hình Nginx
ssl_client_certificatehoặc ApacheSSLCACertificateFilecủa bạn có trỏ đến đúng Root CA thực tế đã ký các chứng chỉ người dùng hay không. - Chỉ dùng để kiểm tra: Sử dụng
curl -kđể bỏ qua bước kiểm tra, nhưng tuyệt đối không làm điều này trên môi trường production.
Tại sao kết nối của bạn bị lỗi?
Nếu bạn thấy thông báo lỗi curl: (35) OpenSSL SSL_connect: alert unknown ca, quá trình bắt tay đã gặp bế tắc. Một bên đã gửi một "Cảnh báo nghiêm trọng" (Fatal Alert) cho bên kia. Cụ thể, unknown_ca có nghĩa là chứng chỉ đã được nhận, nhưng chuỗi tin cậy (chain of trust) bị đứt gãy vì Root CA bị thiếu trong kho lưu trữ tin cậy cục bộ.
Trong HTTPS tiêu chuẩn, trình duyệt hoặc curl sẽ xác thực máy chủ. Tuy nhiên, trong thiết lập mTLS—thường thấy ở các API bảo mật cao trên cổng 8443—cả hai bên đều phải xác thực lẫn nhau. Nếu bạn gặp lỗi này khi đang gửi một chứng chỉ client, thì máy chủ chính là bên đang từ chối bạn vì nó không nhận diện được bên phát hành chứng chỉ của bạn.
Các cách khắc phục thực tế cho những tình huống thường gặp
1. Cập nhật kho lưu trữ tin cậy của hệ thống (Linux)
Các công cụ nội bộ thường sử dụng các CA riêng. Nếu máy cục bộ của bạn không tin tưởng CA nội bộ của công ty, bạn phải thêm nó vào một cách thủ công để tránh việc OpenSSL báo lỗi.
Ubuntu/Debian:
# Di chuyển tệp CA của bạn vào thư mục tin cậy
sudo cp internal-ca.crt /usr/local/share/ca-certificates/internal-ca.crt
# Xây dựng lại kho lưu trữ chứng chỉ
sudo update-ca-certificates
CentOS/RHEL 7 & 8:
# Sao chép tệp vào thư mục anchor
sudo cp internal-ca.crt /etc/pki/ca-trust/source/anchors/
# Cập nhật sự tin cậy của hệ thống
sudo update-ca-trust extract
2. Khắc phục cấu hình máy chủ mTLS
Bạn có phải là quản trị viên không? Nếu client của bạn thấy cảnh báo này, máy chủ của bạn có thể đang thiếu gói (bundle) cần thiết để xác minh danh tính của họ. Ngay cả một chứng chỉ client hợp lệ cũng vô dụng nếu máy chủ không có Root CA của bên ký trong hồ sơ.
Cấu hình Nginx:
server {
listen 443 ssl;
ssl_certificate /etc/nginx/certs/server.crt;
ssl_certificate_key /etc/nginx/certs/server.key;
# Quan trọng: Đây phải là CA đã ký các chứng chỉ CLIENT của bạn
ssl_client_certificate /etc/nginx/certs/client-ca.crt;
ssl_verify_client on;
}
Cấu hình Apache:
<VirtualHost *:443>
SSLEngine on
SSLCertificateFile /etc/apache2/ssl/server.crt
SSLCertificateKeyFile /etc/apache2/ssl/server.key
# Trỏ đến CA được phép ký các chứng chỉ client
SSLCACertificateFile /etc/apache2/ssl/client-ca.crt
SSLVerifyClient require
</VirtualHost>
3. Cung cấp trực tiếp gói CA cho Curl
Việc sửa đổi kho lưu trữ trên toàn hệ thống không phải lúc nào cũng khả thi, đặc biệt là trong các đường ống dẫn CI/CD bị khóa chặt. Thay vào đó, hãy trỏ curl trực tiếp đến tệp mà nó cần. Đối với các kết nối tiêu chuẩn, hãy sử dụng:
curl --cacert path/to/ca-bundle.crt https://api.internal.dev
Đối với các kết nối mTLS, bạn cần cung cấp chứng chỉ, khóa riêng (private key) của mình và CA dùng để xác thực máy chủ:
curl --cacert server-ca.crt \
--cert client.crt \
--key client.key \
https://mtls.example.com:8443
Chẩn đoán chuyên sâu với OpenSSL
Đầu ra của Curl có thể mơ hồ. Để thấy chính xác quá trình bắt tay bị dừng ở đâu, hãy sử dụng công cụ s_client. Nó cung cấp một cái nhìn chi tiết về quá trình trao đổi chứng chỉ.
openssl s_client -connect your-server.com:443 -CAfile my-ca.crt
Kiểm tra đầu ra để tìm trạng thái Verification:
Verification: OK: Mọi thứ đang hoạt động hoàn hảo.self signed certificate in certificate chain: Bạn có khả năng đang thiếu Root CA trong kho lưu trữ của mình.unable to get local issuer certificate: Thiếu CA trung gian (Intermediate CA). Bạn cần toàn bộ chuỗi chứng chỉ.
Các sai lầm thường gặp cần tránh
- Lỗ hổng Intermediate: Nhiều người quên rằng các chứng chỉ thường được ký bởi một CA trung gian (Intermediate CA) chứ không phải trực tiếp từ Root. Hãy đảm bảo gói CA của bạn bao gồm toàn bộ chuỗi (Trung gian + Root).
- Vấn đề định dạng: OpenSSL ưu tiên định dạng PEM (Base64). Nếu CA của bạn là tệp nhị phân
.cerhoặc.der, hãy chuyển đổi nó:openssl x509 -inform der -in cert.cer -out cert.pem. - Lỗi quyền truy cập (Permission Denied): Đảm bảo người dùng đang chạy máy chủ web của bạn (như
www-datahoặcnginx) thực sự có quyền đọc các tệp.crtvà.key. Thiết lậpchmod 644cho các chứng chỉ là một lựa chọn an toàn.

