Service Mesh (ASM) terintegrasi dengan Plugin Open Policy Agent (OPA). Anda dapat menggunakan OPA untuk mendefinisikan kebijakan kontrol akses guna menerapkan kontrol akses granular halus pada aplikasi Anda. ASM memungkinkan Anda mendefinisikan kebijakan OPA di bidang kontrol dan mendorong kebijakan tersebut ke kluster pada bidang data. Topik ini menjelaskan cara mendefinisikan kebijakan OPA di ASM untuk menerapkan kontrol akses granular halus pada aplikasi Anda. Sebagai contoh, Anda dapat mendefinisikan kebijakan OPA untuk mengizinkan atau memblokir permintaan berdasarkan URL permintaan atau token dalam header permintaan. Topik ini juga menyediakan skenario contoh di mana kebijakan OPA digunakan untuk menerapkan kontrol akses.
Prasyarat
Sebuah instance ASM versi 1.9.7 atau yang lebih baru telah dibuat. Untuk informasi lebih lanjut, lihat Buat instance ASM.
Injeksi proxy sidecar otomatis diaktifkan untuk namespace default. Untuk informasi lebih lanjut, lihat bagian "Aktifkan injeksi proxy sidecar otomatis" dari topik Kelola namespace global.
Informasi latar belakang
OPA adalah proyek Lulus dari Cloud Native Computing Foundation (CNCF). Sebagai mesin kebijakan, OPA dapat digunakan untuk menerapkan kontrol akses granular halus pada aplikasi Anda. Anda dapat menerapkan OPA sebagai layanan mandiri bersama dengan mikro layanan. Untuk melindungi aplikasi, pastikan bahwa setiap permintaan ke mikro layanan aplikasi diotorisasi sebelum permintaan diproses. Untuk memeriksa otorisasi, mikro layanan membuat panggilan API ke OPA untuk memeriksa apakah permintaan tersebut diotorisasi.
Langkah 1: Aktifkan plugin OPA dan fitur pengendalian ruang lingkup injeksi OPA
Masuk ke Konsol ASM. Di panel navigasi di sebelah kiri, pilih .
Di halaman Mesh Management, klik nama instance ASM. Di panel navigasi di sebelah kiri, pilih .
Di halaman OPA Policy, pilih Enable Open Policy Agent (OPA) Plug-in dan Enable OPA Injection Range Control, lalu klik Enable OPA. Di pesan Note, klik OK.
Langkah 2: Buat kebijakan OPA
Setelah Anda membuat kebijakan OPA di bidang kontrol instance ASM, kebijakan OPA didorong ke kluster pada bidang data. Kemudian, OPA di pod kluster menggunakan kebijakan OPA untuk menerapkan kontrol akses granular halus. Anda dapat membuat kebijakan OPA dengan menggunakan metode berikut:
Metode 1: Buat kebijakan OPA di konsol ASM
Masuk ke Konsol ASM. Di panel navigasi di sebelah kiri, pilih .
Di halaman Mesh Management, klik nama instance ASM. Di panel navigasi di sebelah kiri, pilih .
Di halaman OPA Policy, klik Create, pilih default dari daftar drop-down Namespace, atur Name menjadi bookinfo-opa, lalu klik Add Matching Label. Di bagian Label Pencocokan, atur Name menjadi version dan Value menjadi v1. Salin konten berikut ke editor kode Rego Rule, lalu klik Create.
Metode 2: Buat kebijakan OPA menggunakan kubectl
Buat file opa.yaml yang berisi konten berikut:
CatatanSaat Anda mendefinisikan kebijakan OPA untuk pod, pastikan hanya satu kebijakan OPA yang berisi bidang
default allow. Jika beberapa kebijakan OPA berlaku untuk pod dan bidangdefault allowdidefinisikan di setiap kebijakan OPA, kebijakan OPA gagal diperbarui secara dinamis karena adanya beberapa bidangdefault allow.Kami menyarankan Anda menggunakan label untuk menentukan ruang lingkup efektif kebijakan OPA saat Anda mendefinisikan kebijakan OPA. Kebijakan Rego yang tidak valid membuat layanan tidak dapat diakses.
OPA berada di pod yang sama dengan kontainer bisnis dan menggunakan port 15081 dan 9191.
Secara default, bidang
default allowdalam kebijakan OPA disetel ke false. Jangan atur ulang bidangdefault allow. Jika tidak, akan terjadi konflik. Tabel berikut menjelaskan beberapa parameter file opa.yaml.
Parameter
Deskripsi
specKonten kebijakan yang ditulis dalam Rego. Untuk informasi lebih lanjut tentang sintaks Rego, lihat Bahasa Kebijakan.
workloadSelectorRuang lingkup efektif kebijakan OPA di namespace tertentu. Secara default, kebijakan OPA berlaku untuk semua pod di namespace. Setelah Anda mengatur parameter ini, kebijakan OPA hanya berlaku untuk pod dengan label tertentu.
user_rolesPeran yang ditetapkan kepada pengguna. Dalam contoh ini, peran tamu diberikan kepada pengguna guest1, dan peran admin diberikan kepada pengguna admin1.
role_permsIzin setiap peran. Dalam contoh ini, peran tamu diberikan izin untuk mengakses aplikasi menggunakan URL yang berisi /productpage, dan peran admin diberikan izin untuk mengakses aplikasi menggunakan URL yang berisi /productpage atau /api/v1/products.
Jalankan perintah berikut untuk membuat kebijakan OPA.
Untuk informasi lebih lanjut tentang cara menggunakan kubectl untuk terhubung ke instance ASM, lihat Gunakan kubectl di bidang kontrol untuk mengakses sumber daya Istio.
kubectl apply -f opa.yaml
Langkah 3: Suntikkan OPA
Sebarkan aplikasi sampel Bookinfo di instance ASM dan periksa apakah OPA disuntikkan ke setiap pod aplikasi Bookinfo.
Sebarkan aplikasi Bookinfo di instance ASM. Untuk informasi lebih lanjut, lihat Sebarkan aplikasi di instance ASM.
Buat gateway ingress, gateway Istio, dan layanan virtual. Untuk informasi lebih lanjut, lihat Gunakan sumber daya Istio untuk merutekan lalu lintas ke versi layanan yang berbeda.
Periksa apakah OPA disuntikkan ke pod setiap aplikasi dalam aplikasi Bookinfo.
Masuk ke Konsol ACK. Di panel navigasi di sebelah kiri, klik Clusters.
Di halaman Clusters, temukan kluster yang diinginkan dan klik namanya. Di panel di sebelah kiri, pilih .
Di halaman Pods, pilih default dari daftar drop-down Namespace dan klik nama pod aplikasi yang diinginkan.
Di tab Container, Anda dapat menemukan bahwa proxy sidecar bernama istio-proxy dan OPA bernama opa-istio disuntikkan ke setiap container. Periksa container setiap aplikasi secara bergantian untuk memastikan bahwa proxy sidecar dan OPA disuntikkan ke setiap container.

