กลับไปสู่ไมโครเซอร์วิสด้วย Istio ส่วนที่ 3

กลับไปสู่ไมโครเซอร์วิสด้วย Istio ส่วนที่ 3

บันทึก. แปล: ส่วนแรก ซีรีส์นี้จัดทำขึ้นเพื่อทำความรู้จักกับความสามารถของ Istio และสาธิตการใช้งานจริง ที่สอง — การกำหนดเส้นทางและการจัดการการรับส่งข้อมูลเครือข่ายที่ได้รับการปรับแต่งอย่างละเอียด ตอนนี้เราจะพูดถึงความปลอดภัย: เพื่อสาธิตฟังก์ชั่นพื้นฐานที่เกี่ยวข้องผู้เขียนใช้บริการข้อมูลประจำตัว Auth0 แต่ผู้ให้บริการรายอื่นสามารถกำหนดค่าได้ในลักษณะเดียวกัน

เราตั้งค่าคลัสเตอร์ Kubernetes ซึ่งเราใช้ Istio และแอปพลิเคชันไมโครเซอร์วิสตัวอย่าง Sentiment Analysis เพื่อสาธิตความสามารถของ Istio

ด้วย Istio เราจึงสามารถให้บริการของเรามีขนาดเล็กได้เนื่องจากไม่จำเป็นต้องใช้เลเยอร์ต่างๆ เช่น การลองใหม่ การหมดเวลา เซอร์กิตเบรกเกอร์ การติดตาม และการตรวจสอบ นอกจากนี้เรายังใช้เทคนิคการทดสอบและการปรับใช้ขั้นสูง: การทดสอบ A/B การมิเรอร์ และการเปิดตัว Canary

กลับไปสู่ไมโครเซอร์วิสด้วย Istio ส่วนที่ 3

ในเนื้อหาใหม่ เราจะจัดการกับเลเยอร์สุดท้ายบนเส้นทางสู่มูลค่าทางธุรกิจ: การรับรองความถูกต้องและการอนุญาต - และใน Istio เป็นเรื่องที่น่ายินดีอย่างยิ่ง!

การรับรองความถูกต้องและการอนุญาตใน Istio

ฉันไม่เคยคิดเลยว่าจะได้รับแรงบันดาลใจจากการรับรองความถูกต้องและการอนุญาต Istio สามารถนำเสนออะไรจากมุมมองของเทคโนโลยีเพื่อทำให้หัวข้อเหล่านี้สนุกสนาน และยิ่งกว่านั้นคือสร้างแรงบันดาลใจให้กับคุณ

คำตอบนั้นง่ายมาก: Istio เปลี่ยนความรับผิดชอบสำหรับความสามารถเหล่านี้จากบริการของคุณไปยังพร็อกซี Envoy เมื่อคำขอไปถึงบริการ คำขอเหล่านั้นก็ได้รับการรับรองความถูกต้องและอนุญาตแล้ว ดังนั้นสิ่งที่คุณต้องทำคือเขียนโค้ดที่เป็นประโยชน์ทางธุรกิจ

ฟังดูเข้าท่า? มาดูข้างในกันดีกว่า!

การรับรองความถูกต้องด้วย Auth0

ในฐานะเซิร์ฟเวอร์สำหรับการจัดการข้อมูลประจำตัวและการเข้าถึง เราจะใช้ Auth0 ซึ่งมีเวอร์ชันทดลอง ใช้งานง่าย และฉันก็ชอบมัน อย่างไรก็ตาม หลักการเดียวกันนี้สามารถนำไปใช้กับหลักการอื่นๆ ได้ การใช้งาน OpenID Connect: KeyCloak, IdentityServer และอื่นๆ อีกมากมาย

หากต้องการเริ่มต้นให้ไปที่ พอร์ทัล Auth0 ด้วยบัญชีของคุณ สร้างผู้เช่า (ผู้เช่า - “ผู้เช่า” ซึ่งเป็นหน่วยตรรกะของการแยก ดูรายละเอียดเพิ่มเติมได้ เอกสาร - ประมาณ แปล.) และไปที่ แอปพลิเคชัน > แอปเริ่มต้นการเลือก โดเมนดังที่แสดงในภาพหน้าจอด้านล่าง:

