Introduction to Istio, Part 11
Security
Các Khái Niệm Bảo Mật Trong Istio
Chương này giải thích các khái niệm bảo mật trong Istio. Chúng ta sẽ tìm hiểu cách Istio sử dụng nhận dạng trong Kubernetes và cách các chứng chỉ được cấp phát và làm mới. Sau đó, chúng ta sẽ học về các câu hỏi kiểm soát truy cập, xác thực và phân quyền, và mTLS.
Mục Tiêu Học Tập
Cuối chương này, bạn sẽ có thể:
Hiểu được xác thực, phân quyền và kiểm soát truy cập là gì, và Istio sử dụng gì để nhận dạng.
Hiểu mTLS là gì và cách cấu hình TLS cho sidecar proxies và gateways.
Hiểu cách xác thực dịch vụ và người dùng trong Istio.
Thảo luận về cách chứng chỉ được cấp phát trong Istio.
Kiểm Soát Truy Cập
Câu hỏi kiểm soát truy cập cố gắng trả lời là: liệu một đối tượng có thể thực hiện một hành động trên một đối tượng khác không?
Ví dụ, xem xét hai câu hỏi sau:
Người dùng có thể xóa một tệp không?
Người dùng có thể thực thi một script không?
Trong ví dụ trên, người dùng là đối tượng chính, các hành động là xóa và thực thi, và đối tượng là tệp và script.
Nếu chúng ta đặt câu hỏi tương tự trong Kubernetes và Istio, câu hỏi có thể là:
- Dịch vụ A có thể thực hiện hành động nào trên dịch vụ B?
Các thuật ngữ quan trọng trong bảo mật và khi trả lời câu hỏi kiểm soát truy cập là xác thực (authentication) và phân quyền (authorization).
Xác Thực (Authentication)
Xác thực liên quan đến đối tượng chính, trong trường hợp này là các dịch vụ và nhận dạng của chúng. Xác thực là hành động xác minh một thông tin chứng nhận và đảm bảo chứng nhận đó là hợp lệ và xác thực. Khi xác thực được thực hiện, chúng ta có thể nói rằng đối tượng chính đã được xác thực.
Trong Kubernetes, mỗi workload tự động được cấp phát một nhận dạng duy nhất. Nhận dạng này được sử dụng khi các workload giao tiếp. Nhận dạng trong Kubernetes có dạng tài khoản dịch vụ Kubernetes. Các pod trong Kubernetes sử dụng tài khoản dịch vụ làm nhận dạng và trình bày nó tại thời gian chạy.
Cụ thể, Istio sử dụng chứng chỉ X.509 từ tài khoản dịch vụ, tạo ra một nhận dạng mới theo đặc tả gọi là SPIFFE (Secure Production Identity Framework For Everyone).
SPIFFE định nghĩa một sơ đồ đặt tên phổ quát dựa trên URI. Ví dụ: spiffe://cluster.local/ns/default/sa/my-service-account
. Đặc tả này mô tả cách lấy nhận dạng và mã hóa nó vào các tài liệu khác nhau. Tài liệu chúng ta quan tâm trong trường hợp này là chứng chỉ X.509.
Dựa trên đặc tả SPIFFE, khi chúng ta tạo chứng chỉ X.509 và điền vào trường Subject Alternative Name (SAN) dựa trên sơ đồ đặt tên trên và kiểm tra tên đó trong quá trình xác minh chứng chỉ, chúng ta có thể xác thực nhận dạng mã hóa trong chứng chỉ. Khi đó, chúng ta sẽ có một nhận dạng SPIFFE hợp lệ, tức là một đối tượng chính đã được xác thực.
Các sidecar proxy Envoy được sửa đổi và có thể thực hiện bước xác minh bổ sung cần thiết theo SPIFFE (tức là kiểm tra SAN), cho phép các đối tượng chính đã xác thực này được sử dụng cho các quyết định chính sách.
Mutual TLS (mTLS)
Khi các workload có một nhận dạng mạnh mẽ, chúng ta có thể sử dụng chúng trong thời gian thực để thực hiện xác thực mTLS (Mutual TLS).
Thông thường, TLS được thực hiện một chiều. Hãy lấy ví dụ khi bạn truy cập https://google.com. Nếu bạn mở trang web, bạn sẽ thấy biểu tượng ổ khóa và có thể nhấn vào đó để xem chi tiết chứng chỉ. Tuy nhiên, chúng ta không cung cấp bất kỳ chứng minh nhận dạng nào cho google.com, chỉ đơn giản là mở trang web. Đây là điểm khác biệt cơ bản của mTLS.
Khi hai dịch vụ cố gắng giao tiếp với nhau thông qua mTLS, yêu cầu cả hai bên phải cung cấp chứng chỉ cho nhau. Như vậy, cả hai bên đều biết được nhận dạng của đối tác mà họ đang giao tiếp.
Với mTLS, cả máy khách và máy chủ đều xác minh lẫn nhau về danh tính.
Cơ Chế Hoạt Động của mTLS trong Istio
Như đã học trước đây, tất cả các giao tiếp giữa các workload đều đi qua các proxy Envoy. Khi một workload gửi yêu cầu đến workload khác, Istio sẽ chuyển hướng lưu lượng đến proxy Envoy của sidecar, bất kể có sử dụng mTLS hay giao tiếp văn bản thuần túy.
Trong trường hợp mTLS, một khi kết nối mTLS được thiết lập, yêu cầu sẽ được chuyển từ proxy Envoy của máy khách đến proxy Envoy của máy chủ. Sau đó, proxy Envoy của sidecar sẽ bắt đầu một thủ tục bắt tay mTLS với proxy Envoy phía máy chủ. Các workload không thực hiện thủ tục bắt tay mTLS – mà chính các proxy Envoy thực hiện công việc này.
Trong suốt quá trình bắt tay, bên gọi sẽ thực hiện kiểm tra tên an toàn để xác minh tài khoản dịch vụ trong chứng chỉ máy chủ có được phép chạy dịch vụ mục tiêu hay không. Sau khi xác thực phía máy chủ, proxy sidecar sẽ chuyển tiếp lưu lượng đến workload.
Các sidecar proxy đóng vai trò quan trọng trong việc chặn lưu lượng đến và hỗ trợ hoặc gửi lưu lượng đi. Vì lý do này, hai tài nguyên riêng biệt sẽ kiểm soát lưu lượng vào và ra. PeerAuthentication kiểm soát lưu lượng vào, còn DestinationRule kiểm soát lưu lượng ra.
Inbound Traffic to the Proxy
Tài nguyên cấu hình loại lưu lượng mTLS mà sidecar chấp nhận là PeerAuthentication. Nó hỗ trợ bốn chế độ hoạt động, như bảng dưới đây.
Chế độ mTLS | Mô tả |
UNSET | Cài đặt được kế thừa từ cấp cha (ví dụ: cài đặt ở cấp mesh hoặc namespace); nếu không, mặc định là chế độ permissive. |
DISABLE | mTLS bị tắt. |
PERMISSIVE (mặc định) | Kết nối giữa các workload có thể là văn bản thuần túy hoặc mTLS. |
STRICT | Kết nối giữa các workload phải sử dụng mTLS (tức là cả hai bên phải cung cấp chứng chỉ). |
Chế độ mTLS mặc định là PERMISSIVE, có nghĩa là nếu một client cố gắng kết nối với dịch vụ qua mTLS, proxy Envoy sẽ phục vụ mTLS. Máy chủ sẽ trả lời bằng văn bản thuần túy nếu client sử dụng giao thức văn bản thuần túy. Với cài đặt này, chúng ta cho phép client tự chọn có sử dụng mTLS hay không. Chế độ permissive hữu ích khi đưa các ứng dụng hiện có vào service mesh vì nó cho phép triển khai mTLS cho tất cả các workload dần dần.
Khi tất cả các ứng dụng đã được tích hợp, chúng ta có thể bật chế độ STRICT. Chế độ strict yêu cầu các workload chỉ có thể giao tiếp thông qua mTLS. Kết nối sẽ bị đóng nếu client cố gắng kết nối mà không cung cấp chứng chỉ của họ.
Chúng ta có thể cấu hình chế độ mTLS ở cấp độ mesh, namespace, workload và port. Ví dụ, chúng ta có thể đặt chế độ STRICT ở cấp độ namespace và sau đó thiết lập chế độ permissive hoặc vô hiệu hóa mTLS ở cấp độ workload cụ thể bằng cách sử dụng selectors hoặc ở cấp độ port cá nhân.
Dưới đây là một ví dụ về cách chúng ta có thể thiết lập chế độ STRICT cho tất cả các workload khớp với một nhãn cụ thể:
apiVersion: security.istio.io/v1beta1
kind: PeerAuthentication
metadata:
name: default
namespace: foo
spec:
selector:
matchLabels:
app: hello-world
mtls:
mode: STRICT
Outbound Traffic from the Proxy
Chúng ta sử dụng tài nguyên DestinationRule để kiểm soát và cấu hình loại lưu lượng TLS mà sidecar gửi đi.
Các chế độ TLS hỗ trợ được trình bày trong bảng dưới đây.
Chế độ TLS | Mô tả |
DISABLE | Không thiết lập kết nối TLS. |
SIMPLE | Khởi tạo kết nối TLS truyền thống. |
MUTUAL | Sử dụng khóa và chứng chỉ được cung cấp để khởi tạo kết nối mTLS. |
ISTIO_MUTUAL (mặc định) | Sử dụng chứng chỉ Istio cho kết nối TLS. |
Dựa trên cấu hình, lưu lượng có thể được gửi dưới dạng văn bản thuần túy (DISABLE), hoặc kết nối TLS có thể được khởi tạo bằng cách sử dụng chế độ SIMPLE cho TLS và MUTUAL hoặc ISTIO_MUTUAL cho mTLS.
Nếu DestinationRule và chế độ TLS không được thiết lập rõ ràng, sidecar sẽ sử dụng chứng chỉ của Istio để khởi tạo kết nối mTLS. Điều này có nghĩa là mặc định, tất cả lưu lượng bên trong mesh sẽ được mã hóa.
Cấu hình có thể được áp dụng cho các host cụ thể qua tên miền đầy đủ (ví dụ: hello-world.my
-namespace.svc.cluster.local
). Chúng ta có thể thiết lập workload selector với các nhãn để chọn các workload cụ thể mà cấu hình sẽ được áp dụng.
Chúng ta cũng có thể cấu hình các port cụ thể trên các workload để áp dụng các cài đặt với độ chính xác cao hơn.
Dưới đây là ví dụ về cách chúng ta có thể cấu hình DestinationRule để khởi tạo kết nối TLS khi giao tiếp với các dịch vụ có domain phù hợp với *.
example.com
:
apiVersion: networking.istio.io/v1beta1
kind: DestinationRule
metadata:
name: tls-example
spec:
host: "*.example.com"
trafficPolicy:
tls:
mode: SIMPLE
Gateways and TLS
Trong trường hợp các cổng (gateways), chúng ta cũng bàn về kết nối vào (inbound) và kết nối ra (outbound).
Với Ingress Gateways, kết nối vào thường đến từ bên ngoài mesh (ví dụ, yêu cầu từ trình duyệt, cURL, v.v.), và kết nối ra sẽ chuyển đến các dịch vụ bên trong mesh.
Ngược lại, với Egress Gateways, kết nối vào thường đến từ bên trong mesh, và kết nối ra sẽ đi ra ngoài mesh.
Trong cả hai trường hợp, cấu hình và các tài nguyên sử dụng là giống nhau. Phía sau cánh cửa, các triển khai Ingress và Egress Gateway của mesh là giống nhau - chính cấu hình là yếu tố giúp chuyên biệt hóa và điều chỉnh chúng cho lưu lượng vào hoặc ra. Cấu hình các gateway được điều khiển bằng tài nguyên Gateway.
Trường tls trong tài nguyên Gateway điều khiển cách thức gateway giải mã lưu lượng vào. Trường protocol xác định xem kết nối vào là HTTP văn bản thuần túy (plaintext), HTTPS, gRPC, MONGO, TCP hay TLS.
Khi kết nối vào là TLS, chúng ta có một vài tùy chọn để kiểm soát hành vi của gateway. Liệu chúng ta có muốn kết thúc kết nối TLS, chuyển tiếp nó, hay thực hiện mTLS?
Các tùy chọn bổ sung này có thể được cấu hình bằng cách sử dụng chế độ TLS trong tài nguyên Gateway. Bảng dưới đây mô tả các chế độ TLS khác nhau.
Chế độ TLS | Mô tả |
PASSTHROUGH | Không kết thúc TLS; việc khớp tuyến đường trong VirtualService được thực hiện dựa trên thông tin SNI. Kết nối được chuyển tiếp đến đích như nguyên trạng. |
SIMPLE | Kết nối TLS tiêu chuẩn. |
MUTUAL | Thực hiện mTLS với đích, yêu cầu phải cài đặt caCertificates hoặc credentialName. |
AUTO_PASSTHROUGH | Tương tự như passthrough, nhưng không yêu cầu một VirtualService liên kết để ánh xạ từ SNI đến dịch vụ trong registry, vì thông tin đích (dịch vụ, subset, cổng) được mã hóa trong giá trị SNI. |
ISTIO_MUTUAL | Tương tự như MUTUAL, nhưng sử dụng chứng chỉ được tạo ra bởi Istio (tức là, danh tính được sử dụng trong chứng chỉ là workload của gateway). |
Các cấu hình liên quan đến TLS khác trong tài nguyên Gateway, chẳng hạn như các phiên bản TLS, có thể được tìm thấy trong tài liệu chính thức.
Khi cấu hình các cài đặt TLS cho lưu lượng ra qua Egress Gateway, cấu hình tương tự cũng áp dụng cho các proxy sidecar Envoy thông thường trong mesh — sử dụng tài nguyên DestinationRule.