Kembali ke layanan mikro dengan Istio. Bagian 3

Kembali ke layanan mikro dengan Istio. Bagian 3

Catatan. terjemahan: Bagian pertama seri ini dikhususkan untuk mengenal kemampuan Istio dan mendemonstrasikannya dalam tindakan, kedua β€” perutean yang disetel dengan baik dan manajemen lalu lintas jaringan. Sekarang kita akan berbicara tentang keamanan: untuk mendemonstrasikan fungsi dasar yang terkait dengannya, penulis menggunakan layanan identitas Auth0, namun penyedia lain dapat dikonfigurasi dengan cara yang sama.

Kami menyiapkan kluster Kubernetes tempat kami menerapkan Istio dan contoh aplikasi layanan mikro, Analisis Sentimen, untuk menunjukkan kemampuan Istio.

Dengan Istio, kami dapat menjaga layanan kami tetap kecil karena tidak perlu mengimplementasikan lapisan seperti Percobaan Ulang, Batas Waktu, Pemutus Sirkuit, Penelusuran, Pemantauan. . Selain itu, kami menggunakan teknik pengujian dan penerapan tingkat lanjut: pengujian A/B, mirroring, dan peluncuran canary.

Kembali ke layanan mikro dengan Istio. Bagian 3

Dalam materi baru, kita akan membahas lapisan terakhir dalam perjalanan menuju nilai bisnis: autentikasi dan otorisasi - dan di Istio ini sungguh menyenangkan!

Otentikasi dan otorisasi di Istio

Saya tidak pernah percaya bahwa saya akan terinspirasi oleh otentikasi dan otorisasi. Apa yang bisa Istio tawarkan dari sudut pandang teknologi untuk menjadikan topik ini menyenangkan dan, terlebih lagi, menginspirasi Anda?

Jawabannya sederhana: Istio mengalihkan tanggung jawab atas kemampuan ini dari layanan Anda ke proxy Utusan. Pada saat permintaan mencapai layanan, permintaan tersebut telah diautentikasi dan diotorisasi, jadi yang perlu Anda lakukan hanyalah menulis kode yang berguna untuk bisnis.

Kedengarannya bagus? Mari kita lihat ke dalam!

Otentikasi dengan Auth0

Sebagai server untuk manajemen identitas dan akses, kami akan menggunakan Auth0, yang memiliki versi uji coba, intuitif untuk digunakan dan saya menyukainya. Namun, prinsip yang sama dapat diterapkan pada prinsip lainnya Implementasi OpenID Connect: KeyCloak, IdentityServer dan banyak lainnya.

Untuk memulai, buka Portal Auth0 dengan akun Anda, buat penyewa (penyewa - "penyewa", unit isolasi logis, untuk lebih jelasnya lihat dokumentasi - kira-kira. terjemahkan) dan pergi ke Aplikasi > Aplikasi Defaultmemilih Domain, seperti yang ditunjukkan pada tangkapan layar di bawah ini:

Kembali ke layanan mikro dengan Istio. Bagian 3

Tentukan domain ini dalam file resource-manifests/istio/security/auth-policy.yaml (sumber):

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

Dengan sumber daya seperti itu, Pilot (salah satu dari tiga komponen dasar Control Plane di Istio - kira-kira terjemahan) mengonfigurasi Utusan untuk mengautentikasi permintaan sebelum meneruskannya ke layanan: sa-web-app ΠΈ sa-feedback. Pada saat yang sama, konfigurasi tidak diterapkan pada layanan Utusan sa-frontend, memungkinkan kita membiarkan frontend tidak diautentikasi. Untuk menerapkan Kebijakan, jalankan perintah:

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

Kembali ke halaman dan buat permintaan - Anda akan melihat bahwa itu diakhiri dengan status 401 Tidak Resmi. Sekarang mari kita arahkan ulang pengguna frontend untuk mengautentikasi dengan Auth0.

Mengautentikasi permintaan dengan Auth0

Untuk mengautentikasi permintaan pengguna akhir, Anda perlu membuat API di Auth0 yang akan mewakili layanan yang diautentikasi (ulasan, detail, dan peringkat). Untuk membuat API, buka Portal Auth0 > API > Buat API dan isi formulir:

Kembali ke layanan mikro dengan Istio. Bagian 3

Informasi penting di sini adalah mengenali, yang akan kita gunakan nanti di skrip. Mari kita tuliskan seperti ini:

  • Para penonton: {ANDA_ANDA}

Detail lainnya yang kami perlukan terdapat di Portal Auth0 di bagian tersebut Aplikasi - Pilih Aplikasi Tes (dibuat secara otomatis bersama dengan API).

Di sini kami akan menulis:

  • Domain: {DOMAIN_ANDA}
  • ID Klien: {YOUR_CLIENT_ID}

Gulir ke Aplikasi Tes ke bidang teks URL Panggilan Balik yang Diizinkan (URL terselesaikan untuk panggilan balik), di mana kami menentukan URL tujuan pengiriman panggilan setelah otentikasi selesai. Dalam kasus kami, ini adalah:

http://{EXTERNAL_IP}/callback

Dan untuk URL Keluar yang Diizinkan (URL yang diizinkan untuk keluar) tambahkan:

http://{EXTERNAL_IP}/logout

Mari beralih ke bagian depan.

Pembaruan bagian depan

Beralih ke cabang auth0 gudang [istio-mastery]. Di cabang ini, kode frontend diubah untuk mengarahkan pengguna ke Auth0 untuk otentikasi dan menggunakan token JWT dalam permintaan ke layanan lain. Yang terakhir ini diimplementasikan sebagai berikut (aplikasi.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));
}

Untuk mengubah frontend agar menggunakan data penyewa di Auth0, buka sa-frontend/src/services/Auth.js dan ganti di dalamnya nilai-nilai yang kita tulis di atas (Auth.js):

const Config = {
    clientID: '{YOUR_CLIENT_ID}',
    domain:'{YOUR_DOMAIN}',
    audience: '{YOUR_AUDIENCE}',
    ingressIP: '{EXTERNAL_IP}' // Π˜ΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ для Ρ€Π΅Π΄ΠΈΡ€Π΅ΠΊΡ‚Π° послС Π°ΡƒΡ‚Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ†ΠΈΠΈ
}

Aplikasi sudah siap. Tentukan ID Docker Anda pada perintah di bawah ini saat membuat dan menerapkan perubahan yang dibuat:

$ 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

Coba aplikasinya! Anda akan diarahkan ke Auth0, di mana Anda harus masuk (atau mendaftar), setelah itu Anda akan dikirim kembali ke halaman tempat permintaan yang sudah diautentikasi akan dibuat. Jika Anda mencoba perintah yang disebutkan di bagian pertama artikel dengan curl, Anda akan mendapatkan kodenya 401 Kode Status, menandakan bahwa permintaan tersebut tidak diotorisasi.

Mari kita ambil langkah selanjutnya - mengotorisasi permintaan.

Otorisasi dengan Auth0

Otentikasi memungkinkan kita memahami siapa penggunanya, tetapi otorisasi diperlukan untuk mengetahui akses apa yang mereka miliki. Istio juga menawarkan alat untuk ini.

Sebagai contoh, mari buat dua grup pengguna (lihat diagram di bawah):

  • Anggota (pengguna) β€” dengan akses hanya ke layanan SA-WebApp dan SA-Frontend;
  • moderator (moderator) β€” dengan akses ke ketiga layanan.

Kembali ke layanan mikro dengan Istio. Bagian 3
Konsep otorisasi

Untuk membuat grup ini, kami akan menggunakan ekstensi Otorisasi Auth0 dan menggunakan Istio untuk memberi mereka tingkat akses yang berbeda.

Instalasi dan konfigurasi Otorisasi Auth0

Di portal Auth0, buka ekstensi (Ekstensi) dan instal Otorisasi Auth0. Setelah instalasi, buka Perpanjangan Otorisasi, dan di sana - ke konfigurasi penyewa dengan mengklik kanan atas dan memilih opsi menu yang sesuai (Konfigurasi). Aktifkan grup (Grup) dan klik tombol terbitkan aturan (Publikasikan aturan).

Kembali ke layanan mikro dengan Istio. Bagian 3

Buat grup

Di Ekstensi Otorisasi, buka Grup dan membuat grup Moderator. Karena kami akan memperlakukan semua pengguna yang diautentikasi sebagai pengguna biasa, tidak perlu membuat grup tambahan untuk mereka.

Pilih grup Moderator, Tekan Tambahkan Anggota, tambahkan akun utama Anda. Biarkan beberapa pengguna tanpa grup apa pun untuk memastikan akses mereka ditolak. (Pengguna baru dapat dibuat secara manual melalui Portal Auth0 > Pengguna > Buat Pengguna.)

Tambahkan Klaim Grup ke Token Akses

Pengguna telah ditambahkan ke grup, namun informasi ini juga harus tercermin dalam token akses. Untuk mematuhi OpenID Connect dan pada saat yang sama mengembalikan grup yang kita perlukan, token perlu menambahkan grupnya sendiri klaim khusus. Diimplementasikan melalui aturan Auth0.

Untuk membuat aturan, buka Portal Auth0 ke Peraturan, Tekan Buat Aturan dan pilih aturan kosong dari templat.

Kembali ke layanan mikro dengan Istio. Bagian 3

Salin kode di bawah ini dan simpan sebagai aturan baru Tambahkan Klaim Grup (namespacedGroup.js):

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