กลับไปสู่ไมโครเซอร์วิสด้วย Istio ส่วนที่ 3

ระบุโดเมนนี้ในไฟล์ resource-manifests/istio/security/auth-policy.yaml (แหล่งที่มา):

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

ด้วยทรัพยากรดังกล่าว ไพล็อต (หนึ่งในสามองค์ประกอบพื้นฐานของ Control Plane ใน Istio - การแปลโดยประมาณ) กำหนดค่า Envoy เพื่อตรวจสอบสิทธิ์คำขอก่อนส่งต่อไปยังบริการ: sa-web-app и sa-feedback. ในเวลาเดียวกัน การกำหนดค่าจะไม่นำไปใช้กับทูตบริการ sa-frontendทำให้เราออกจากส่วนหน้าโดยไม่ผ่านการตรวจสอบสิทธิ์ หากต้องการใช้นโยบายให้รันคำสั่ง:

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

กลับไปที่หน้าและทำการร้องขอ - คุณจะเห็นว่ามันลงท้ายด้วยสถานะ 401 ไม่ได้รับอนุญาต. ตอนนี้เรามาเปลี่ยนเส้นทางผู้ใช้ส่วนหน้าเพื่อตรวจสอบสิทธิ์กับ Auth0

กำลังตรวจสอบคำขอด้วย Auth0

ในการตรวจสอบสิทธิ์คำขอของผู้ใช้ คุณต้องสร้าง API ใน Auth0 ซึ่งจะแสดงบริการที่ได้รับการตรวจสอบสิทธิ์ (บทวิจารณ์ รายละเอียด และการให้คะแนน) หากต้องการสร้าง API ให้ไปที่ พอร์ทัล Auth0 > API > สร้าง API และกรอกแบบฟอร์ม:

กลับไปสู่ไมโครเซอร์วิสด้วย Istio ส่วนที่ 3

ข้อมูลสำคัญที่นี่คือ ตัวบ่งชี้ซึ่งเราจะใช้ในภายหลังในสคริปต์ ลองเขียนมันลงไปดังนี้:

  • ผู้ชม: {YOUR_AUDIENCE}

รายละเอียดที่เหลือที่เราต้องการจะอยู่ที่ Auth0 Portal ในส่วนนี้ การใช้งาน - เลือก ใบสมัครสอบ (สร้างขึ้นโดยอัตโนมัติพร้อมกับ API)

ที่นี่เราจะเขียน:

  • โดเมน: {ของคุณ_DOMAIN}
  • รหัสลูกค้า: {ของคุณ_CLIENT_ID}

เลื่อนไปที่ ใบสมัครสอบ ไปที่ช่องข้อความ URL การติดต่อกลับที่อนุญาต (URL ที่แก้ไขแล้วสำหรับการโทรกลับ) ซึ่งเราระบุ URL ที่ควรส่งการโทรหลังจากการรับรองความถูกต้องเสร็จสิ้น ในกรณีของเราคือ:

http://{EXTERNAL_IP}/callback

และสำหรับ URL ออกจากระบบที่อนุญาต (URL ที่อนุญาตสำหรับการออกจากระบบ) เพิ่ม:

http://{EXTERNAL_IP}/logout

มาต่อที่ส่วนหน้ากันดีกว่า

อัปเดตส่วนหน้า

เปลี่ยนไปสาขา auth0 ที่เก็บ [istio-mastery]. ในสาขานี้ รหัสส่วนหน้าจะเปลี่ยนไปเพื่อเปลี่ยนเส้นทางผู้ใช้ไปที่ Auth0 เพื่อตรวจสอบสิทธิ์ และใช้โทเค็น JWT ในคำขอไปยังบริการอื่น ๆ หลังมีการดำเนินการดังต่อไปนี้ (แอป 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));
}

