Quay lại microservice với Istio. Phần 3

Quay lại microservice với Istio. Phần 3

Ghi chú. bản dịch.: Phần đầu tiên loạt bài này được dành để tìm hiểu các khả năng của Istio và thể hiện chúng trong thực tế, 2 - tinh chỉnh định tuyến và quản lý lưu lượng mạng. Bây giờ chúng ta sẽ nói về bảo mật: để trình bày các chức năng cơ bản liên quan đến nó, tác giả sử dụng dịch vụ nhận dạng Auth0, nhưng các nhà cung cấp khác có thể được cấu hình theo cách tương tự.

Chúng tôi đã thiết lập một cụm Kubernetes trong đó chúng tôi đã triển khai Istio và một ứng dụng vi dịch vụ mẫu, Phân tích tình cảm, để chứng minh khả năng của Istio.

Với Istio, chúng tôi có thể duy trì các dịch vụ của mình ở quy mô nhỏ vì chúng không cần triển khai các lớp như Thử lại, Hết giờ, Bộ ngắt mạch, Truy tìm, Giám sát. . Ngoài ra, chúng tôi đã sử dụng các kỹ thuật triển khai và thử nghiệm nâng cao: thử nghiệm A/B, phản chiếu và triển khai theo kiểu canary.

Quay lại microservice với Istio. Phần 3

Trong tài liệu mới, chúng ta sẽ giải quyết các lớp cuối cùng trên con đường dẫn đến giá trị kinh doanh: xác thực và ủy quyền - và ở Istio, đó thực sự là một niềm vui!

Xác thực và ủy quyền trong Istio

Tôi chưa bao giờ tin rằng mình sẽ được truyền cảm hứng từ việc xác thực và ủy quyền. Istio có thể cung cấp những gì từ góc độ công nghệ để làm cho những chủ đề này trở nên thú vị và thậm chí còn truyền cảm hứng cho bạn?

Câu trả lời rất đơn giản: Istio chuyển trách nhiệm về những khả năng này từ dịch vụ của bạn sang proxy Envoy. Vào thời điểm các yêu cầu đến được các dịch vụ, chúng đã được xác thực và ủy quyền, vì vậy tất cả những gì bạn phải làm là viết mã hữu ích cho doanh nghiệp.

Âm thanh tốt? Chúng ta hãy nhìn vào bên trong!

Xác thực bằng Auth0

Là một máy chủ để quản lý danh tính và quyền truy cập, chúng tôi sẽ sử dụng Auth0, phiên bản dùng thử, trực quan để sử dụng và tôi chỉ thích nó. Tuy nhiên, những nguyên tắc tương tự có thể được áp dụng cho bất kỳ Triển khai OpenID Connect: KeyCloak, IdentityServer và nhiều thứ khác.

Để bắt đầu, hãy truy cập Cổng thông tin Auth0 với tài khoản của bạn, tạo một người thuê nhà (người thuê - "người thuê", đơn vị cách ly logic, để biết thêm chi tiết, xem tài liệu - khoảng. dịch.) và đi đến Ứng dụng > Ứng dụng mặc địnhlựa chọn miền, như thể hiện trong ảnh chụp màn hình bên dưới:

Quay lại microservice với Istio. Phần 3

Chỉ định tên miền này trong tệp resource-manifests/istio/security/auth-policy.yaml (nguồn):

apiVersion: authentication.istio.io/v1alpha1
kind: Policy
metadata:
  name: auth-policy
spec:
  targets:
  - name: sa-web-app
  - name: sa-feedback
  origins:
  - jwt:
      issuer: "https://{YOUR_DOMAIN}/"
      jwksUri: "https://{YOUR_DOMAIN}/.well-known/jwks.json"
  principalBinding: USE_ORIGIN

