1. Thiết lập Certificate Authority (CA) nội bộ
Tạo thư mục làm việc và cấu trúc CA
Tạo một thư mục riêng biệt để chứa toàn bộ các file liên quan đến chứng chỉ và khóa riêng tư. Việc phân vùng rõ ràng giúp quản lý vòng đời chứng chỉ dễ dàng hơn.
Thực hiện lệnh tạo thư mục và chuyển vào thư mục đó:
mkdir -p ~/mtls-ca && cd ~/mtls-ca
Kết quả mong đợi: Bạn đang ở trong thư mục ~/mtls-ca trên máy chủ hoặc máy phát triển.
Tạo khóa riêng và chứng chỉ gốc (Root CA)
Để xây dựng hệ thống mTLS, bạn cần một CA nội bộ để ký cho chứng chỉ Server của Kong và chứng chỉ Client của người dùng. Chúng ta sẽ tạo một Root CA tự ký (Self-signed) để mục đích demo và testing.
Đầu tiên, tạo khóa riêng (Private Key) cho CA:
openssl genrsa -out ca.key 4096
Kết quả mong đợi: File ca.key được tạo ra với độ dài 4096 bit.
Tiếp theo, tạo chứng chỉ CA dựa trên khóa riêng vừa tạo. Thời hạn hiệu lực đặt là 10 năm (3650 ngày):
openssl req -x509 -new -nodes -key ca.key -sha256 -days 3650 -out ca.crt -subj "/C=VN/ST=Hanoi/L=Hanoi/O=TechDept/CN=Internal-CA"
Kết quả mong đợi: File ca.crt được tạo ra, đây là chứng chỉ gốc mà mọi bên tin cậy.
Verify Root CA
Để đảm bảo chứng chỉ CA đã được tạo đúng thông tin, kiểm tra nội dung của nó:
openssl x509 -in ca.crt -text -noout | grep -A 2 "Subject:"
Kết quả mong đợi: Bạn thấy dòng "Subject: C = VN, ST = Hanoi, L = Hanoi, O = TechDept, CN = Internal-CA".
2. Tạo chứng chỉ Server cho Kong Gateway
Tạo CSR (Certificate Signing Request) cho Server
Kong Gateway cần một chứng chỉ Server để thiết lập kết nối TLS với Client. Chúng ta sẽ tạo một CSR với Common Name (CN) là tên domain hoặc FQDN của Gateway (ví dụ: kong-gateway.example.com).
Tạo khóa riêng cho Server:
openssl genrsa -out kong-server.key 2048
Kết quả mong đợi: File kong-server.key được tạo.
Tạo file cấu hình OpenSSL để hỗ trợ Subject Alternative Name (SAN), vì trình duyệt và client hiện đại yêu cầu SAN cho tên domain:
cat > kong-server.cnf
Kết quả mong đợi: File kong-server.cnf được tạo thành công.
Tạo CSR dựa trên file cấu hình vừa tạo:
openssl req -new -key kong-server.key -out kong-server.csr -config kong-server.cnf
Kết quả mong đợi: File kong-server.csr được tạo.
Ký chứng chỉ Server bằng CA
Bây giờ dùng Root CA để ký cho CSR của Server, tạo ra chứng chỉ Server hợp lệ trong hệ sinh thái nội bộ của bạn.
Thực hiện lệnh ký chứng chỉ (thời hạn 365 ngày):
openssl x509 -req -in kong-server.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out kong-server.crt -days 365 -sha256 -extfile kong-server.cnf -extensions v3_req
Kết quả mong đợi: File kong-server.crt được tạo, đây là chứng chỉ công khai của Gateway.
Verify Server Certificate
Đảm bảo chứng chỉ Server đã được ký bởi CA và có đúng tên domain:
openssl verify -CAfile ca.crt kong-server.crt
Kết quả mong đợi: Dòng "kong-server.crt: OK".
3. Cấu hình Secret trong Kubernetes
Tạo Secret chứa chứng chỉ Server
Kong trên Kubernetes cần truy cập chứng chỉ thông qua Kubernetes Secret. Secret này sẽ chứa cả file .crt và .key của server.
Giả sử bạn đang ở thư mục ~/mtls-ca, tạo Secret có tên "kong-mtls-server-tls" trong namespace "kong":
kubectl create secret tls kong-mtls-server-tls --cert=kong-server.crt --key=kong-server.key --namespace=kong
Kết quả mong đợi: Dòng "secret/kong-mtls-server-tls created".
Tạo Secret chứa CA Root (dùng để verify Client)
Để Kong có thể xác thực chứng chỉ của Client (mTLS), Gateway cần biết chứng chỉ gốc (CA) nào là đáng tin cậy. Chúng ta tạo một Secret loại "Opaque" chứa file ca.crt.
Tạo Secret chứa CA root:
kubectl create secret generic kong-ca-root --from-file=ca.crt=ca.crt --namespace=kong
Kết quả mong đợi: Dòng "secret/kong-ca-root created".
Verify Secrets
Liệt kê các secret đã tạo để đảm bảo chúng tồn tại và có đúng kích thước (có dữ liệu):
kubectl get secrets -n kong | grep -E "kong-mtls-server-tls|kong-ca-root"
Kết quả mong đợi: Hai secret xuất hiện trong danh sách với TYPE tương ứng (kubernetes.io/tls và Opaque).
4. Cấu hình Kong yêu cầu mTLS
Cấu hình ConfigMap cho mTLS
Để kích hoạt mTLS, chúng ta cần cấu hình Kong để nó sử dụng Secret chứa chứng chỉ Server cho listener, và yêu cầu Client phải cung cấp chứng chỉ được ký bởi CA trong Secret kia.
Tạo hoặc cập nhật file ConfigMap có tên "kong-config" trong namespace "kong". Nội dung dưới đây cấu hình listener ở cổng 443, sử dụng secret server-tls, và bật client certificate verification.
Lưu ý: Bạn cần mount Secret "kong-ca-root" vào Pod Kong ở đường dẫn `/etc/kong/certs/ca.crt` để Kong đọc được file CA.
Tạo file YAML `kong-mtls-configmap.yaml`:
cat > kong-mtls-configmap.yaml
Kết quả mong đợi: File YAML được tạo.
Áp dụng ConfigMap vào cluster:
kubectl apply -f kong-mtls-configmap.yaml
Kết quả mong đợi: Dòng "configmap/kong-config configured" hoặc "created".
Cập nhật Deployment Kong để mount Secret
ConfigMap chỉ chứa các biến môi trường. Để Kong đọc được file chứng chỉ vật lý, chúng ta phải mount các Secret đã tạo vào Pod của Kong tại các đường dẫn tương ứng với biến trong ConfigMap.
Bạn cần chỉnh sửa Deployment của Kong (giả sử tên là `kong`). Dưới đây là đoạn YAML mẫu để thêm volume mounts. Lưu ý: Nếu bạn dùng Helm, hãy cấu hình trong values.yaml thay vì edit trực tiếp.
Tạo file `kong-deployment-patch.yaml` để apply patch vào deployment hiện tại:
cat > kong-deployment-patch.yaml
Kết quả mong đợi: File patch được tạo.
Áp dụng patch để cập nhật Deployment:
kubectl apply -f kong-deployment-patch.yaml
Kết quả mong đợi: Deployment được cập nhật. Pod Kong sẽ tự động restart để load cấu hình mới.
Khởi động lại Pod Kong
Đảm bảo Pod đã restart để áp dụng các volume mounts và biến môi trường mới.
kubectl rollout restart deployment kong -n kong
Kết quả mong đợi: Dòng "deployment.apps/kong restarted".
5. Verify kết quả mTLS
Kiểm tra trạng thái Pod
Đợi Pod hoàn tất khởi động (Running) và kiểm tra log để đảm bảo không có lỗi khi load chứng chỉ.
kubectl logs -n kong -l app=kong --tail=50
Kết quả mong đợi: Log hiện thông báo "listening on 0.0.0.0:8443" và không có lỗi "SSL_CTX_use_certificate_chain_file failed" hoặc "error loading certificate".
Test kết nối mTLS thành công
Tạo một chứng chỉ Client mẫu để test. Đầu tiên tạo khóa và CSR cho client:
cd ~/mtls-ca && openssl genrsa -out client.key 2048 && openssl req -new -key client.key -out client.csr -subj "/CN=test-client"
Tiếp theo, ký chứng chỉ Client bằng CA Root:
openssl x509 -req -in client.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out client.crt -days 365 -sha256
Thử kết nối vào Gateway (giả sử bạn đã expose Service Kong ra ngoài, ví dụ qua NodePort hoặc LoadBalancer, ở đây dùng curl test local nếu bạn đã port-forward):
curl --cacert ca.crt --cert client.crt --key client.key https://kong-gateway.example.com:8443
Kết quả mong đợi: Nếu cấu hình đúng, bạn nhận được phản hồi HTTP 200 (hoặc 404 nếu chưa có route, nhưng không bị lỗi SSL). Quan trọng là kết nối TLS được thiết lập thành công.
Test kết nối bị từ chối (Client không có chứng chỉ)
Thử kết nối mà không cung cấp chứng chỉ Client để đảm bảo Kong đang từ chối các kết nối không an toàn.
curl --cacert ca.crt https://kong-gateway.example.com:8443
Kết quả mong đợi: Lỗi "SSL certificate problem: certificate required" hoặc kết nối bị cắt đứt ngay lập tức (Connection closed by foreign host). Điều này xác nhận mTLS đang hoạt động đúng yêu cầu.
Điều hướng series:
Mục lục: Series: Xây dựng nền tảng Secure API Gateway với Kong, OPA và mTLS trên Kubernetes
« Phần 2: Triển khai Kong Gateway trên Kubernetes
Phần 4: Triển khai và tích hợp OPA (Open Policy Agent) »