หากต้องการเปลี่ยนส่วนหน้าเพื่อใช้ข้อมูลผู้เช่าใน Auth0 ให้เปิด sa-frontend/src/services/Auth.js และแทนที่ค่าที่เราเขียนไว้ด้านบน (Auth.js):

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

ใบสมัครพร้อมแล้ว ระบุ Docker ID ของคุณในคำสั่งด้านล่างเมื่อสร้างและปรับใช้การเปลี่ยนแปลงที่ทำ:

$ 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

ลองใช้แอป! คุณจะถูกนำไปที่ Auth0 ซึ่งคุณต้องเข้าสู่ระบบ (หรือลงทะเบียน) หลังจากนั้นคุณจะถูกส่งกลับไปยังหน้าซึ่งจะมีการส่งคำขอที่ได้รับการตรวจสอบสิทธิ์แล้ว หากคุณลองใช้คำสั่งที่กล่าวถึงในส่วนแรกของบทความด้วย curl คุณจะได้รับโค้ด 401 รหัสสถานะเป็นการส่งสัญญาณว่าคำขอไม่ได้รับอนุญาต

ขั้นต่อไป - อนุมัติคำขอ

การอนุญาตด้วย Auth0

การตรวจสอบสิทธิ์ช่วยให้เราเข้าใจว่าผู้ใช้คือใคร แต่ต้องได้รับอนุมัติก่อนจึงจะรู้ว่าพวกเขาเข้าถึงอะไรได้บ้าง Istio มีเครื่องมือสำหรับสิ่งนี้ด้วย

ตามตัวอย่าง เรามาสร้างกลุ่มผู้ใช้สองกลุ่ม (ดูแผนภาพด้านล่าง):

  • สมาชิก (ผู้ใช้) — เข้าถึงได้เฉพาะบริการ SA-WebApp และ SA-Frontend เท่านั้น
  • ผู้ดูแล (ผู้ดูแล) — พร้อมการเข้าถึงบริการทั้งสามอย่าง

กลับไปสู่ไมโครเซอร์วิสด้วย Istio ส่วนที่ 3
แนวคิดเรื่องการอนุญาต

ในการสร้างกลุ่มเหล่านี้ เราจะใช้ส่วนขยาย Auth0 Authorization และใช้ Istio เพื่อมอบสิทธิ์การเข้าถึงระดับต่างๆ

การติดตั้งและการกำหนดค่าของการอนุญาต Auth0

ในพอร์ทัล Auth0 ไปที่ส่วนขยาย (ส่วนขยาย) และติดตั้ง การอนุญาต Auth0. หลังจากติดตั้งแล้วให้ไปที่ การขยายเวลาการอนุญาตและไปยังการกำหนดค่าของผู้เช่าโดยคลิกที่ด้านบนขวาแล้วเลือกตัวเลือกเมนูที่เหมาะสม (การกำหนดค่า). เปิดใช้งานกลุ่ม (กลุ่ม) และคลิกที่ปุ่มกฎการเผยแพร่ (กฎการเผยแพร่).

กลับไปสู่ไมโครเซอร์วิสด้วย Istio ส่วนที่ 3

สร้างกลุ่ม

ในส่วนขยายการอนุญาตไปที่ กลุ่ม และสร้างกลุ่ม moderators. เนื่องจากเราจะปฏิบัติต่อผู้ใช้ที่ได้รับการตรวจสอบสิทธิ์ทั้งหมดในฐานะผู้ใช้ทั่วไป จึงไม่จำเป็นต้องสร้างกลุ่มเพิ่มเติมสำหรับพวกเขา

เลือกกลุ่ม moderators, กด เพิ่มสมาชิกเพิ่มบัญชีหลักของคุณ ปล่อยให้ผู้ใช้บางรายไม่มีกลุ่มใดๆ เพื่อให้แน่ใจว่าพวกเขาจะถูกปฏิเสธการเข้าถึง (ผู้ใช้ใหม่สามารถสร้างได้ด้วยตนเองผ่านทาง พอร์ทัล Auth0 > ผู้ใช้ > สร้างผู้ใช้.)

