TLS mã hoá kết nối và xác thực danh tính bên kia bằng chứng chỉ X.509. Chứng chỉ chỉ có giá trị khi client dựng được một chain of trust từ cert của server lên tới một root CA nằm sẵn trong trust store của client (OS, trình duyệt, ca-certificates, JVM...).
Chain of trust
flowchart TD R["Root CA (self-signed, trong trust store)"] -->|ký| I["Intermediate CA"] I -->|ký| L["Leaf cert: api.example.com"] S[Server] -->|gửi leaf + intermediate| C[Client] C -->|tra root trong trust store| R
- Server phải gửi leaf + intermediate (file
fullchain.pem). Root không cần gửi, client đã có sẵn. - Thiếu intermediate là lỗi kinh điển: trình duyệt đôi khi vẫn chạy (do cache/AIA fetching) nhưng
curl, Python, Go, thiết bị mạng thì báounable to get local issuer certificate. - Root CA nội bộ (lab, gNMI, Vault PKI) phải được thêm vào trust store của từng client.
Thành phần
| Thành phần | Là gì | Ghi chú |
|---|---|---|
| Private key | Khoá bí mật của chủ cert | Không bao giờ rời máy sinh ra nó, quyền 0600 |
| CSR | Certificate Signing Request: public key + subject + SAN, ký bằng private key | Gửi cho CA, không chứa secret |
| Certificate | Public key + danh tính + thời hạn, được CA ký | Định dạng PEM (Base64) hoặc DER (binary) |
| CA | Bên ký cert: public CA (Let's Encrypt, DigiCert) hoặc CA nội bộ | Root CA nên offline, ký qua intermediate |
| SAN | Subject Alternative Name: danh sách DNS/IP mà cert hợp lệ | Client hiện đại chỉ kiểm tra SAN, bỏ qua CN |
| Trust store | Tập root CA client tin | Ubuntu: /etc/ssl/certs/ca-certificates.crt |
| OCSP / CRL | Cơ chế thu hồi cert | Nhiều client không kiểm tra chặt, nên ưu tiên cert ngắn hạn |
Định dạng file hay gặp
| Đuôi | Nội dung | Dùng ở đâu |
|---|---|---|
.pem, .crt |
Cert dạng Base64 có header BEGIN CERTIFICATE |
Nginx, HAProxy, Linux |
.key |
Private key PEM | Đi kèm cert |
.der, .cer |
Cert dạng binary | Windows, Java cũ |
.p12, .pfx |
PKCS#12: cert + key + chain trong 1 file, có passphrase | Windows, Java keystore, import thiết bị |
.csr |
CSR dạng PEM | Gửi CA |
TLS handshake (TLS 1.3, rút gọn)
sequenceDiagram participant C as Client participant S as Server C->>S: ClientHello (SNI, cipher suites, key share) S->>C: ServerHello + Certificate + CertificateVerify + Finished C->>C: Kiểm tra chain, thời hạn, SAN khớp SNI C->>S: Finished C->>S: Dữ liệu ứng dụng (mã hoá)
SNI cho phép một IP phục vụ nhiều domain: client gửi tên host trong ClientHello, server chọn cert tương ứng. Kết nối bằng IP trần hoặc client cũ không gửi SNI sẽ nhận cert mặc định, dẫn tới lỗi SAN không khớp.
mTLS
Trong mutual TLS, server cũng yêu cầu client gửi cert (CertificateRequest) và kiểm tra nó với một CA mà server tin. Dùng cho:
- gNMI/gRPC giữa collector và router, API nội bộ giữa service, agent ↔ controller.
- Thay thế API key tĩnh: danh tính gắn với cert ngắn hạn, thu hồi bằng cách không cấp lại.
| TLS thường | mTLS | |
|---|---|---|
| Server có cert | Có | Có |
| Client có cert | Không | Có, do CA nội bộ cấp |
| Xác thực client | Mật khẩu/token ở tầng ứng dụng | Ngay trong handshake |
| Vận hành | Đơn giản | Cần quy trình cấp/xoay vòng cert client |
Khi nào dùng gì
- Website/API public: cert từ Let's Encrypt, tự động gia hạn. Xem Let's Encrypt với certbot.
- Dịch vụ nội bộ, lab, thiết bị mạng: CA nội bộ (Vault PKI, step-ca, hoặc
opensslcho lab nhỏ). Phân phối root CA vào trust store. - Service-to-service, telemetry gNMI: mTLS với cert ngắn hạn.
- Thao tác cụ thể với file cert/key: OpenSSL cheatsheet. Lỗi handshake: TLS troubleshooting.