Setiap aturan kebijakan keamanan Google Cloud Armor memiliki prioritas, kondisi kecocokan, dan satu tindakan. Google Cloud Armor melakukan tindakan pada aturan prioritas tertinggi yang sesuai dengan permintaan. Aturan dengan prioritas yang lebih rendah daripada aturan pencocokan prioritas tertinggi tidak akan dievaluasi, meskipun memiliki kondisi pencocokan yang sama.
Setiap aturan kebijakan keamanan mendukung dua jenis kondisi pencocokan:
- Kondisi pencocokan dasar berisi daftar alamat IP atau daftar rentang alamat IP. Kondisi pencocokan dasar ditentukan dengan menggunakan flag
--src-ip-ranges
saat membuat aturan menggunakan Google Cloud CLI. - Kondisi pencocokan lanjutan berisi ekspresi dengan maksimal lima subekspresi yang dapat cocok dengan berbagai atribut permintaan masuk.
Kondisi pencocokan lanjutan ditentukan menggunakan flag
--expression
saat membuat aturan menggunakan Google Cloud CLI.
Halaman ini membahas kondisi pencocokan lanjutan dan bahasa aturan khusus Google Cloud Armor yang Anda gunakan untuk menulis ekspresi dalam kondisi pencocokan lanjutan aturan kebijakan keamanan. Bahasa aturan kustom Google Cloud Armor adalah bagian dari Common Expression Language (CEL). Ekspresi yang ditulis dalam bahasa aturan kustom Google 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 benar 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 Google Cloud Armor, aturan tersebut dianggap sebagai aturan dengan kondisi pencocokan lanjutan dari perspektif kuota. Untuk mengetahui informasi selengkapnya, lihat Kuota dan batas Google Cloud Armor.
Atribut
Atribut mewakili informasi dari permintaan masuk, seperti alamat IP asal atau jalur URL yang diminta.
Kolom | Jenis | Deskripsi kolom |
---|---|---|
origin.ip |
string | Alamat IP sumber permintaan. |
origin.user_ip |
string | Alamat IP klien asal, 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 .
Jika Anda tidak mengonfigurasi opsi |
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 |
map | Peta string-ke-string untuk header permintaan HTTP. Jika header berisi beberapa nilai, nilai dalam peta ini akan menjadi string yang dipisahkan koma dari semua nilai header. Kunci dalam peta ini semuanya huruf kecil. Semua header yang diterima oleh Load Balancer Aplikasi eksternal akan diperiksa, dan batasan header yang sama akan berlaku. |
request.method |
string | Metode permintaan HTTP, seperti GET atau POST . |
request.path |
string | Jalur URL HTTP yang diminta. |
request.scheme |
string | Skema URL HTTP seperti http atau https .
Semua nilai untuk atribut ini adalah 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 dilakukan.
|
origin.region_code |
string | Kode negara Unicode yang terkait dengan IP asal, seperti US . Jika Anda membuat aturan atau ekspresi yang menggunakan kode negara atau wilayah ISO 3166-1 alpha 2, Google Cloud Armor akan memperlakukan setiap kode secara independen. Aturan dan ekspresi Google Cloud Armor secara eksplisit menggunakan kode region tersebut untuk mengizinkan atau menolak permintaan.
Untuk informasi selengkapnya, lihat unicode_region_subtag dalam Standar Teknis Unicode. |
origin.asn |
bilangan bulat | Nomor sistem otonom (ASN) yang terkait dengan alamat IP asal. ASN yang unik secara global ditentukan berdasarkan operator jaringan yang mendukung awalan alamat IP yang berisi alamat IP asal. |
Atribut reCAPTCHA Enterprise
Bagian ini mencantumkan atribut yang hanya berlaku untuk token reCAPTCHA Enterprise atau cookie pengecualian. Subekspresi berdasarkan atribut ini menampilkan false
jika token reCAPTCHA Enterprise atau cookie pengecualian yang akan dievaluasi tidak tersedia atau tidak valid karena salah satu alasan berikut:
- Format token salah dan tidak dapat didekode.
- Token berisi atribut yang tidak valid. Misalnya, token dibuat menggunakan kunci reCAPTCHA yang tidak cocok dengan kunci reCAPTCHA terkait aturan.
- Masa berlaku token telah habis.
Atribut cookie pengecualian
Kolom | Jenis | Deskripsi kolom |
---|---|---|
token.recaptcha_exemption.valid |
bool |
Adanya cookie pengecualian reCAPTCHA yang valid. |
Atribut token tindakan
Kolom | Jenis | Deskripsi kolom |
---|---|---|
token.recaptcha_action.score |
float |
Skor dari token tindakan reCAPTCHA. Skor yang valid berkisar dari 0.0 hingga 1.0 , dengan 0.0 kemungkinan besar adalah pengguna tidak sah, dan 1.0 kemungkinan besar adalah pengguna yang sah. |
token.recaptcha_action.captcha_status |
string |
Status reCAPTCHA dari token tindakan reCAPTCHA. Status yang valid adalah
NONE , PASS , atau FAIL , dengan
NONE mengacu pada saat tidak ada tantangan yang terlibat selama
penilaian reCAPTCHA sehingga kolom reCAPTCHA tidak ada dalam
token tindakan. |
token.recaptcha_action.action |
string |
Nama tindakan (maksimal 100 karakter) dari token tindakan reCAPTCHA. Lihat Nama tindakan. |
token.recaptcha_action.valid |
bool |
Keberadaan token tindakan reCAPTCHA yang valid. |
Atribut token sesi
Kolom | Jenis | Deskripsi kolom |
---|---|---|
token.recaptcha_session.score |
float |
Skor dari token sesi reCAPTCHA. Skor yang valid berkisar dari 0.0 hingga 1.0 , dengan 0.0 kemungkinan besar adalah pengguna tidak sah, dan 1.0 kemungkinan besar adalah pengguna yang sah. |
token.recaptcha_session.valid |
bool |
Keberadaan token sesi reCAPTCHA yang valid. |
Operasi
Referensi berikut menjelaskan operator yang dapat Anda gunakan dengan atribut (diwakili oleh x
, y
, dan k
) untuk menentukan ekspresi aturan.
Ekspresi | Deskripsi |
---|---|
x == "foo" |
Menampilkan benar jika x sama dengan literal string konstan yang diberikan. |
x == R"fo'o" |
Menampilkan true (benar) jika x sama dengan literal string mentah yang diberikan yang tidak menafsirkan urutan escape. Literal string mentah berguna untuk menyatakan string yang harus menggunakan karakter urutan escape. |
x == y |
Menampilkan true (benar) jika x sama dengan y. |
x != y |
Menampilkan true (benar) jika x tidak sama dengan y. |
x + y |
Menampilkan string gabungan xy. |
x && y |
Menampilkan benar jika x dan y benar. |
x || y |
Menampilkan true (benar) jika x, y, atau keduanya benar. |
!x |
Menampilkan benar jika nilai Boolean x bernilai salah, atau menampilkan nilai salah jika nilai Boolean x bernilai benar. |
x.contains(y) |
Menampilkan true (benar) jika string x berisi substring y. |
x.startsWith(y) |
Menampilkan true (benar) jika string x diawali dengan substring y. |
x.endsWith(y) |
Menampilkan true (benar) jika string x diakhiri dengan substring y. |
x.matches(y) |
Menampilkan true (benar) jika string x cocok sebagian dengan pola RE2 y yang ditentukan. Pola RE2 dikompilasi menggunakan opsi RE2::Latin1 yang menonaktifkan fitur Unicode. |
inIpRange(x, y) |
Menampilkan true (benar) jika alamat IP x berada dalam rentang IP y. {i>Subnet mask<i} untuk alamat IPv6 tidak boleh lebih besar dari /64. |
x.lower() |
Menampilkan nilai huruf kecil dari string x. |
x.upper() |
Menampilkan nilai huruf besar string x. |
x.base64Decode() |
Menampilkan nilai x yang didekode base64; karakter _ - pertama kali diganti dengan / + .
Menampilkan "" (string kosong) jika x bukan nilai base64 yang valid. |
has(m['k']) |
Menampilkan nilai benar jika kunci k tersedia di peta m. |
m['k'] |
Menampilkan nilai pada kunci k dalam peta string-ke-string m jika k tersedia; jika tidak, akan menampilkan error. Pendekatan yang direkomendasikan adalah memeriksa ketersediaan terlebih dahulu menggunakan "has(m['k'])==true" . |
int(x) |
Mengonversi hasil string x ke jenis int . Kemudian, nilai ini dapat digunakan untuk melakukan perbandingan bilangan bulat dengan operator aritmetika standar seperti > dan <=. Ini hanya berfungsi untuk nilai yang seharusnya berupa bilangan bulat. |
size(x) |
Menampilkan panjang string x. |
x.urlDecode() |
Menampilkan nilai yang didekode URL untuk x; urutan karakter dalam format %## diganti dengan padanan non-ASCII, dan + diganti dengan spasi. Encoding yang tidak valid ditampilkan
apa adanya. |
x.urlDecodeUni() |
Menampilkan nilai yang didekode URL untuk x; selain
urlDecode() , nilai ini juga menangani urutan karakter unicode dalam
format %u### . Encoding yang tidak valid ditampilkan sebagaimana adanya. |
x.utf8ToUnicode() |
Menampilkan representasi Unicode huruf kecil dari x berenkode UTF-8. |
Contoh ekspresi
Untuk setiap ekspresi ini, tindakan yang diambil bergantung pada apakah ekspresi disertakan dalam aturan penolakan atau aturan izinkan.
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
referer
yang tidak kosong:has(request.headers['referer']) && request.headers['referer'] != ""
Mengizinkan atau menolak traffic berdasarkan URL host di header
Ekspresi berikut cocok dengan permintaan ke URL tertentu:
request.headers['host'].lower().contains('test.example.com')
Mengizinkan atau menolak traffic dari wilayah 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 wilayah lain harus diblokir.
Dalam aturan penolakan, gunakan ekspresi berikut yang cocok dengan permintaan dari semua region selain region
AU
:origin.region_code != 'AU'
Kode wilayah didasarkan pada kode
ISO 3166-1 alpha 2. Dalam beberapa kasus, wilayah sesuai dengan suatu negara, tetapi tidak selalu. 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 melakukan pemblokiran.
Dalam aturan penolakan, gunakan ekspresi berikut yang cocok dengan permintaan dari ASN tertentu:
origin.asn == 123
Atau, jika aplikasi web Anda hanya tersedia bagi pelanggan yang tidak menggunakan 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.
Pada contoh berikut, permintaan dari
1.2.3.0/24
(seperti penguji alfa) di regionAU
cocok dengan ekspresi berikut:origin.region_code == "AU" && inIpRange(origin.ip, '1.2.3.0/24')
Ekspresi berikut cocok dengan permintaan dari
1.2.3.4
yang agen penggunanya 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
bad_path
dalam URI:request.path.matches('/bad_path/')
Ekspresi berikut cocok dengan permintaan yang memiliki
Chrome
di kolom headerUser-Agent
:request.headers['user-agent'].matches('Chrome')
Ekspresi berikut menunjukkan pencocokan yang tidak peka huruf besar/kecil untuk header
User-Agent
yang berisiwordpress
; cocok denganUser-Agent:WordPress/605.1.15
,User-Agent:wordPress
, dan variasiwordpress
lainnya:request.headers['user-agent'].matches('(?i:wordpress)')
Mengizinkan atau menolak traffic yang berisi nilai tertentu yang didekode base64
Ekspresi berikut cocok dengan permintaan yang memiliki nilai
myValue
yang didekode dalam 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
x-data
header lebih dari atau sama dengan 1.024 karakter:size(request.headers['x-data']) >= 1024
Mengizinkan atau menolak traffic yang memiliki nol content-length
dalam isi HTTP
Ekspresi berikut cocok dengan permintaan yang memiliki
content-length
nol dalam 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 encoding URL tertentu dari string Unicode
Ekspresi berikut cocok dengan permintaan yang memiliki nilai cookie sama dengan
Match%2BValue
atauMatch%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 JA3 yang diketahui
Ekspresi berikut cocok dengan permintaan yang memiliki sidik jari JA3 yang sama dengan
e7d705a3286e19ea42f587b344ee6865
:origin.tls_ja3_fingerprint == 'e7d705a3286e19ea42f587b344ee6865'
Mengizinkan atau menolak traffic berdasarkan daftar sidik jari JA3
Ekspresi berikut cocok dengan permintaan yang memiliki sidik jari JA3 sama dengan salah satu sidik jari JA3 berikut:
e7d705a3286e19ea42f587b344ee6865
f8a5929f8949e846267b582072e35f84
8f8b62163873a62234c14f15e7b88340
origin.tls_ja3_fingerprint == 'e7d705a3286e19ea42f587b344ee6865' || origin.tls_ja3_fingerprint == 'f8a5929f8949e846267b582072e35f84' || origin.tls_ja3_fingerprint == '8f8b62163873a62234c14f15e7b88340'
Aturan WAF yang telah dikonfigurasi sebelumnya
Aturan WAF yang telah dikonfigurasi sebelumnya menggunakan tanda tangan statis, ekspresi reguler, atau keduanya yang telah dikonfigurasi sebelumnya agar cocok pada isi HTTP POST, header permintaan HTTP, dan parameter kueri. Aturan WAF yang telah dikonfigurasi sebelumnya dan tersedia didasarkan pada kumpulan aturan inti Modsecurity OWASP versi 3.3. Google Cloud Armor menyediakan beberapa aturan WAF yang telah dikonfigurasi sebelumnya. Untuk mengetahui daftar lengkap aturan WAF yang telah dikonfigurasi sebelumnya, baca Ringkasan aturan WAF yang telah dikonfigurasi Google Cloud Armor.
Untuk mencantumkan semua aturan WAF yang telah dikonfigurasi sebelumnya, lihat Mencantumkan aturan WAF yang telah dikonfigurasi sebelumnya.
Untuk mengetahui informasi selengkapnya tentang aturan WAF yang telah dikonfigurasi sebelumnya, lihat kasus penggunaan Memitigasi serangan 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>-<ModSecurity 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 dalam versi canary
terlebih dahulu. Jika
penambahan dan modifikasi dianggap aman dan stabil, penambahan dan modifikasi tersebut akan dipromosikan
ke versi stable
.
ID anggota aturan WAF yang telah dikonfigurasi sebelumnya
Aturan WAF yang telah dikonfigurasi sebelumnya berisi beberapa ekspresi, masing-masing dengan tanda tangannya.
Misalnya, aturan WAF xss-v33-stable
yang telah dikonfigurasi sebelumnya menyertakan ekspresi yang disebut owasp-crs-v030301-id941100-xss
, yang sesuai dengan ID aturan id941100
untuk versi 3.3. Anda dapat menggunakan tanda tangan 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 penetapan dan penyesuaian aturan inti 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 true (benar) jika salah satu tanda tangan WAF dalam kumpulan aturan WAF yang ditentukan menampilkan nilai benar (true). Argumen pertama adalah nama kumpulan aturan WAF, seperti xss-v33-stable . Argumen kedua (opsional) adalah peta yang kuncinya berupa string dan nilainya diketik secara dinamis, bergantung pada kuncinya. Tujuan argumen ini adalah
untuk menyesuaikan tanda tangan WAF mana yang akan dievaluasi. Kunci yang diterima mencakup
hal berikut:
Kunci "opt_out_rule_ids" dan "opt_in_rule_ids" sama-sama bersifat eksklusif. Anda dapat memilih menggunakan "opt_in_rule_ids" jika ingin meninjau dan secara manual mengikutsertakan tanda tangan WAF baru yang nantinya ditambahkan ke dalam kumpulan aturan yang sudah ada. |
evaluatePreconfiguredExpr(string, LIST) |
Menampilkan true (benar) jika salah satu ekspresi dalam aturan WAF yang telah dikonfigurasi sebelumnya dan menampilkan nilai benar (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-stable
yang telah dikonfigurasi sebelumnya untuk memitigasi serangan XSS:evaluatePreconfiguredExpr('xss-v33-stable')
Ekspresi berikut menggunakan semua ekspresi dari aturan WAF
xss-v33-stable
yang telah dikonfigurasi sebelumnya, kecuali untuk ID anggota941100
dan941110
:evaluatePreconfiguredExpr('xss-v33-stable', ['owasp-crs-v030301-id941100-xss', 'owasp-crs-v030301-id941110-xss'])
Ekspresi berikut menggunakan aturan WAF yang telah dikonfigurasi untuk memitigasi serangan SQLi dari rentang alamat IP
198.51.100.0/24
:inIpRange(origin.ip, '198.51.100.0/24') && evaluatePreconfiguredExpr('sqli-v33-stable')
Langkah selanjutnya
- Mengonfigurasi kebijakan, aturan, dan ekspresi keamanan
- Menyesuaikan aturan firewall aplikasi web (WAF)
- Memecahkan masalah