เพิ่มการอ้างสิทธิ์กลุ่มในโทเค็นการเข้าถึง

เพิ่มผู้ใช้ในกลุ่มแล้ว แต่ข้อมูลนี้จะต้องสะท้อนให้เห็นในโทเค็นการเข้าถึงด้วย เพื่อให้สอดคล้องกับ OpenID Connect และในขณะเดียวกันก็ส่งคืนกลุ่มที่เราต้องการ โทเค็นจะต้องเพิ่มของตัวเอง การเรียกร้องที่กำหนดเอง. ดำเนินการผ่านกฎ Auth0

หากต้องการสร้างกฎ ให้ไปที่ Auth0 Portal ไปที่ กฎระเบียบ, กด สร้างกฎ และเลือกกฎว่างจากเทมเพลต

กลับไปสู่ไมโครเซอร์วิสด้วย Istio ส่วนที่ 3

คัดลอกโค้ดด้านล่างและบันทึกเป็นกฎใหม่ เพิ่มการอ้างสิทธิ์แบบกลุ่ม (เนมสเปซกรุ๊ป.js):

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

หมายเหตุ: รหัสนี้รับกลุ่มผู้ใช้กลุ่มแรกที่กำหนดไว้ในส่วนขยายการอนุญาตและเพิ่มลงในโทเค็นการเข้าถึงเป็นการอ้างสิทธิ์ที่กำหนดเอง (ใต้เนมสเปซ ตามที่กำหนดโดย Auth0)

กลับไปที่หน้า กฎระเบียบ และตรวจสอบว่าคุณมีกฎสองข้อที่เขียนตามลำดับต่อไปนี้:

  • auth0-การอนุญาต-ส่วนขยาย
  • เพิ่มการอ้างสิทธิ์แบบกลุ่ม

ลำดับมีความสำคัญเนื่องจากฟิลด์กลุ่มได้รับกฎแบบอะซิงโครนัส auth0-การอนุญาต-ส่วนขยาย และหลังจากนั้นก็เพิ่มเป็นการเรียกร้องตามกฎข้อที่สอง ผลลัพธ์ที่ได้คือโทเค็นการเข้าถึงดังนี้:

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