Langkah 4: Verifikasi bahwa kebijakan OPA menerapkan kontrol akses sesuai harapan
Jalankan perintah berikut untuk mengakses aplikasi menggunakan URL yang berisi /productpage:
curl -X GET http://<Alamat IP gateway ingress>/productpage --user guest1:password -IOutput yang diharapkan:
HTTP/1.1 200 OKJalankan perintah berikut untuk mengakses aplikasi menggunakan URL yang berisi
/api/v1/products:curl -X GET http://<Alamat IP gateway ingress>/api/v1/products --user guest1:password -IOutput yang diharapkan:
HTTP/1.1 403 ForbiddenHasil yang diharapkan menunjukkan bahwa peran tamu diberikan kepada pengguna guest1 dan pengguna guest1 memiliki izin untuk mengakses aplikasi menggunakan URL yang berisi
/productpage, tetapi tidak menggunakan URL yang berisi/api/v1/products.Jalankan perintah berikut untuk mengakses aplikasi menggunakan URL yang berisi
/productpage:curl -X GET http://{{Alamat IP gateway ingress}}/productpage --user admin1:password -IOutput yang diharapkan:
HTTP/1.1 200 OKJalankan perintah berikut untuk mengakses aplikasi menggunakan URL yang berisi
/api/v1/products:curl -X GET http://<Alamat IP gateway ingress>/api/v1/products --user admin1:password -IOutput yang diharapkan:
HTTP/1.1 200 OKHasil yang diharapkan menunjukkan bahwa peran admin diberikan kepada pengguna admin1 dan pengguna admin1 memiliki izin untuk mengakses aplikasi menggunakan URL yang berisi
/productpageatau/api/v1/products. Hasil sebelumnya menunjukkan bahwa kebijakan OPA yang didefinisikan menerapkan kontrol akses sesuai harapan.
Langkah 5: Perbarui kebijakan OPA secara dinamis
Jalankan perintah berikut untuk masuk ke antarmuka pengeditan kebijakan OPA:
kubectl edit asmopapolicy bookinfo-opa -n default Dalam keluaran perintah, edit kebijakan OPA untuk memberikan peran tamu dan admin kepada pengguna guest1.
apiVersion: istio.alibabacloud.com/v1beta1
kind: ASMOPAPolicy
metadata:
name: bookinfo-opa
namespace: default
spec:
policy: |
package istio.authz
import input.attributes.request.http as http_request
allow {
roles_for_user[r]
required_roles[r]
}
roles_for_user[r] {
r := user_roles[user_name][_]
}
required_roles[r] {
perm := role_perms[r][_]
perm.method = http_request.method
perm.path = http_request.path
}
user_name = parsed {
[_, encoded] := split(http_request.headers.authorization, " ")
[parsed, _] := split(base64url.decode(encoded), ":")
}
user_roles = {
"guest1": ["guest", "admin"],
"admin1": ["admin"]
}
role_perms = {
"guest": [
{"method": "GET", "path": "/productpage"},
],
"admin": [
{"method": "GET", "path": "/productpage"},
{"method": "GET", "path": "/api/v1/products"},
],
}user_roles: peran yang ditetapkan kepada pengguna. Dalam contoh ini, peran tamu dan admin diberikan kepada pengguna guest1, dan peran admin diberikan kepada pengguna admin1.
role_perms: izin setiap peran. Dalam contoh ini, peran tamu diberikan izin untuk mengakses aplikasi menggunakan URL yang berisi /productpage, dan peran admin diberikan izin untuk mengakses aplikasi menggunakan URL yang berisi /productpage atau /api/v1/products.
Langkah 6: Verifikasi bahwa kebijakan OPA diperbarui secara dinamis
Jalankan perintah berikut untuk mengakses aplikasi menggunakan URL yang berisi /productpage:
curl -X GET http://<Alamat IP gateway ingress>/productpage --user guest1:password -IOutput yang diharapkan:
HTTP/1.1 200 OKJalankan perintah berikut untuk mengakses aplikasi menggunakan URL yang berisi /api/v1/products:
curl -X GET http://<Alamat IP gateway ingress>/api/v1/products --user guest1:password -IOutput yang diharapkan:
HTTP/1.1 200 OKSebelum kebijakan OPA diperbarui, pengguna guest1 dapat mengakses aplikasi menggunakan URL yang berisi /productpage, tetapi tidak /api/v1/products. Setelah kebijakan OPA diperbarui, pengguna guest1 dapat mengakses aplikasi menggunakan URL yang berisi /productpage atau /api/v1/products. Hasilnya menunjukkan bahwa kebijakan OPA diperbarui secara dinamis.
Skema contoh
Skema 1: Otentikasi permintaan dengan memeriksa JWT
Saat aplikasi menerima permintaan, OPA memeriksa JSON Web Token (JWT) di header permintaan. Permintaan untuk mengakses aplikasi diizinkan hanya jika JWT memenuhi persyaratan tertentu.
Kebijakan OPA berikut mendefinisikan bahwa permintaan untuk mengakses aplikasi Productpage diizinkan hanya jika permintaan menggunakan metode GET dan permintaan berisi JWT di mana bidang Role disetel ke guest dan bidang userGroup disetel ke visitor:
apiVersion: istio.alibabacloud.com/v1beta1
kind: ASMOPAPolicy
metadata:
name: policy-jwt
namespace: default
spec:
policy: |
package istio.authz
allow {
input.attributes.request.http.method == "GET"
input.parsed_path[0] == "productpage"
# set certificate 'B41BD5F462719C6D6118E673A2389'
io.jwt.verify_hs256(bearer_token, "B41BD5F462719C6D6118E673A2389")
claims.Role == "guest"
claims.userGroup == "visitor"
}
claims := payload {
[_, payload, _] := io.jwt.decode(bearer_token)
}
bearer_token := t {
v := input.attributes.request.http.headers.authorization
startswith(v, "Bearer ")
t := substring(v, count("Bearer "), -1)
}input.attributes.request.http.method: metode permintaan. Dalam contoh ini, nilainya disetel ke
GET.input.parsed_path[0]: aplikasi yang akan diakses.
claims.Role: nilai yang diharapkan dari bidang
Roledalam JWT. Dalam contoh ini, nilainya disetel keguest.claims.userGroup: nilai yang diharapkan dari bidang
userGroupdalam JWT. Dalam contoh ini, nilainya disetel kevisitor.
Anda dapat menggunakan alat JWT untuk mengkodekan informasi permintaan seperti bidang Role dan userGroup menjadi string JWT.
Jalankan perintah berikut untuk mengakses aplikasi Productpage:
curl --location --request GET 'http://{Alamat IP gateway ingress}/productpage' \
--header 'Authorization: Bearer
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJuYW1lIjoiZ3Vlc3QxIiwiUm9sZSI6Imd1ZXN0IiwidXNlckdyb3VwIjoidmlzaXRvciJ9.44OnUFZwOzSWzC7hyVfcle-uYk8byv7q_BBxS10AEWc'Output yang diharapkan:
200Kode status 200 dikembalikan, yang menunjukkan bahwa aplikasi Productpage dapat diakses menggunakan permintaan GET yang berisi JWT di mana bidang Role disetel ke guest dan bidang userGroup disetel ke visitor. Jika Anda menggunakan JWT yang tidak valid atau permintaan tidak berisi JWT, kode kesalahan 403 dikembalikan. Ini menunjukkan bahwa permintaan untuk mengakses aplikasi Productpage ditolak.
Skema 2: Otentikasi permintaan dengan memeriksa badan permintaan HTTP dan JWT
Anda dapat menggunakan kebijakan OPA untuk mengizinkan permintaan HTTP hanya jika nilai parameter username dalam badan permintaan sama dengan nilai bidang Role dalam JWT permintaan.
Kebijakan OPA berikut mendefinisikan bahwa permintaan untuk mengakses aplikasi Productpage diizinkan hanya jika permintaan menggunakan metode GET, nilai parameter username dalam badan permintaan sama dengan nilai bidang Role dalam JWT permintaan, dan bidang userGroup dalam JWT disetel ke manager:
apiVersion: istio.alibabacloud.com/v1beta1
kind: ASMOPAPolicy
metadata:
name: policy-body
namespace: default
spec:
policy: |
package istio.authz
allow {
input.attributes.request.http.method == "GET"
input.parsed_path[0] == "productpage"
io.jwt.verify_hs256(bearer_token, "B41BD5F462719C6D6118E673A2389")
claims.Role == input.parsed_body.username
claims.userGroup == "manager"
}
claims := payload {
[_, payload, _] := io.jwt.decode(bearer_token)
}
bearer_token := t {
v := input.attributes.request.http.headers.authorization
startswith(v, "Bearer ")
t := substring(v, count("Bearer "), -1)
}input.attributes.request.http.method: metode permintaan. Dalam contoh ini, nilainya disetel ke
GET.input.parsed_path[0]: aplikasi yang akan diakses.
claims.Role: nilai yang diharapkan dari bidang Role dalam JWT. Dalam contoh ini, nilainya disetel ke
input.parsed_body.username. Ini menunjukkan bahwa nilai parameterusernamedalam badan permintaan harus sama dengan nilai bidang Role dalam JWT permintaan.claims.userGroup: nilai yang diharapkan dari bidang
userGroupdalam JWT. Dalam contoh ini, nilainya disetel kemanager.
Anda dapat menggunakan alat JWT untuk mengkodekan informasi permintaan seperti bidang Role dan userGroup menjadi string JWT.
Jalankan perintah berikut untuk mengakses aplikasi Productpage:
curl --location --request GET 'http://{Alamat IP gateway ingress}/productpage' \
--header 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJuYW1lIjoiZ3Vlc3QxIiwiUm9sZSI6ImFkbWluIiwidXNlckdyb3VwIjoibWFuYWdlciJ9.pAUvTeONHF-i5Ps-EUYYXk-hnaz-j-ZgP_wXJZMBiR0' \
--header 'Content-Type: application/json' \
--header 'Cookie: session=eyJ1c2VyIjoiYWRtaW4ifQ.YRz90g.GT34_5BqlFTwGqabZk_qGZzxYQ0' \
--data-raw '{
"username":"admin",
"password":"12****"
Output yang diharapkan:
200Kode status 200 dikembalikan, yang menunjukkan bahwa aplikasi Productpage dapat diakses menggunakan permintaan GET yang berisi JWT di mana nilai bidang Role sama dengan nilai parameter username dalam badan permintaan dan bidang userGroup disetel ke manager. Jika Anda menggunakan JWT yang tidak valid atau permintaan tidak berisi JWT, kode kesalahan 403 dikembalikan. Ini menunjukkan bahwa permintaan untuk mengakses aplikasi Productpage ditolak.
Skema 3: Otentikasi permintaan dengan memeriksa lebih banyak informasi konteks
Anda dapat menggunakan kebijakan OPA untuk memeriksa lebih banyak informasi konteks selain informasi yang diperiksa dalam Skema 2. Dalam contoh ini, nilai bidang username dalam JWT harus masuk dalam rentang nilai yang ditentukan oleh bidang bookinfo_managers.
Kebijakan OPA berikut mendefinisikan bahwa permintaan untuk mengakses aplikasi Productpage diizinkan hanya jika permintaan menggunakan metode GET, nilai parameter username dalam badan permintaan sama dengan nilai bidang Role dalam JWT permintaan, nilai bidang username dalam JWT masuk dalam rentang nilai yang ditentukan oleh bidang bookinfo_managers, dan bidang userGroup dalam JWT disetel ke manager:
apiVersion: istio.alibabacloud.com/v1beta1
kind: ASMOPAPolicy
metadata:
name: policy-range
namespace: default
spec:
policy: |
package istio.authz
bookinfo_managers = [{"name": "user1"}, {"name": "user2"}, {"name": "user3"}]
allow {
input.attributes.request.http.method == "GET"
input.parsed_path[0] == "productpage"
io.jwt.verify_hs256(bearer_token, "B41BD5F462719C6D6118E673A2389")
claims.Role == input.parsed_body.username
claims.userGroup == "manager"
claims.username == bookinfo_managers[_].name
}
claims := payload {
[_, payload, _] := io.jwt.decode(bearer_token)
}
bearer_token := t {
v := input.attributes.request.http.headers.authorization
startswith(v, "Bearer ")
t := substring(v, count("Bearer "), -1)
}input.attributes.request.http.method: metode permintaan. Dalam contoh ini, nilainya disetel ke
GET.input.parsed_path[0]: aplikasi yang akan diakses.
claims.Role: nilai yang diharapkan dari bidang Role dalam JWT. Dalam contoh ini, nilainya disetel ke
input.parsed_body.username. Ini menunjukkan bahwa nilai parameter username dalam badan permintaan harus sama dengan nilai bidang Role dalam JWT permintaan.claims.userGroup: nilai yang diharapkan dari bidang
userGroupdalam JWT. Dalam contoh ini, nilainya disetel kemanager.claims.username: nilai yang diharapkan dari bidang
usernamedalam JWT. Dalam contoh ini, nilainya disetel kebookinfo_managers[_].name. Ini menunjukkan bahwa nilai bidang username dalam JWT harus masuk dalam rentang nilai yang ditentukan oleh bidangbookinfo_managers.
Anda dapat menggunakan alat JWT untuk mengkodekan informasi permintaan menjadi string JWT.
Jalankan perintah berikut untuk mengakses aplikasi Productpage:
curl --location --request GET 'http://{Alamat IP gateway ingress}/productpage' \
--header 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9eyJ1c2VybmFtZSI6InVzZXIxIiwiUm9sZSI6ImFkbWluIiwidXNlckdyb3VwIjoibWFuYWdlciJ9.2X0Fmb96jBexLcVm_55t8ZY6XveSxUAsQ1j3ar5dI_g' \
--header 'Content-Type: application/json' \
--header 'Cookie: session=eyJ1c2VyIjoiYWRtaW4ifQ.YRz90g.GT34_5BqlFTwGqabZk_qGZzxYQ0' \
--data-raw '{
"username":"admin",
"password":"12****"
}'Output yang diharapkan:
200Kode status 200 dikembalikan, yang menunjukkan bahwa aplikasi Productpage dapat diakses menggunakan permintaan GET yang berisi JWT di mana nilai bidang Role sama dengan nilai parameter username dalam badan permintaan, nilai bidang username dalam JWT masuk dalam rentang nilai yang ditentukan oleh bidang bookinfo_managers, dan bidang userGroup disetel ke manager. Jika Anda menggunakan JWT yang tidak valid atau permintaan tidak berisi JWT, kode kesalahan 403 dikembalikan. Ini menunjukkan bahwa permintaan untuk mengakses aplikasi Productpage ditolak.
Tanya Jawab Umum
Bagaimana cara memeriksa apakah pod menggunakan kebijakan OPA?
OPA diterapkan dalam mode sidecar di pod yang sama dengan kontainer bisnis. Untuk memeriksa apakah pod menggunakan kebijakan OPA, sambungkan ke pod dan jalankan perintah berikut:
curl 127.0.0.1:15081/v1/policiesBagaimana cara memeriksa kebijakan yang ditulis dalam Rego?
Situs resmi OPA menyediakan alat online yang dapat Anda gunakan untuk memeriksa kebijakan yang ditulis dalam Rego.
Referensi
Jika Anda ingin menggunakan ConfigMaps untuk mendefinisikan kebijakan OPA, baca topik berikut: