Cấu hình AuthorizationPolicy để kiểm soát truy cập theo Namespace và Workload
Mục tiêu: Áp dụng chính sách bảo mật ở tầng L7 (HTTP/gRPC) của Istio để xác định rõ ai (source) được phép gọi dịch vụ nào (destination) và qua phương thức nào (method/port).
Khác với NetworkPolicy (L3/L4), AuthorizationPolicy của Istio hoạt động dựa trên thông tin mTLS (Identity/Subject) và header HTTP, cho phép kiểm soát chi tiết đến từng action.
Bước 1: Tạo mẫu AuthorizationPolicy cơ bản cho service frontend.
Tạo file cấu hình YAML định nghĩa chính sách cho workload "frontend" trong namespace "app".
Đường dẫn file: /etc/istio/policies/frontend-authz.yaml
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
name: frontend-authz
namespace: app
spec:
selector:
matchLabels:
app: frontend
action: ALLOW
rules:
- from:
- source:
principals: ["cluster.local/ns/app/sa/backend"]
to:
- operation:
methods: ["GET", "POST"]
paths: ["/api/*", "/health"]
Giải thích:
selector.matchLabels: Áp dụng chính sách cho pod có label app=frontend.
action: ALLOW: Chỉ cho phép các yêu cầu khớp với rules (tự động deny các yêu cầu khác).
source.principals: Chỉ cho phép ServiceAccount backend từ namespace app truy cập.
operation: Giới hạn phương thức HTTP và đường dẫn.
Áp dụng cấu hình:
kubectl apply -f /etc/istio/policies/frontend-authz.yaml
Kết quả mong đợi: Istiod cập nhật sidecar Envoy, trả về AuthorizationPolicy "frontend-authz" created.
Áp dụng chính sách 'Deny All' và Whitelist cụ thể
Mục tiêu: Thiết lập nguyên tắc Zero Trust mặc định: "Mọi thứ bị cấm trừ khi được phép rõ ràng".
Bước 1: Áp dụng chính sách Deny All toàn namespace.
Tạo một AuthorizationPolicy "mặc định" phủ tất cả workload trong namespace để chặn mọi lưu lượng mới.
Đường dẫn file: /etc/istio/policies/deny-all-default.yaml
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
name: deny-all-default
namespace: app
spec:
action: DENY
rules:
- to:
- operation:
methods: ["*"]
ports: ["*"]
Giải thích:
action: DENY: Chặn tất cả các yêu cầu khớp rule.
methods: ["*"] và ports: ["*"]: Phủ toàn bộ phương thức và cổng.
- Không có
selector: Áp dụng cho tất cả workload trong namespace (trừ khi có chính sách cụ thể hơn override).
Áp dụng cấu hình:
kubectl apply -f /etc/istio/policies/deny-all-default.yaml
Kết quả mong đợi: Tất cả lưu lượng HTTP/HTTPS vào namespace app sẽ bị trả về lỗi 403 Forbidden.
Bước 2: Whitelist (cho phép) cho service backend.
Tạo chính sách riêng cho backend để vượt qua chính sách Deny All ở trên.
Đường dẫn file: /etc/istio/policies/backend-whitelist.yaml
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
name: backend-whitelist
namespace: app
spec:
selector:
matchLabels:
app: backend
action: ALLOW
rules:
- from:
- source:
principals: ["cluster.local/ns/app/sa/frontend"]
to:
- operation:
methods: ["GET"]
paths: ["/data/*"]
Áp dụng cấu hình:
kubectl apply -f /etc/istio/policies/backend-whitelist.yaml
Kết quả mong đợi: Service backend chỉ chấp nhận request GET từ frontend vào đường dẫn /data/*. Các request khác vào backend vẫn bị 403.
Kết hợp Cilium Network Policy và Istio AuthorizationPolicy (L3-L7)
Mục tiêu: Tạo lớp bảo vệ kép: Cilium chặn ở tầng Transport (L3/L4) và Istio chặn ở tầng Application (L7).
Bước 1: Cấu hình Cilium Network Policy để chặn kết nối TCP không mong muốn.
Cilium sử dụng eBPF để lọc gói tin ở kernel, nhanh hơn và nhẹ hơn Envoy. Chúng ta sẽ chặn kết nối từ namespace external vào app.
Đường dẫn file: /etc/cilium/policies/app-isolation.yaml
apiVersion: cilium.io/v2
kind: CiliumNetworkPolicy
metadata:
name: app-isolation-l3
spec:
endpointSelector:
matchLabels:
app: backend
ingress:
- fromEndpoints:
- matchLabels:
app: frontend
toPorts:
- ports:
- port: "8080"
protocol: TCP
Giải thích:
endpointSelector: Áp dụng cho pod backend.
fromEndpoints: Chỉ cho phép kết nối TCP từ pod frontend.
toPorts: Chỉ mở cổng 8080.
- Phép kết hợp: Cilium sẽ drop gói tin TCP từ bất kỳ nguồn nào khác ngay tại kernel, trước khi đến Envoy.
Áp dụng cấu hình:
cilium policy import /etc/cilium/policies/app-isolation.yaml
Kết quả mong đợi: Cilium chấp nhận policy, hiển thị Policy imported. Kết nối TCP từ nguồn lạ bị drop ngay lập tức (RST hoặc Timeout).
Bước 2: Xác minh sự kết hợp (Defense in Depth).
Kịch bản: Một kẻ tấn công từ namespace external cố gắng gọi backend:8080.
1. Cilium (L4): Drop gói tin TCP SYN. Kết quả: Kết nối không thể thiết lập.
2. Nếu Cilium bị bỏ qua (ví dụ: kết nối nội bộ nhưng sai SA): Istio (L7) sẽ nhận kết nối TCP nhưng chặn request HTTP vì không khớp AuthorizationPolicy. Kết quả: 403 Forbidden.
Kiểm thử các kịch bản tấn công và xác minh chính sách
Mục tiêu: Thực hiện các request thử nghiệm để xác nhận chính sách hoạt động đúng như thiết kế.
Chuẩn bị: Đảm bảo có pod frontend, backend và attacker (pod giả lập kẻ tấn công) trong namespace app.
Bước 1: Test trường hợp hợp lệ (Whitelist).
Thực hiện request từ frontend đến backend đúng phương thức và path.
kubectl exec -it deploy/frontend -- curl -s -o /dev/null -w "%{http_code}" http://backend:8080/data/secret
Kết quả mong đợi: Mã trạng thái 200 (OK). Chứng tỏ chính sách ALLOW đã hoạt động.
Bước 2: Test trường hợp bị chặn bởi AuthorizationPolicy (L7).
Thực hiện request từ attacker (SA khác) đến backend.
kubectl exec -it deploy/attacker -- curl -s -o /dev/null -w "%{http_code}" http://backend:8080/data/secret
Kết quả mong đợi: Mã trạng thái 403 (Forbidden). Istio đã chặn vì SA attacker không nằm trong danh sách principals.
Bước 3: Test trường hợp bị chặn bởi Cilium Network Policy (L4).
Thử kết nối từ attacker đến cổng không được phép (ví dụ: 9090) hoặc từ namespace khác nếu đã cấu hình isolation.
kubectl exec -it deploy/attacker -- curl -s -o /dev/null -w "%{http_code}" --connect-timeout 2 http://backend:9090/any
Kết quả mong đợi: Lỗi Connection timed out hoặc Connection refused. Cilium đã drop gói tin ở tầng L4 trước khi đến Envoy.
Bước 4: Xác minh log audit của Istio.
Để xem chi tiết lý do bị chặn trong log của Envoy (sidecar).
kubectl logs -n app deploy/backend -c istio-proxy | grep -i "403"
Kết quả mong đợi: Xuất hiện dòng log upstream_rq_403 hoặc reason=RBAC, xác nhận yêu cầu bị chặn bởi chính sách bảo mật.
Bước 5: Sử dụng Kiali (nếu đã deploy) để visualize policy.
Vào giao diện Kiali -> Namespace app -> Chọn service backend -> Tab AuthorizationPolicies.
Kết quả mong đợi: Hiển thị đồ thị luồng traffic với các mũi tên màu đỏ (denied) và xanh (allowed) tương ứng với các chính sách đã cấu hình.
Điều hướng series:
Mục lục: Series: Xây dựng nền tảng Service Mesh nội bộ an toàn với Istio, Cilium và eBPF trên Kubernetes để quản lý lưu lượng mạng, bảo mật và quan sát chi tiết
« Phần 4: Quản lý lưu lượng mạng chi tiết với Istio Traffic Policies
Phần 6: Thiết lập hệ thống quan sát (Observability) với Hubble và Kiali »