ตอนนี้คุณต้องกำหนดค่าพร็อกซี Envoy เพื่อตรวจสอบการเข้าถึงของผู้ใช้ ซึ่งกลุ่มจะถูกดึงออกจากการอ้างสิทธิ์ (https://sa.io/group) ในโทเค็นการเข้าถึงที่ส่งคืน นี่คือหัวข้อสำหรับส่วนถัดไปของบทความ

การกำหนดค่าการอนุญาตใน Istio

เพื่อให้การอนุญาตทำงาน คุณต้องเปิดใช้งาน RBAC สำหรับ Istio เมื่อต้องการทำเช่นนี้ เราจะใช้การกำหนดค่าต่อไปนี้:

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" 

คำอธิบาย:

  • 1 — เปิดใช้งาน RBAC สำหรับบริการและเนมสเปซที่แสดงอยู่ในฟิลด์เท่านั้น Inclusion;
  • 2 — เราแสดงรายการบริการของเรา

ลองใช้การกำหนดค่าด้วยคำสั่งต่อไปนี้:

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

บริการทั้งหมดจำเป็นต้องมีการควบคุมการเข้าถึงตามบทบาท กล่าวอีกนัยหนึ่ง ห้ามเข้าถึงบริการทั้งหมดและจะส่งผลให้เกิดการตอบสนอง RBAC: access denied. ตอนนี้ให้อนุญาตการเข้าถึงแก่ผู้ใช้ที่ได้รับอนุญาต

การกำหนดค่าการเข้าถึงสำหรับผู้ใช้ทั่วไป

ผู้ใช้ทุกคนต้องมีสิทธิ์เข้าถึงบริการ SA-Frontend และ SA-WebApp ใช้งานโดยใช้ทรัพยากร Istio ต่อไปนี้:

  • บทบาทการบริการ — กำหนดสิทธิ์ที่ผู้ใช้มี
  • ServiceRoleBinding — กำหนดว่า ServiceRole นี้เป็นของใคร

สำหรับผู้ใช้ทั่วไปเราจะอนุญาตให้เข้าถึงบริการบางอย่าง (servicerole.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: ["*"]

และหลังจากนั้น regular-user-binding ใช้ ServiceRole กับผู้เยี่ยมชมเพจทั้งหมด (บริการผู้ใช้ปกติ-role-binding.yaml):

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

"ผู้ใช้ทั้งหมด" หมายความว่าผู้ใช้ที่ไม่ได้รับการรับรองความถูกต้องจะสามารถเข้าถึง SA WebApp ได้หรือไม่ ไม่ นโยบายจะตรวจสอบความถูกต้องของโทเค็น JWT

ลองใช้การกำหนดค่า:

$ 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

การกำหนดค่าการเข้าถึงสำหรับผู้ดูแล

สำหรับผู้ดูแล เราต้องการเปิดใช้งานการเข้าถึงบริการทั้งหมด (mod-บริการ-role.yaml):

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

แต่เราต้องการสิทธิ์ดังกล่าวสำหรับผู้ใช้ที่มีโทเค็นการเข้าถึงที่มีการอ้างสิทธิ์เท่านั้น https://sa.io/group ด้วยความหมาย Moderators (mod-บริการบทบาทbinding.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" 

ลองใช้การกำหนดค่า:

$ 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

เนื่องจากการแคชทูต อาจใช้เวลาสองสามนาทีก่อนที่กฎการให้สิทธิ์จะมีผล จากนั้นคุณสามารถมั่นใจได้ว่าผู้ใช้และผู้ตรวจสอบมีระดับการเข้าถึงที่แตกต่างกัน

บทสรุปในส่วนนี้

จริงๆ แล้วคุณเคยเห็นวิธีการที่ง่ายกว่า ง่ายดาย ปรับขนาดได้ และปลอดภัยในการรับรองความถูกต้องและการอนุญาตหรือไม่?

ต้องใช้ทรัพยากร Istio เพียง XNUMX รายการเท่านั้น (RbacConfig, ServiceRole และ ServiceRoleBinding) เพื่อให้สามารถควบคุมการตรวจสอบสิทธิ์และการอนุญาตการเข้าถึงบริการของผู้ใช้ปลายทางได้อย่างละเอียด

นอกจากนี้ เราได้ดูแลปัญหาเหล่านี้ด้วยบริการทูตของเรา เพื่อให้บรรลุเป้าหมาย:

  • ลดจำนวนรหัสทั่วไปที่อาจมีปัญหาด้านความปลอดภัยและข้อบกพร่อง
  • ลดจำนวนสถานการณ์โง่ ๆ ที่ปลายทางหนึ่งสามารถเข้าถึงได้จากภายนอกและลืมรายงาน
  • ไม่จำเป็นต้องอัปเดตบริการทั้งหมดทุกครั้งที่มีการเพิ่มบทบาทหรือสิทธิ์ใหม่
  • บริการใหม่ๆ ยังคงเรียบง่าย ปลอดภัย และรวดเร็ว

เอาท์พุต

Istio ช่วยให้ทีมมุ่งความสนใจไปที่ทรัพยากรของตนไปที่งานที่สำคัญต่อธุรกิจได้โดยไม่ต้องเพิ่มค่าใช้จ่ายในการบริการ และเปลี่ยนกลับเป็นสถานะย่อย

บทความนี้ (แบ่งออกเป็น XNUMX ส่วน) ให้ความรู้พื้นฐานและคำแนะนำเชิงปฏิบัติแบบสำเร็จรูปสำหรับการเริ่มต้นใช้งาน Istio ในโครงการจริง

ปล.จากผู้แปล

อ่านเพิ่มเติมในบล็อกของเรา:

ที่มา: will.com

เพิ่มความคิดเห็น