Setiap aturan kebijakan keamanan Google Cloud Armor memiliki prioritas, kondisi kecocokan, dan tindakan. Cloud Armor melakukan tindakan aturan prioritas tertinggi yang cocok dengan permintaan. Aturan dengan prioritas yang lebih rendah daripada aturan yang cocok dengan prioritas tertinggi tidak dievaluasi, meskipun memiliki kondisi kecocokan yang sama.
Setiap aturan kebijakan keamanan mendukung dua jenis kondisi kecocokan:
- Kondisi kecocokan dasar berisi daftar alamat IP atau daftar rentang alamat IP. Kondisi kecocokan dasar ditentukan dengan menggunakan
flag
--src-ip-rangessaat membuat aturan menggunakan Google Cloud CLI. - Kondisi kecocokan lanjutan berisi ekspresi dengan hingga lima
subekspresi yang dapat mencocokkan berbagai atribut permintaan yang masuk.
Kondisi kecocokan lanjutan ditentukan menggunakan flag
--expressionsaat membuat aturan menggunakan Google Cloud CLI.
Halaman ini membahas kondisi pencocokan lanjutan dan bahasa aturan khusus Cloud Armor yang Anda gunakan untuk menulis ekspresi dalam kondisi pencocokan lanjutan aturan kebijakan keamanan. Bahasa aturan kihusus Cloud Armor adalah subset dari Common Expression Language (CEL). Ekspresi yang ditulis dalam bahasa aturan khusus Cloud Armor memerlukan dua komponen:
- Atribut: data yang akan diperiksa
- Operasi: cara menggunakan data
Misalnya, ekspresi berikut menggunakan atribut origin.ip dan
9.9.9.0/24 dalam operasi inIpRange(). Dalam hal ini, ekspresi
akan menampilkan true jika origin.ip berada dalam rentang alamat IP 9.9.9.0/24.
inIpRange(origin.ip, '9.9.9.0/24')
Meskipun ekspresi contoh sebelumnya hanya cocok dengan alamat IP sumber, saat Anda menggunakan ekspresi contoh dalam aturan kebijakan keamanan Cloud Armor, aturan tersebut dianggap sebagai aturan dengan kondisi kecocokan lanjutan dari perspektif kuota. Untuk mengetahui informasi selengkapnya, lihat Kuota dan batas Cloud Armor.
Operasi
Referensi berikut menjelaskan operator yang dapat Anda gunakan dengan atribut
(diwakili oleh x, y, dan k) untuk menentukan ekspresi aturan.
| Operasi | Ekspresi | Deskripsi |
|---|---|---|
| Persamaan | x == y |
Menampilkan true jika x sama dengan y. |
| Persamaan, literal string | x == "foo" |
Menampilkan true jika x sama dengan literal string konstan yang diberikan. |
| Persamaan, literal string raw | x == R"fo'o" |
Menampilkan true jika x sama dengan literal string raw yang diberikan yang tidak menafsirkan urutan escape. Literal string raw berguna untuk mengekspresikan string yang harus menggunakan karakter urutan escape. |
| Logika NOT | !x |
Menampilkan trus jika nilai Boolean x salah, atau menampilkan false jika nilai Boolean x benar. |
| Ketidaksetaraan | x != y |
Menampilkan true jika x tidak sama dengan y. |
| Penyambungan | x + y |
Menampilkan string penyambungan xy. |
| Logika AND | x && y |
Menampilkan true jika x dan y benar. |
| Logika OR | x || y |
Menampilkan true jika x, y, atau keduanya benar. |
| Berisi substring | x.contains(y) |
Menampilkan true jika string x berisi substring y. |
| Dimulai dengan substring | x.startsWith(y) |
Menampilkan true jika string x dimulai dengan substring y. |
| Diakhiri dengan substring | x.endsWith(y) |
Menampilkan true jika string x diakhiri dengan substring y. |
| Pencocokan ekspresi reguler | x.matches(y) |
Menampilkan true jika string x cocok sebagian dengan pola RE2 yang ditentukan y. Pola RE2 dikompilasi menggunakan opsi RE2::Latin1 yang menonaktifkan fitur Unicode. |
| Alamat IP dalam rentang | inIpRange(x, y) |
Menampilkan true jika alamat IP x berada dalam rentang IP y. |
| Huruf kecil | x.lower() |
Menampilkan nilai huruf kecil dari string x. |
| Huruf besar | x.upper() |
Menampilkan nilai huruf besar dari string x. |
| Nilai yang didekode Base64 | x.base64Decode() |
Menampilkan nilai yang didekode base64 dari x; karakter
_ - diganti terlebih dahulu dengan / +.
Menampilkan "" (string kosong) jika x bukan nilai base64
yang valid. |
| Nilai konfigurasi tombol | m['k'] |
Menampilkan nilai pada tombol k dalam peta string-ke-string m jika
k tersedia; jika tidak, menampilkan error. Pendekatan yang direkomendasikan adalah
dengan memeriksa ketersediaan terlebih dahulu menggunakan "has(m['k'])==true". |
| Memeriksa ketersediaan kunci di peta | has(m['k']) |
Menampilkan true jika tombol k tersedia di peta m. |
| Mengonversi ke bilangan bulat | int(x) |
Mengonversi hasil string x menjadi jenis int. Kemudian, nilai ini dapat digunakan untuk melakukan perbandingan bilangan bulat menggunakan operator aritmetika standar seperti > dan <=. Cara ini hanya berfungsi untuk nilai yang seharusnya berupa bilangan bulat. |
| Panjang | size(x) |
Menampilkan panjang string x. |
| Mendekode URL | x.urlDecode() |
Menampilkan nilai yang didekodekan URL dari x; urutan karakter dalam
format %## diganti dengan karakter non-ASCII yang setara, dan
+ diganti dengan spasi. Encoding yang tidak valid ditampilkan
apa adanya. |
| Mendekode URL (Unicode) | x.urlDecodeUni() |
Menampilkan nilai x yang didekode URL; selain
urlDecode(), fungsi ini juga menangani urutan karakter unicode dalam
format %u###. Encoding yang tidak valid ditampilkan apa adanya. |
| Mengonversi utf8 ke Unicode | x.utf8ToUnicode() |
Menampilkan representasi Unicode huruf kecil dari x yang dienkode UTF-8. |
Atribut
Atribut merepresentasikan informasi dari permintaan masuk, seperti alamat IP origin atau jalur URL yang diminta.
| Kolom | Jenis | Deskripsi kolom |
|---|---|---|
origin.ip |
string | Alamat IP sumber permintaan. |
origin.user_ip |
string | Alamat IP klien origin, yang disertakan dalam
HTTP-HEADER oleh proxy upstream. Sebelum menggunakan
atribut ini, Anda harus mengonfigurasi opsi userIpRequestHeaders[]
di kolom advancedOptionsConfig kebijakan keamanan
agar cocok dengan sumber seperti True-Client-IP,
X-Forwarded-For, atau X-Real-IP. Untuk mengetahui informasi selengkapnya, lihat
Ringkasan alamat IP pengguna.
Jika Anda tidak mengonfigurasi opsi |
origin.tls_ja4_fingerprint |
string | Sidik jari TLS/SSL JA4
jika klien terhubung menggunakan
HTTPS, HTTP/2, atau HTTP/3. Jika tidak tersedia, string kosong akan ditampilkan. |
origin.tls_ja3_fingerprint |
string | Sidik jari TLS/SSL JA3
jika klien terhubung menggunakan
HTTPS, HTTP/2, atau HTTP/3. Jika tidak tersedia, string kosong akan ditampilkan. |
request.headers |
peta | Peta string-ke-string dari header permintaan HTTP. Jika header
berisi beberapa nilai, nilai dalam peta ini akan berupa string yang dipisahkan koma
dari semua nilai header. Semua kunci dalam peta ini adalah
huruf kecil. Semua header yang diterima oleh Load Balancer Aplikasi eksternal
diperiksa, dan batasan header yang sama
berlaku. Pendekatan yang direkomendasikan adalah memeriksa ketersediaan terlebih dahulu menggunakan
|
request.method |
string | Metode permintaan HTTP. |
request.path |
string | Jalur URL HTTP yang diminta. |
request.scheme |
string | Skema URL HTTP seperti http atau https.
Nilai untuk atribut ini semuanya huruf kecil. |
request.query |
string | Kueri URL HTTP dalam format
name1=value&name2=value2, seperti yang muncul di baris pertama
permintaan HTTP. Tidak ada decoding yang dijalankan.
|
origin.region_code |
string | Kode negara Unicode yang terkait dengan IP origin, seperti
US. Jika Anda membuat aturan atau ekspresi yang menggunakan
kode negara atau region ISO 3166-1 alpha 2, Cloud Armor memperlakukan setiap kode secara terpisah. Aturan dan ekspresi Cloud Armor secara eksplisit
menggunakan kode region tersebut untuk mengizinkan atau menolak permintaan.
|
origin.asn |
bilangan bulat | Nomor sistem otonom (ASN) yang terkait dengan alamat IP origin. ASN yang unik secara global ditentukan berdasarkan operator jaringan yang mendukung awalan alamat IP yang berisi alamat IP origin. |
Contoh ekspresi
Untuk setiap ekspresi ini, tindakan yang diambil bergantung pada apakah ekspresi tersebut disertakan dalam aturan penolakan atau aturan izin.
Mengizinkan atau menolak akses berdasarkan rentang alamat IP di IPv4 atau IPv6
Ekspresi berikut cocok dengan permintaan dari rentang alamat IP
198.51.100.0/24:inIpRange(origin.ip, '198.51.100.0/24')
Ekspresi berikut cocok dengan permintaan dari rentang alamat IP
2001:db8::/32:inIpRange(origin.ip, '2001:db8::/32')
Mengizinkan atau menolak akses berdasarkan rentang alamat IP klien kustom di belakang proxy upstream
Jika telah mengonfigurasi operator origin.user_ip, Anda dapat mencocokkan berdasarkan
nilai header yang ditentukan di kolom
advancedOptionsConfig.userIpRequestHeaders[].
Ekspresi berikut cocok dengan permintaan yang berasal dari rentang alamat IP
192.0.2.0/24:inIpRange(origin.user_ip, '192.0.2.0/24')
Ekspresi berikut cocok dengan permintaan yang berasal dari rentang alamat IP
2001:db8::/32:inIpRange(origin.user_ip, '2001:db8::/32')
Mengizinkan atau menolak traffic dengan cookie tertentu
Ekspresi berikut cocok dengan permintaan yang memiliki cookie yang berisi
80=BLAH:has(request.headers['cookie']) && request.headers['cookie'].contains('80=BLAH')
Mengizinkan atau menolak traffic dengan header referer yang tidak kosong
Ekspresi berikut cocok dengan permintaan yang memiliki header
refereryang tidak kosong:has(request.headers['referer']) && request.headers['referer'] != ""
Mengizinkan atau menolak traffic berdasarkan header host
Anda dapat mengizinkan atau menolak traffic berdasarkan nilai header Host dalam permintaan.
Ekspresi berikut cocok dengan permintaan ke URL tertentu menggunakan
==:request.headers['host'].lower() == 'test.example.com'
Ekspresi berikut cocok dengan permintaan ke URL tertentu menggunakan
endsWith:request.headers['host'].lower().endsWith('.example.com')Ekspresi berikut cocok dengan permintaan ke URL tertentu menggunakan
contains:request.headers['host'].lower().contains('test.example.com')
Ekspresi berikut cocok dengan permintaan ke beberapa domain menggunakan
contains:request.headers['host'].lower().contains('test.example.com') || request.headers['host'].lower().contains('test22.example.com')Ekspresi berikut mencocokkan permintaan untuk domain dan subdomainnya menggunakan
matches:request.headers['host'].matches('(?i:(sub\.)?test\.example\.com)')
Mengizinkan atau menolak traffic dari region tertentu
Jika aplikasi web Anda tidak tersedia di region AU, semua permintaan dari region tersebut harus diblokir.
Dalam aturan penolakan, gunakan ekspresi berikut, yang cocok dengan permintaan dari region
AU:origin.region_code == 'AU'
Atau, jika aplikasi web Anda hanya tersedia di region AU,
permintaan dari semua region lain harus diblokir.
Dalam aturan penolakan, gunakan ekspresi berikut, yang cocok dengan permintaan dari semua region selain region
AU:origin.region_code != 'AU'
Kode region didasarkan pada kode
ISO 3166-1 alpha 2. Dalam beberapa kasus, region sesuai dengan negara, tetapi tidak selalu demikian. Misalnya, kode US mencakup semua negara bagian Amerika Serikat, satu distrik, dan enam area terpencil.
Mengizinkan atau menolak traffic dari ASN tertentu
Jika aplikasi web Anda perlu diblokir untuk pelanggan yang dilayani oleh operator jaringan tertentu, Anda dapat menggunakan nomor ASN operator jaringan untuk memblokir.
Dalam aturan penolakan, gunakan ekspresi berikut, yang cocok dengan permintaan dari ASN tertentu:
origin.asn == 123
Atau, jika aplikasi web Anda hanya tersedia untuk pelanggan di belakang operator jaringan tertentu, permintaan dari semua operator jaringan lainnya harus diblokir.
Dalam aturan penolakan, gunakan ekspresi berikut, yang cocok dengan semua operator jaringan lainnya selain yang ingin Anda izinkan:
origin.asn != 123
Beberapa ekspresi
Untuk menyertakan beberapa kondisi dalam satu aturan, gabungkan beberapa subekspresi.
Dalam contoh berikut, permintaan dari
1.2.3.0/24(seperti penguji alfa Anda) di regionAUcocok dengan ekspresi berikut:origin.region_code == "AU" && inIpRange(origin.ip, '1.2.3.0/24')
Ekspresi berikut mencocokkan permintaan dari
1.2.3.4saat agen pengguna berisi stringWordPress:inIpRange(origin.ip, '1.2.3.4/32') && has(request.headers['user-agent']) && request.headers['user-agent'].contains('WordPress')
Mengizinkan atau menolak traffic untuk URI permintaan yang cocok dengan ekspresi reguler
Ekspresi berikut cocok dengan permintaan yang berisi string
/example_path/di URI:request.path.matches('/example_path/')Ekspresi berikut cocok dengan permintaan yang memiliki
Chromedi kolom headerUser-Agent:request.headers['user-agent'].matches('Chrome')Ekspresi berikut menunjukkan pencocokan yang tidak peka huruf besar/kecil untuk header
User-Agentyang berisiwordpress; ekspresi ini cocok denganUser-Agent:WordPress/605.1.15,User-Agent:wordPress, dan variasiwordpresslainnya:request.headers['user-agent'].matches('(?i:wordpress)')
Mengizinkan atau menolak traffic yang berisi nilai yang didekode base64 tertentu
Ekspresi berikut cocok dengan permintaan yang memiliki nilai
myValueyang didekode base64 untuk headeruser-id:has(request.headers['user-id']) && request.headers['user-id'].base64Decode().contains('myValue')
Mengizinkan atau menolak traffic yang berisi nilai string dengan panjang tertentu
Ekspresi berikut cocok dengan permintaan yang memiliki panjang URL lebih dari 10 karakter:
size(request.path) > 10
Ekspresi berikut cocok dengan permintaan yang memiliki panjang header
x-datalebih besar dari atau sama dengan 1.024 karakter:size(request.headers['x-data']) >= 1024
Mengizinkan atau menolak traffic yang memiliki nol content-length di isi HTTP
Ekspresi berikut mencocokkan permintaan yang memiliki
content-lengthnol di isi HTTP:int(request.headers["content-length"]) == 0
Mengizinkan atau menolak traffic yang berisi nilai yang dienkode URL tertentu
Ekspresi berikut cocok dengan permintaan yang memiliki nilai cookie yang berisi
%3c:has(request.headers['cookie']) && request.headers['cookie'].urlDecode().contains('<')
Mengizinkan atau menolak traffic yang berisi nilai string Unicode yang dienkode URL tertentu
Ekspresi berikut cocok dengan permintaan yang memiliki nilai cookie yang sama dengan
Match%2BValueatauMatch%u002BValue:has(request.headers['cookie']) && request.headers['cookie'].urlDecodeUni() == 'Match+Value'
Mengizinkan atau menolak traffic yang berisi string Unicode tertentu dari teks UTF-8
Ekspresi berikut cocok dengan permintaan yang memiliki nilai cookie sama dengan
¬:has(request.headers['cookie']) && request.headers['cookie'].utf8ToUnicode() == '%u00ac'
Mengizinkan atau menolak traffic berdasarkan sidik jari JA4 yang diketahui
Ekspresi berikut cocok dengan permintaan yang memiliki sidik jari JA4 yang sama dengan
t13d1516h2_8daaf6152771_b186095e22b6:origin.tls_ja4_fingerprint == 't13d1516h2_8daaf6152771_b186095e22b6'
Mengizinkan atau menolak traffic berdasarkan daftar sidik jari JA4
Ekspresi berikut cocok dengan permintaan yang memiliki sidik jari JA4 yang sama dengan salah satu sidik jari JA4 berikut:
t00d0000h0_000000000000_000000000000t13d1516h2_8daaf6152771_b186095e22b6
origin.tls_ja4_fingerprint == 't00d0000h0_000000000000_000000000000' || origin.tls_ja4_fingerprint == 't13d1516h2_8daaf6152771_b186095e22b6'
Aturan WAF yang telah dikonfigurasi sebelumnya
Aturan WAF yang telah dikonfigurasi sebelumnya menggunakan signature statis, ekspresi reguler, atau keduanya yang telah dikonfigurasi sebelumnya untuk mencocokkan isi permintaan HTTP, header permintaan HTTP, dan parameter kueri. Aturan WAF yang telah dikonfigurasi sebelumnya yang tersedia didasarkan pada OWASP core rule set versi 3.3. Cloud Armor menyediakan beberapa aturan WAF yang telah dikonfigurasi dan ditentukan sebelumnya. Untuk mengetahui daftar lengkap aturan WAF yang telah dikonfigurasi sebelumnya, lihat Ringkasan aturan WAF yang telah dikonfigurasi sebelumnya oleh Cloud Armor.
Untuk mencantumkan semua aturan WAF yang telah dikonfigurasi sebelumnya yang tersedia, lihat Mencantumkan aturan WAF yang telah dikonfigurasi sebelumnya yang tersedia.
Untuk mengetahui informasi selengkapnya tentang aturan WAF yang telah dikonfigurasi sebelumnya, lihat kasus penggunaan Mencegah serangan pada lapisan aplikasi menggunakan aturan WAF yang telah dikonfigurasi sebelumnya.
Nama aturan WAF yang telah dikonfigurasi sebelumnya
Nama aturan WAF yang telah dikonfigurasi sebelumnya memiliki format
<attack category>-<OWASP CRS version>-<version field>. Kategori serangan menentukan jenis serangan yang ingin Anda lindungi, seperti xss (pembuatan skrip lintas situs) atau sqli (injeksi SQL).
Kolom versi yang didukung adalah stable dan canary. Penambahan dan
modifikasi pada aturan dirilis terlebih dahulu di versi canary. Jika penambahan dan modifikasi dianggap aman dan stabil, maka akan dipromosikan ke versi stable.
ID anggota aturan WAF yang telah dikonfigurasi sebelumnya
Aturan WAF yang telah dikonfigurasi sebelumnya berisi beberapa ekspresi, yang masing-masing memiliki signature-nya.
Misalnya, aturan WAF yang telah dikonfigurasi sebelumnya xss-v33-stable mencakup ekspresi
yang disebut owasp-crs-v030301-id941100-xss, yang sesuai dengan ID aturan id941100
untuk versi 3.3. Anda dapat menggunakan signature untuk mengecualikan ekspresi tertentu agar tidak digunakan, yang berguna jika ekspresi tertentu secara konsisten memicu positif palsu. Untuk mengetahui informasi selengkapnya, lihat informasi pemecahan masalah positif palsu.
Untuk mengetahui informasi tentang rangkaian aturan inti dan penyesuaian pada berbagai tingkat sensitivitas, lihat Menyesuaikan aturan WAF Google Cloud Armor.
Operator untuk aturan WAF yang telah dikonfigurasi sebelumnya
| Ekspresi | Deskripsi |
|---|---|
evaluatePreconfiguredWaf(string, MAP<string, dyn>) |
Menampilkan nilai true jika salah satu signature WAF dalam rangkaian aturan WAF yang ditentukan menampilkan true. Argumen pertama adalah nama rangkaian aturan WAF, seperti xss-v33-stable. Argumen kedua
(opsional) adalah peta dengan kunci berupa string dan nilai yang
diketik secara dinamis bergantung pada kuncinya. Tujuan argumen ini adalah untuk menyempurnakan signature WAF yang dievaluasi. Kunci yang diterima mencakup
berikut ini:
Kunci "opt_out_rule_ids" dan "opt_in_rule_ids" tidak dapat muncul bersamaan. Anda dapat memilih untuk menggunakan "opt_in_rule_ids" jika ingin meninjau dan secara manual mengaktifkan signature WAF baru yang ditambahkan nanti ke dalam rangkaian aturan yang ada. |
evaluatePreconfiguredExpr(string, LIST) |
Menampilkan true jika salah satu ekspresi di dalam aturan WAF yang telah dikonfigurasi sebelumnya dan ditentukan menampilkan true. Argumen pertama adalah nama aturan WAF yang telah dikonfigurasi sebelumnya, seperti
|
Contoh aturan WAF yang telah dikonfigurasi sebelumnya
Ekspresi berikut menggunakan aturan WAF
xss-v33-stableyang telah dikonfigurasi sebelumnya untuk mengurangi serangan XSS:evaluatePreconfiguredWaf('xss-v33-stable')Ekspresi berikut menggunakan semua ekspresi dari aturan WAF
xss-v33-stableyang telah dikonfigurasi sebelumnya kecuali untuk ID anggota941100dan941110:evaluatePreconfiguredWaf('xss-v33-stable', {'opt_out_rule_ids': ['owasp-crs-v030301-id941100-xss', 'owasp-crs-v030301-id941110-xss']})Ekspresi berikut menggunakan aturan WAF yang telah dikonfigurasi sebelumnya untuk memitigasi serangan SQLi dari rentang alamat IP
198.51.100.0/24:inIpRange(origin.ip, '198.51.100.0/24') && evaluatePreconfiguredWaf('sqli-v33-stable')
Operator lainnya
| Ekspresi | Deskripsi |
|---|---|
evaluateThreatIntelligence(string)evaluateThreatIntelligence(string, LIST)evaluateThreatIntelligence(string, string, LIST)
|
Menampilkan true jika alamat IP sumber cocok dengan rentang IP mana pun dalam daftar IP yang diberikan, kecuali jika secara eksplisit dikecualikan dengan daftar pengecualian. Argumen pertama adalah nama feed Google Threat Intelligence, seperti |
evaluateAddressGroup(string, string)evaluateAddressGroup(string, string, LIST)evaluateOrganizationAddressGroup(string, string)evaluateOrganizationAddressGroup(string, string, LIST)
|
Menampilkan true jika alamat IP sumber cocok dengan rentang IP mana pun dalam grup alamat yang diberikan, kecuali jika secara eksplisit dikecualikan dengan daftar pengecualian. Argumen pertama adalah nama grup alamat. Argumen
kedua menentukan dari mana alamat IP diekstrak, dan dapat berupa
|
evaluateAdaptiveProtection(string) |
Menampilkan true jika permintaan cocok dengan tanda serangan yang dihasilkan oleh Perlindungan Adaptif. Argumennya adalah ID pemberitahuan tertentu yang dibuat oleh Perlindungan Adaptif saat mendeteksi serangan. |
evaluateAdaptiveProtectionAutoDeploy() |
Menampilkan true jika permintaan berasal dari alamat IP heavy hitter yang cocok dengan tanda serangan dari serangan yang sedang berlangsung yang terdeteksi oleh Perlindungan Adaptif. |
Contoh
Ekspresi berikut mencocokkan permintaan masuk dengan feed
iplist-known-malicious-ipsGoogle Threat Intelligence untuk perlindungan dari daftar IP berbahaya yang diketahui:evaluateThreatIntelligence('iplist-known-malicious-ips')Ekspresi berikut mencocokkan permintaan masuk dengan feed
iplist-known-malicious-ipsGoogle Threat Intelligence untuk perlindungan dari daftar IP berbahaya yang diketahui, kecuali IP di104.135.0.0/16:evaluateThreatIntelligence('iplist-known-malicious-ips', ['104.135.0.0/16'])Ekspresi berikut mencocokkan header permintaan kustom untuk IP pengguna dengan grup alamat bernama
my-own-list-of-bad-ips:evaluateAddressGroup('my-own-list-of-bad-ips', origin.user_ip)
Langkah berikutnya
- Mengonfigurasi kebijakan keamanan Cloud Armor
- Menyesuaikan aturan WAF yang telah dikonfigurasi sebelumnya oleh Cloud Armor
- Memecahkan masalah Cloud Armor
- Kuota dan batas