Catatan: Kode ini mengambil grup pengguna pertama yang ditentukan dalam Ekstensi Otorisasi dan menambahkannya ke token akses sebagai klaim khusus (di bawah namespacenya, seperti yang diwajibkan oleh Auth0).

Kembali ke halaman Peraturan dan periksa apakah Anda memiliki dua aturan yang ditulis dalam urutan berikut:

  • ekstensi-otorisasi-auth0
  • Tambahkan Klaim Grup

Urutan ini penting karena bidang grup menerima aturan secara asinkron ekstensi-otorisasi-auth0 dan setelah itu ditambahkan sebagai tuntutan menurut aturan kedua. Hasilnya adalah token akses seperti ini:

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

Sekarang Anda perlu mengkonfigurasi proxy Utusan untuk memeriksa akses pengguna, yang grupnya akan ditarik dari klaim (https://sa.io/group) di token akses yang dikembalikan. Ini adalah topik untuk bagian artikel selanjutnya.

Konfigurasi otorisasi di Istio

Agar otorisasi berfungsi, Anda harus mengaktifkan RBAC untuk Istio. Untuk melakukan ini, kita akan menggunakan konfigurasi berikut:

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" 

Penjelasan:

  • 1 β€” aktifkan RBAC hanya untuk layanan dan namespace yang tercantum di kolom Inclusion;
  • 2 β€” kami mencantumkan daftar layanan kami.

Mari terapkan konfigurasi dengan perintah berikut:

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

Semua layanan sekarang memerlukan Kontrol Akses Berbasis Peran. Dengan kata lain, akses terhadap semua layanan dilarang dan akan menimbulkan tanggapan RBAC: access denied. Sekarang mari izinkan akses ke pengguna yang berwenang.

Konfigurasi akses untuk pengguna biasa

Semua pengguna harus memiliki akses ke layanan SA-Frontend dan SA-WebApp. Diimplementasikan menggunakan sumber daya Istio berikut:

  • Peran Layanan β€” menentukan hak yang dimiliki pengguna;
  • Pengikatan Peran Layanan β€” menentukan milik siapa ServiceRole ini.

Untuk pengguna biasa kami akan mengizinkan akses ke layanan tertentu (peran layanan.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: ["*"]

Dan kemudian regular-user-binding terapkan ServiceRole ke semua pengunjung halaman (pengikatan peran-pengguna-reguler.yaml):

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

Apakah "semua pengguna" berarti bahwa pengguna yang tidak diautentikasi juga akan memiliki akses ke SA WebApp? Tidak, kebijakan akan memeriksa validitas token JWT.

Mari terapkan konfigurasinya:

$ 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

Konfigurasi akses untuk moderator

Untuk moderator, kami ingin mengaktifkan akses ke semua layanan (mod-layanan-peran.yaml):

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

Namun kami menginginkan hak tersebut hanya untuk pengguna yang token aksesnya berisi klaim https://sa.io/group dengan makna Moderators (mod-layanan-peran-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" 

Mari terapkan konfigurasinya:

$ 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

Karena adanya cache di utusan, mungkin diperlukan waktu beberapa menit agar aturan otorisasi diterapkan. Anda kemudian dapat memastikan bahwa pengguna dan moderator memiliki tingkat akses yang berbeda.

Kesimpulan pada bagian ini

Namun serius, pernahkah Anda melihat pendekatan autentikasi dan otorisasi yang lebih sederhana, mudah, terukur, dan aman?

Hanya tiga sumber daya Istio (RbacConfig, ServiceRole, dan ServiceRoleBinding) yang diperlukan untuk mencapai kontrol menyeluruh atas autentikasi dan otorisasi akses pengguna akhir ke layanan.

Selain itu, kami telah menangani masalah ini melalui layanan utusan kami, dengan mencapai:

  • mengurangi jumlah kode generik yang mungkin mengandung masalah keamanan dan bug;
  • mengurangi jumlah situasi bodoh di mana satu titik akhir ternyata dapat diakses dari luar dan lupa melaporkannya;
  • menghilangkan kebutuhan untuk memperbarui semua layanan setiap kali peran atau hak baru ditambahkan;
  • bahwa layanan baru tetap sederhana, aman dan cepat.

Keluaran

Istio memungkinkan tim untuk memfokuskan sumber daya mereka pada tugas-tugas penting bisnis tanpa menambah biaya tambahan pada layanan, sehingga mengembalikannya ke status mikro.

Artikel (dalam tiga bagian) memberikan pengetahuan dasar dan instruksi praktis siap pakai untuk memulai Istio dalam proyek nyata.

PS dari penerjemah

Baca juga di blog kami:

Sumber: www.habr.com

Tambah komentar