Với nguồn lực như vậy, Pilot (một trong ba thành phần Control Plane cơ bản trong Istio - bản dịch xấp xỉ) định cấu hình Envoy để xác thực các yêu cầu trước khi chuyển tiếp chúng đến các dịch vụ: sa-web-app и sa-feedback. Đồng thời, cấu hình không được áp dụng cho dịch vụ Envoys sa-frontend, cho phép chúng tôi rời khỏi giao diện người dùng mà không được xác thực. Để áp dụng Chính sách, hãy chạy lệnh:

$ kubectl apply -f resource-manifests/istio/security/auth-policy.yaml
policy.authentication.istio.io “auth-policy” created

Quay lại trang và đưa ra yêu cầu - bạn sẽ thấy nó kết thúc bằng trạng thái 401 trái phép. Bây giờ hãy chuyển hướng người dùng giao diện người dùng để xác thực bằng Auth0.

Xác thực yêu cầu với Auth0

Để xác thực các yêu cầu của người dùng cuối, bạn cần tạo một API trong Auth0 sẽ đại diện cho các dịch vụ được xác thực (đánh giá, chi tiết và xếp hạng). Để tạo API, hãy truy cập Cổng thông tin Auth0 > API > Tạo API và điền vào mẫu:

Quay lại microservice với Istio. Phần 3

Thông tin quan trọng ở đây là Định danh, mà chúng ta sẽ sử dụng sau này trong tập lệnh. Hãy viết nó ra như thế này:

  • Khán giả: {KHÁN GIẢ CỦA BẠN}

Các chi tiết còn lại chúng ta cần đều có trên Cổng thông tin Auth0 trong phần Ứng dụng - lựa chọn Ứng dụng thử nghiệm (được tạo tự động cùng với API).

Ở đây chúng tôi sẽ viết:

  • miền: {TÊN MIỀN CỦA BẠN}
  • Id khách hàng: {YOUR_CLIENT_ID}

Cuộn đến Ứng dụng thử nghiệm vào trường văn bản URL gọi lại được phép (URL đã được giải quyết cho cuộc gọi lại), trong đó chúng tôi chỉ định URL nơi cuộc gọi sẽ được gửi sau khi hoàn tất xác thực. Trong trường hợp của chúng tôi đó là:

http://{EXTERNAL_IP}/callback

Và cho URL đăng xuất được phép (URL được phép đăng xuất) thêm:

http://{EXTERNAL_IP}/logout

Hãy chuyển sang giao diện người dùng.

Cập nhật giao diện người dùng

Chuyển sang chi nhánh auth0 kho [istio-mastery]. Trong nhánh này, mã giao diện người dùng được thay đổi để chuyển hướng người dùng đến Auth0 để xác thực và sử dụng mã thông báo JWT trong các yêu cầu tới các dịch vụ khác. Cái sau được thực hiện như sau (Ứng dụng.js):

analyzeSentence() {
    fetch('/sentiment', {
        method: 'POST',
        headers: {
            'Content-Type': 'application/json',
            'Authorization': `Bearer ${auth.getAccessToken()}` // Access Token
        },
        body: JSON.stringify({ sentence: this.textField.getValue() })
    })
        .then(response => response.json())
        .then(data => this.setState(data));
}

Để thay đổi giao diện người dùng để sử dụng dữ liệu đối tượng thuê trong Auth0, hãy mở sa-frontend/src/services/Auth.js và thay thế vào đó các giá trị mà chúng tôi đã viết ở trên (Auth.js):

const Config = {
    clientID: '{YOUR_CLIENT_ID}',
    domain:'{YOUR_DOMAIN}',
    audience: '{YOUR_AUDIENCE}',
    ingressIP: '{EXTERNAL_IP}' // Используется для редиректа после аутентификации
}

Ứng dụng đã sẵn sàng. Chỉ định ID Docker của bạn trong các lệnh bên dưới khi xây dựng và triển khai các thay đổi đã thực hiện:

$ docker build -f sa-frontend/Dockerfile 
 -t $DOCKER_USER_ID/sentiment-analysis-frontend:istio-auth0 
 sa-frontend

$ docker push $DOCKER_USER_ID/sentiment-analysis-frontend:istio-auth0

$ kubectl set image deployment/sa-frontend 
 sa-frontend=$DOCKER_USER_ID/sentiment-analysis-frontend:istio-auth0

Hãy thử ứng dụng! Bạn sẽ được chuyển hướng đến Auth0, nơi bạn cần đăng nhập (hoặc đăng ký), sau đó bạn sẽ được đưa trở lại trang mà từ đó các yêu cầu đã được xác thực sẽ được thực hiện. Nếu bạn thử các lệnh được đề cập ở phần đầu của bài viết bằng lệnh cuộn tròn, bạn sẽ nhận được mã 401 Mã trạng thái, báo hiệu rằng yêu cầu không được phép.

Hãy thực hiện bước tiếp theo - cho phép các yêu cầu.

Ủy quyền với Auth0

Xác thực cho phép chúng tôi hiểu người dùng là ai, nhưng cần có ủy quyền để biết họ có quyền truy cập vào những gì. Istio cũng cung cấp các công cụ cho việc này.

Ví dụ: hãy tạo hai nhóm người dùng (xem sơ đồ bên dưới):

  • Thành viên (người dùng) — chỉ có quyền truy cập vào các dịch vụ SA-WebApp và SA-Frontend;
  • Người điều hành (người điều hành) — với quyền truy cập vào cả ba dịch vụ.

Quay lại microservice với Istio. Phần 3
Khái niệm ủy quyền

Để tạo các nhóm này, chúng tôi sẽ sử dụng tiện ích mở rộng Ủy quyền Auth0 và sử dụng Istio để cung cấp cho họ các cấp độ truy cập khác nhau.

Cài đặt và cấu hình ủy quyền Auth0

Trong cổng Auth0, đi tới phần mở rộng (Phần mở rộng) và cài đặt Ủy quyền Auth0. Sau khi cài đặt, hãy truy cập Gia hạn ủy quyềnvà ở đó - cấu hình của đối tượng thuê bằng cách nhấp vào phía trên bên phải và chọn tùy chọn menu thích hợp (Cấu hình). Kích hoạt nhóm (Các nhóm) và nhấp vào nút quy tắc xuất bản (Quy tắc xuất bản).

Quay lại microservice với Istio. Phần 3

Tạo nhóm

Trong phần Gia hạn ủy quyền, hãy đi tới Du lịch Nhóm và tạo một nhóm Người điều hành. Vì chúng tôi sẽ coi tất cả người dùng được xác thực là người dùng thông thường nên không cần phải tạo nhóm bổ sung cho họ.

Chọn một nhóm Người điều hành, Nhấn Thêm thành viên, thêm tài khoản chính của bạn. Để lại một số người dùng mà không có bất kỳ nhóm nào để đảm bảo rằng họ bị từ chối truy cập. (Người dùng mới có thể được tạo thủ công thông qua Cổng thông tin Auth0 > Người dùng > Tạo người dùng.)

Thêm xác nhận nhóm vào mã thông báo truy cập

Người dùng đã được thêm vào nhóm nhưng thông tin này cũng phải được phản ánh trong mã thông báo truy cập. Để tuân thủ OpenID Connect và đồng thời trả lại các nhóm chúng tôi cần, mã thông báo sẽ cần thêm mã thông báo của riêng nó yêu cầu tùy chỉnh. Được thực hiện thông qua các quy tắc Auth0.

Để tạo quy tắc, hãy truy cập Cổng thông tin Auth0 để Nội quy, Nhấn Tạo quy tắc và chọn một quy tắc trống từ các mẫu.

Quay lại microservice với Istio. Phần 3

Sao chép mã bên dưới và lưu nó làm quy tắc mới Thêm yêu cầu nhóm (namespaceGroup.js):

