[Microservices Series] Bài 11: Bảo mật nội bộ – Đừng ngây thơ tin tưởng "người nhà" (Zero Trust)
Chào anh em, mình đây! Ở các bài trước, chúng ta đã chia nhỏ hệ thống, dựng API Gateway làm bảo vệ cổng, và có Service Discovery để dò đường. Nhìn bề ngoài, pháo đài Microservices có vẻ đã bất khả xâm phạm.
Nhưng thực tế, rất nhiều hệ thống Microservices đang mắc phải một tử huyệt chết người: Bảo mật bên ngoài thì chặt, nhưng bên trong thì lỏng lẻo. Khi bạn mặc định rằng "các service nằm chung một mạng LAN (Private Network) nên chúng có thể thoải mái gọi nhau mà không cần xác thực", đó là lúc thảm họa chực chờ.
Hôm nay, chúng ta sẽ mổ xẻ triết lý Zero Trust (Không tin tưởng ai) trong thế giới Microservices.
1. Sự ngây thơ mang tên "Mạng nội bộ thì an toàn"
Trong kiến trúc cơ bản, API Gateway đứng ở ngoài cùng chặn user. Nó giải mã JWT Token, bóc lấy User_ID, rồi nhét vào Header gửi xuống cho Service Bán Vé. Service Bán Vé tin tưởng 100% cái Header đó và xuất vé.
Nghe có vẻ ổn, cho đến khi:
-
Một bạn Dev vô tình mở hớ một port của Service Bán Vé ra public (hoặc bị lỗ hổng SSRF).
-
Hacker lọt qua được một khe hẹp vào mạng nội bộ, dùng Postman bắn thẳng một request HTTP có chứa
X-User-Id: 1vào trực tiếp IP của Service Bán Vé (bỏ qua API Gateway). -
Service Bán Vé ngây thơ tin rằng đây là request hợp lệ. Bùm! Toàn bộ vé bị xuất khống.
Zero Trust ra đời để giải quyết bài toán này: Ngay cả khi Service A và Service B nằm chung một nhà, chúng vẫn phải trình giấy tờ tùy thân khi nói chuyện với nhau.
2. Các chiến thuật "phòng thủ" nội bộ
Để các service xác thực lẫn nhau (Machine-to-Machine Authentication), chúng ta có 2 vũ khí phổ biến:
Chiến thuật 1: Internal API Keys (Nhanh, gọn, lẹ) Mỗi service được cấp một mã Key bí mật. Khi Service A (Go) gọi Service B (Laravel), nó phải đính kèm Header X-Internal-Key: abcdxyz.
-
Điểm cộng: Dễ cài đặt, code lẹ, cực kỳ phù hợp cho các dự án cỡ vừa và nhỏ.
-
Điểm trừ: Lộ key là toang. Quản lý key thủ công cho 50 cái service sẽ rất mệt mỏi.
Chiến thuật 2: mTLS (Mutual TLS) qua Service Mesh Đây là "trùm cuối" của bảo mật nội bộ. Thay vì để các Dev phải tự viết code check API Key, hệ thống hạ tầng (như Istio hoặc Linkerd trên Kubernetes) sẽ tự động bọc mọi giao tiếp HTTP/gRPC bằng chứng chỉ số SSL/TLS hai chiều.
-
Cách hoạt động: Service A muốn gọi B, hạ tầng mạng sẽ tự mã hóa toàn bộ dữ liệu. B nhận được, kiểm tra đúng chứng chỉ (Certificate) của A thì mới cho qua. Cả A và B đều không cần viết thêm một dòng code bảo mật nào.
-
Điểm cộng: Bảo mật tuyệt đối, chống luôn cả việc ai đó bắt gói tin (sniffing) trong mạng LAN.
3. Thực chiến bảo mật tại hệ thống AFC
Trong hệ thống điều hành Metro Line 1, tính toàn vẹn của dữ liệu quẹt thẻ và thanh toán là sống còn. Mình không thể để một lỗ hổng nội bộ nào có cơ hội làm sai lệch dữ liệu vé.
Với các cụm service lõi (Core Services), mình áp dụng mô hình lai:
-
Giao tiếp từ Gateway xuống: Mình dùng cơ chế ký chữ ký số (HMAC) trên Payload. Khi Gateway ném request xuống các Service viết bằng Go hoặc Laravel, các service này luôn dùng một
Secret_Keychung để verify lại chữ ký xem request đó có thực sự phát ra từ Gateway không. -
Giao tiếp giữa Backend với nhau: Với những luồng cực kỳ nhạy cảm như Gate Service gọi sang Wallet Service để trừ tiền, mình bắt buộc xác thực qua gRPC đi kèm TLS certificates (mTLS). Ngay cả khi ai đó trong nội bộ công ty biết được IP nội bộ của máy chủ, họ cũng không thể dùng Postman hay Curl để fake giao dịch nạp/trừ tiền được.
Tạm kết
Bảo mật trong Microservices không chỉ là chống lại hacker từ Internet, mà còn là thiết kế một kiến trúc giới hạn tối đa "bán kính sát thương" nếu lỡ một mảnh ghép trong hệ thống bị thỏa hiệp.
Nhưng khi bạn đã có 20-30 cái service, được bảo mật chằng chịt, giao tiếp với nhau bằng gRPC, thì một vấn đề cực lớn tiếp theo sẽ xuất hiện: Làm sao để deploy (triển khai) mớ hỗn độn này lên server mỗi khi có code mới mà không làm gián đoạn hệ thống (Zero Downtime)?
Ở Bài 12, chúng ta sẽ nói về kỹ thuật Deployment với Docker & CI/CD – Trải nghiệm "vầng trăng khóc" khi nhét Microservices vào Server.
Anh em hiện tại đang dùng cách nào để các service nội bộ nhận diện nhau? Có anh em nào từng bị "phốt" vì tin tưởng tuyệt đối vào mạng LAN chưa? Cùng bình luận nhé!
All rights reserved