function (user, context, callback) {
    context.accessToken['https://sa.io/group'] = user.groups[0];
    return callback(null, user, context);
}

Ghi: Mã này lấy nhóm người dùng đầu tiên được xác định trong Tiện ích mở rộng ủy quyền và thêm nhóm đó vào mã thông báo truy cập dưới dạng xác nhận quyền sở hữu tùy chỉnh (trong không gian tên của nhóm, theo yêu cầu của Auth0).

Quay lại trang Nội quy và kiểm tra xem bạn có hai quy tắc được viết theo thứ tự sau không:

  • auth0-ủy quyền-phần mở rộng
  • Thêm yêu cầu nhóm

Thứ tự rất quan trọng vì trường nhóm nhận quy tắc không đồng bộ auth0-ủy quyền-phần mở rộng và sau đó nó được thêm vào như một yêu cầu theo quy tắc thứ hai. Kết quả là một mã thông báo truy cập như thế này:

{
 "https://sa.io/group": "Moderators",
 "iss": "https://sentiment-analysis.eu.auth0.com/",
 "sub": "google-oauth2|196405271625531691872"
 // [сокращено для наглядности]
}

Bây giờ bạn cần định cấu hình proxy Envoy để kiểm tra quyền truy cập của người dùng, nhóm này sẽ bị loại khỏi yêu cầu (https://sa.io/group) trong mã thông báo truy cập được trả về. Đây là chủ đề cho phần tiếp theo của bài viết.

Cấu hình ủy quyền trong Istio

Để ủy quyền hoạt động, bạn phải kích hoạt RBAC cho Istio. Để làm điều này, chúng tôi sẽ sử dụng cấu hình sau:

apiVersion: "rbac.istio.io/v1alpha1"
kind: RbacConfig
metadata:
  name: default
spec:
  mode: 'ON_WITH_INCLUSION'                     # 1
  inclusion:
    services:                                   # 2
    - "sa-frontend.default.svc.cluster.local"
    - "sa-web-app.default.svc.cluster.local"
    - "sa-feedback.default.svc.cluster.local" 

Giải thích:

  • 1 - chỉ bật RBAC cho các dịch vụ và không gian tên được liệt kê trong trường Inclusion;
  • 2 — chúng tôi liệt kê danh sách các dịch vụ của mình.

Hãy áp dụng cấu hình bằng lệnh sau:

$ kubectl apply -f resource-manifests/istio/security/enable-rbac.yaml
rbacconfig.rbac.istio.io/default created

Tất cả các dịch vụ hiện yêu cầu Kiểm soát truy cập dựa trên vai trò. Nói cách khác, việc truy cập vào tất cả các dịch vụ đều bị cấm và sẽ dẫn đến phản hồi RBAC: access denied. Bây giờ hãy cho phép truy cập vào người dùng được ủy quyền.

Truy cập cấu hình cho người dùng thông thường

Tất cả người dùng phải có quyền truy cập vào các dịch vụ SA-Frontend và SA-WebApp. Được triển khai bằng cách sử dụng các tài nguyên Istio sau:

  • Vai trò dịch vụ — xác định các quyền mà người dùng có;
  • Dịch vụRoleRàng buộc — xác định ServiceRole này thuộc về ai.

Đối với người dùng thông thường, chúng tôi sẽ cho phép truy cập vào một số dịch vụ nhất định (dịch vụrole.yaml):

apiVersion: "rbac.istio.io/v1alpha1"
kind: ServiceRole
metadata:
  name: regular-user
  namespace: default
spec:
  rules:
  - services: 
    - "sa-frontend.default.svc.cluster.local" 
    - "sa-web-app.default.svc.cluster.local"
    paths: ["*"]
    methods: ["*"]

Và sau regular-user-binding áp dụng ServiceRole cho tất cả khách truy cập trang (người dùng thường xuyên-dịch vụ-vai trò ràng buộc.yaml):

apiVersion: "rbac.istio.io/v1alpha1"
kind: ServiceRoleBinding
metadata:
  name: regular-user-binding
  namespace: default
spec:
  subjects:
  - user: "*"
  roleRef:
    kind: ServiceRole
    name: "regular-user"

Phải chăng "tất cả người dùng" có nghĩa là những người dùng chưa được xác thực cũng sẽ có quyền truy cập vào SA WebApp? Không, chính sách sẽ kiểm tra tính hợp lệ của mã thông báo JWT.

Hãy áp dụng các cấu hình:

$ kubectl apply -f resource-manifests/istio/security/user-role.yaml
servicerole.rbac.istio.io/regular-user created
servicerolebinding.rbac.istio.io/regular-user-binding created

Cấu hình truy cập cho người điều hành

Đối với người điều hành, chúng tôi muốn cho phép truy cập vào tất cả các dịch vụ (mod-service-role.yaml):

apiVersion: "rbac.istio.io/v1alpha1"
kind: ServiceRole
metadata:
  name: mod-user
  namespace: default
spec:
  rules:
  - services: ["*"]
    paths: ["*"]
    methods: ["*"]

Nhưng chúng tôi chỉ muốn những quyền đó dành cho những người dùng có mã thông báo truy cập chứa xác nhận quyền sở hữu https://sa.io/group với ý nghĩa Moderators (mod-service-role-bind.yaml):

apiVersion: "rbac.istio.io/v1alpha1"
kind: ServiceRoleBinding
metadata:
  name: mod-user-binding
  namespace: default
spec:
  subjects:
  - properties:
      request.auth.claims[https://sa.io/group]: "Moderators"
  roleRef:
    kind: ServiceRole
name: "mod-user" 

Hãy áp dụng các cấu hình:

$ kubectl apply -f resource-manifests/istio/security/mod-role.yaml
servicerole.rbac.istio.io/mod-user created
servicerolebinding.rbac.istio.io/mod-user-binding created

Do bộ nhớ đệm trong envoys nên có thể mất vài phút để các quy tắc ủy quyền có hiệu lực. Sau đó, bạn có thể đảm bảo rằng người dùng và người kiểm duyệt có các cấp độ truy cập khác nhau.

Kết luận về phần này

Nghiêm túc mà nói, bạn đã bao giờ thấy một cách tiếp cận đơn giản, dễ dàng, có thể mở rộng và an toàn để xác thực và ủy quyền chưa?

Chỉ cần ba tài nguyên Istio (RbacConfig, ServiceRole và ServiceRoleBinding) để đạt được quyền kiểm soát chi tiết đối với việc xác thực và ủy quyền quyền truy cập của người dùng cuối vào dịch vụ.

Ngoài ra, chúng tôi đã giải quyết những vấn đề này từ dịch vụ đại sứ của mình và đạt được:

  • giảm số lượng mã chung có thể chứa các vấn đề và lỗi bảo mật;
  • giảm số lượng các tình huống ngu ngốc trong đó một điểm cuối hóa ra có thể truy cập được từ bên ngoài và quên báo cáo;
  • loại bỏ nhu cầu cập nhật tất cả các dịch vụ mỗi khi thêm vai trò hoặc quyền mới;
  • rằng các dịch vụ mới vẫn đơn giản, an toàn và nhanh chóng.

Đầu ra

Istio cho phép các nhóm tập trung nguồn lực vào các nhiệm vụ quan trọng trong kinh doanh mà không cần thêm chi phí vào dịch vụ, đưa chúng về trạng thái vi mô.

Bài viết (gồm ba phần) cung cấp kiến ​​thức cơ bản và hướng dẫn thực tế có sẵn để bắt đầu sử dụng Istio trong các dự án thực tế.

Tái bút từ người dịch

Đọc thêm trên blog của chúng tôi:

Nguồn: www.habr.com

Thêm một lời nhận xét