每個 Google Cloud Armor 安全性政策規則都有優先順序、比對條件和動作。Google Cloud Armor 會執行與要求相符的最高優先順序規則所指定的動作。優先順序低於最高匹配規則的規則不會評估,即使兩者具有相同的匹配條件也一樣。
每項安全性政策規則都支援兩種比對條件:
- 基本比對條件包含 IP 位址清單或 IP 位址範圍清單。使用 Google Cloud CLI 建立規則時,您可以使用
--src-ip-ranges
標記定義基本比對條件。 - 進階比對條件包含一個運算式,最多可包含五個子運算式,可比對傳入要求的各種屬性。使用 Google Cloud CLI 建立規則時,可使用
--expression
標記定義進階比對條件。
本頁面將說明進階比對條件,以及 Google Cloud Armor 自訂規則語言,您可使用這兩者在安全性政策規則的進階比對條件中編寫運算式。Google Cloud Armor 自訂規則語言是一般運算語言 (CEL) 的子集。使用 Google Cloud Armor 自訂規則語言編寫的運算式需要兩個元件:
- 屬性:要檢查的資料
- 作業:如何使用資料
例如,以下運算式會在 inIpRange()
運算中使用 origin.ip
和 9.9.9.0/24
屬性。在本範例中,如果 origin.ip
位於 9.9.9.0/24
IP 位址範圍內,運算式會傳回 true。
inIpRange(origin.ip, '9.9.9.0/24')
雖然上述範例運算式只會比對來源 IP 位址,但如果您在 Google Cloud Armor 安全性政策規則中使用上述範例運算式,從配額角度來看,系統會將該規則視為具有進階比對條件的規則。詳情請參閱 Google Cloud Armor 配額與限制。
作業
以下參考資料說明可搭配屬性 (以 x
、y
和 k
表示) 定義規則運算式的運算子。
作業 | 運算式 | 說明 |
---|---|---|
平等 | x == y |
如果 x 等於 y,則傳回 true。 |
相等性,字串常值 | x == "foo" |
如果 x 等於指定的常數字串文字,則傳回 true。 |
相等性,原始字串常值 | x == R"fo'o" |
如果 x 等於不解譯轉義序列的指定原始字串文字常值,則傳回 true。原始字串文字非常適合用來表示本身必須使用逸出序列字元的字串。 |
邏輯 NOT | !x |
如果布林值 x 為 false,則傳回 true;如果布林值 x 為 true,則傳回 false。 |
不等式 | x != y |
如果 x 不等於 y,則傳回 true。 |
串連 | x + y |
傳回串連字串 xy。 |
邏輯 AND | x && y |
如果 x 和 y 均為 true,則傳回 true。 |
邏輯 OR | x || y |
如果 x、y 或兩者皆為 true,則傳回 true。 |
包含子字串 | x.contains(y) |
如果字串 x 包含子字串 y,則傳回 true。 |
以子字串開頭 | x.startsWith(y) |
如果字串 x 開頭為子字串 y,則傳回 true。 |
結尾為子字串 | x.endsWith(y) |
如果字串 x 結尾為子字串 y,則傳回 true。 |
規則運算式比對 | x.matches(y) |
如果字串 x 部分符合指定的 RE2 模式 y,則傳回 true。RE2 模式是以 RE2::Latin1 選項編譯,該選項會停用萬國碼 (Unicode) 功能。 |
IP 位址位於範圍內 | inIpRange(x, y) |
如果 IP 位址 x 包含在 IP 範圍 y 中,則傳回「是」。 |
小寫 | x.lower() |
傳回字串 x 的小寫值。 |
Uppercase | x.upper() |
傳回字串 x 的大寫值。 |
Base64 解碼值 | x.base64Decode() |
傳回 x 的 Base64 解碼值;字元 _ - 會先分別替換為 / + 。如果 x 不是有效的 Base64 值,則傳回 "" (空字串)。 |
鍵/對應值 | m['k'] |
如果 k 可用,則傳回字串對字串對應 m 中索引鍵 k 的值;否則傳回錯誤。建議您先使用 "has(m['k'])==true" 檢查可用性。 |
檢查地圖中的索引鍵可用性 | has(m['k']) |
如果索引鍵 k 位於對應 m 中,則傳回「是」。 |
轉換為整數 | int(x) |
將 x 的字串結果轉換為 int 類型。接著,您可以使用標準算術運算子 (例如 > 和 <=) 進行整數比較。這項功能僅適用於應為整數的值。 |
長度 | size(x) |
傳回字串 x 的長度。 |
解碼網址 | x.urlDecode() |
傳回 x 的網址解碼值;%## 格式的字元序列會替換為非 ASCII 等價字元,而 + 會替換為空格。系統會原封不動地傳回無效的編碼。 |
解碼網址 (Unicode) | x.urlDecodeUni() |
傳回 x 的已解碼網址值;除了 urlDecode() ,這也處理 %u### 格式的 Unicode 字元序列。系統會原封不動地傳回無效的編碼。 |
將 utf8 轉換為 Unicode | x.utf8ToUnicode() |
傳回 UTF-8 編碼 x 的 小寫 Unicode 表示法。 |
屬性
屬性代表來自傳入要求的資訊,例如來源 IP 位址或要求的網址路徑。
欄位 | 類型 | 欄位說明 |
---|---|---|
origin.ip |
字串 | 要求的來源 IP 位址。 |
origin.user_ip |
字串 | 來源用戶端的 IP 位址,包含在上游 Proxy 的 HTTP-HEADER 中。使用這項屬性前,您必須在安全性政策的 advancedOptionsConfig 欄位中設定 userIpRequestHeaders[] 選項,以便與 True-Client-IP 、X-Forwarded-For 或 X-Real-IP 等來源相符。如果您未設定 |
origin.tls_ja3_fingerprint |
字串 | 如果用戶端使用 HTTPS 、HTTP/2 或 HTTP/3 進行連線,則會產生 JA3 TLS/SSL 指紋。如果沒有,則會傳回空白字串。 |
request.headers |
地圖 | HTTP 要求標頭的字串對字串對應。如果標頭含有多個值,這項對應中的值會是以半形逗號分隔的字串,當中包含標頭的所有值。這項對應中的鍵都是小寫。外部應用程式負載平衡器接受的所有標頭都會受到檢查,並套用相同的標頭限制。 建議做法是先使用 |
request.method |
字串 | HTTP 要求方法,例如 GET 或 POST 。 |
request.path |
字串 | 要求的 HTTP 網址路徑。 |
request.scheme |
字串 | HTTP 網址通訊協定,例如 http 或 https 。這個屬性的值皆為小寫。 |
request.query |
字串 | HTTP 網址查詢,採用 name1=value&name2=value2 格式,因為這會顯示在 HTTP 要求的第一行。未執行任何解碼作業。 |
origin.region_code |
字串 | 與來源 IP 相關聯的萬國碼 (Unicode) 國家/地區代碼,例如 US 。如果您建立的規則或運算式使用 ISO 3166-1 alpha 2 國家/地區代碼,Google Cloud Armor 會個別處理每個代碼。Google Cloud Armor 規則和運算式會明確使用這些區域代碼來允許或拒絕要求。 |
origin.asn |
整數 | 與來源 IP 位址相關聯的自治系統編號 (ASN)。系統會根據支援含有來源 IP 位址的 IP 位址前置字元的網路業者,決定全球唯一的 ASN。 |
reCAPTCHA 屬性
本節列出僅適用於 reCAPTCHA 符記或豁免 cookie 的屬性。如果要評估的 reCAPTCHA 權杖或豁免 cookie 因下列任一原因而無法使用或無效,則以這些屬性為基礎的子運算式會傳回 false
:
- 權杖格式錯誤,無法解碼。
- 權杖包含無效的屬性。例如,權杖是使用與規則相關聯的 reCAPTCHA 金鑰以外的 reCAPTCHA 金鑰產生。
- 權杖已過期。
豁免 cookie 屬性
欄位 | 類型 | 欄位說明 |
---|---|---|
token.recaptcha_exemption.valid |
bool |
存在有效的 reCAPTCHA 豁免 Cookie。 |
動作符記屬性
欄位 | 類型 | 欄位說明 |
---|---|---|
token.recaptcha_action.score |
float |
reCAPTCHA 動作權杖的分數。有效分數的範圍為 0.0 到 1.0 ,其中 0.0 很可能是不正當使用者,而 1.0 則很可能是合法使用者。 |
token.recaptcha_action.captcha_status |
string |
reCAPTCHA 動作權杖的驗證碼狀態。有效狀態為 NONE 、PASS 或 FAIL ,其中 NONE 是指 reCAPTCHA 評估期間沒有挑戰,因此動作符記中沒有人機驗證欄位。 |
token.recaptcha_action.action |
string |
reCAPTCHA 動作符記中的動作名稱 (最多 100 個半形字元)。 請參閱「動作名稱」。 |
token.recaptcha_action.valid |
bool |
存在有效的 reCAPTCHA 動作符記。 |
工作階段符記屬性
欄位 | 類型 | 欄位說明 |
---|---|---|
token.recaptcha_session.score |
float |
reCAPTCHA 工作階段符記的分數。有效分數的範圍為 0.0 到 1.0 ,其中 0.0 很可能是不正當使用者,而 1.0 則很可能是合法使用者。 |
token.recaptcha_session.valid |
bool |
存在有效的 reCAPTCHA 工作階段符記。 |
運算式範例
針對每個運算式,採取的動作取決於運算式是否包含在拒絕規則或允許規則中。
根據 IPv4 或 IPv6 中的 IP 位址範圍允許或拒絕存取
以下運算式會與
198.51.100.0/24
IP 位址範圍的請求相符:inIpRange(origin.ip, '198.51.100.0/24')
以下運算式會與
2001:db8::/32
IP 位址範圍的請求相符:inIpRange(origin.ip, '2001:db8::/32')
根據上游 Proxy 後方自訂的用戶端 IP 位址範圍,允許或拒絕存取權
如果您已設定 origin.user_ip
運算子,就可以根據 advancedOptionsConfig.userIpRequestHeaders[]
欄位中指定的標頭值進行比對。
以下運算式會比對來自
192.0.2.0/24
IP 位址範圍的要求:inIpRange(origin.user_ip, '192.0.2.0/24')
以下運算式會比對來自
2001:db8::/32
IP 位址範圍的要求:inIpRange(origin.user_ip, '2001:db8::/32')
允許或拒絕含有特定 Cookie 的流量
以下運算式會與含有
80=BLAH
的 Cookie 要求相符:has(request.headers['cookie']) && request.headers['cookie'].contains('80=BLAH')
使用非空白的 referer
標頭允許或拒絕流量
以下運算式會與含有非空
referer
標頭的要求相符:has(request.headers['referer']) && request.headers['referer'] != ""
根據標頭中的主機網址允許或拒絕流量
下列運算式會比對特定網址的要求:
request.headers['host'].lower().contains('test.example.com')
允許或拒絕特定區域的流量
如果您的網頁應用程式無法在 AU
區域使用,則必須封鎖該區域的所有要求。
在拒絕規則中使用下列運算式,比對來自
AU
區域的要求:origin.region_code == 'AU'
或者,如果您的網頁應用程式「僅」在 AU
區域提供服務,則必須封鎖來自所有其他區域的請求。
在拒絕規則中使用下列運算式,比對
AU
區域以外的所有區域要求:origin.region_code != 'AU'
區域代碼採用 ISO 3166-1 alpha 2 代碼。在某些情況下,地區會對應到國家/地區,但這並非一成不變的規則。舉例來說,US
代碼包含美國所有州、一個行政區和六個外圍地區。
允許或拒絕特定 ASN 的流量
如果您的網頁應用程式需要封鎖特定網路業者的客戶,您可以使用網路業者的 ASN 編號來封鎖。
在拒絕規則中使用下列運算式,比對特定 ASN 的要求:
origin.asn == 123
或者,如果您的網頁應用程式僅提供給特定網路業者的客戶使用,則必須封鎖所有其他網路業者的請求。
在拒絕規則中,請使用下列運算式,這會比對所有其他網路運算子,除了您要允許的運算子:
origin.asn != 123
多個運算式
如要在單一規則中加入多個條件,請結合多個子運算式。
在以下範例中,
AU
區域中1.2.3.0/24
的用戶 (例如您的 Alpha 測試人員) 提出的要求,會與下列運算式相符:origin.region_code == "AU" && inIpRange(origin.ip, '1.2.3.0/24')
下列運算式會比對
1.2.3.4
的要求,其中使用者代理程式包含WordPress
字串:inIpRange(origin.ip, '1.2.3.4/32') && has(request.headers['user-agent']) && request.headers['user-agent'].contains('WordPress')
允許或拒絕符合規則運算式的要求 URI 流量
以下運算式會比對 URI 中含有字串
/example_path/
的要求:request.path.matches('/example_path/')
以下運算式會比對
User-Agent
標頭欄位中含有Chrome
的要求:request.headers['user-agent'].matches('Chrome')
下列運算式顯示包含
wordpress
的User-Agent
標頭不區分大小寫比對結果,與User-Agent:WordPress/605.1.15
、User-Agent:wordPress
和其他wordpress
變化版本相符:request.headers['user-agent'].matches('(?i:wordpress)')
允許或拒絕含有特定 Base64 解碼值的流量
下列運算式會比對要求,這些要求的
user-id
標頭 Base64 解碼值為myValue
:has(request.headers['user-id']) && request.headers['user-id'].base64Decode().contains('myValue')
允許或拒絕含有特定長度字串值的流量
以下運算式會比對網址長度超過 10 個字元的請求:
size(request.path) > 10
以下運算式會比對標頭
x-data
長度大於或等於 1024 個字元的請求:size(request.headers['x-data']) >= 1024
允許或拒絕 HTTP 主體中 content-length
為零的流量
以下運算式會比對 HTTP 內容中含有零個
content-length
的要求:int(request.headers["content-length"]) == 0
允許或拒絕含有特定網址編碼值的流量
以下運算式會比對含有
%3c
的 Cookie 值要求:has(request.headers['cookie']) && request.headers['cookie'].urlDecode().contains('<')
允許或拒絕含有特定網址編碼值的 Unicode 字串流量
以下運算式會比對 Cookie 值等於
Match%2BValue
或Match%u002BValue
的要求:has(request.headers['cookie']) && request.headers['cookie'].urlDecodeUni() == 'Match+Value'
允許或拒絕包含 UTF-8 文字的特定萬國碼字串流量
以下運算式會比對 Cookie 值等於
¬
的要求:has(request.headers['cookie']) && request.headers['cookie'].utf8ToUnicode() == '%u00ac'
根據已知的 JA3 指紋允許或拒絕流量
以下運算式會比對 JA3 指紋等於
e7d705a3286e19ea42f587b344ee6865
的要求:origin.tls_ja3_fingerprint == 'e7d705a3286e19ea42f587b344ee6865'
根據 JA3 指紋清單允許或拒絕流量
以下運算式會比對 JA3 指紋等於下列任一 JA3 指紋的要求:
e7d705a3286e19ea42f587b344ee6865
f8a5929f8949e846267b582072e35f84
8f8b62163873a62234c14f15e7b88340
origin.tls_ja3_fingerprint == 'e7d705a3286e19ea42f587b344ee6865' || origin.tls_ja3_fingerprint == 'f8a5929f8949e846267b582072e35f84' || origin.tls_ja3_fingerprint == '8f8b62163873a62234c14f15e7b88340'
預先設定的網路應用程式防火牆規則
預先設定的 WAF 規則會使用預先設定的靜態簽章、規則或兩者,比對 HTTP POST 主體、HTTP 要求標頭和查詢參數。可用的預先設定 WAF 規則是以 OWASP 核心規則集第 3.3 版為基礎。Google Cloud Armor 提供多個預先定義的網路應用程式防火牆規則。如需預先設定的網路應用程式防火牆規則完整清單,請參閱 Google Cloud Armor 預先設定的網路應用程式防火牆規則總覽。
如要列出所有可用的預先設定網路應用程式防火牆規則,請參閱「列出可用的預先設定網路應用程式防火牆規則」。
如要進一步瞭解預先設定的 WAF 規則,請參閱用途說明「使用預先設定的 WAF 規則,減輕應用程式層攻擊」。
預先設定的網路應用程式防火牆規則名稱
預先設定的網路應用程式防火牆規則名稱格式為 <attack category>-<OWASP CRS version>-<version field>
。攻擊類別會指定您要防範的攻擊類型,例如 xss
(跨網站指令碼) 或 sqli
(SQL 注入)。
支援的版本欄位為 stable
和 canary
。規則的新增和修改內容會先在 canary
版本中發布。當新增和修改內容被視為安全且穩定時,就會升級至 stable
版本。
預先設定的網路應用程式防火牆規則成員 ID
預先設定的網路應用程式防火牆規則包含多個運算式,每個運算式都有其簽名。舉例來說,預先設定的網路應用程式防火牆規則 xss-v33-stable
包含名為 owasp-crs-v030301-id941100-xss
的運算式,對應於 3.3 版的規則 ID id941100
。您可以使用這些簽章來排除特定運算式的使用,這在特定運算式經常觸發誤判時非常實用。詳情請參閱誤判為垃圾內容的疑難排解資訊。
如要瞭解核心規則集和不同敏感度層級的調整方式,請參閱「調整 Google Cloud Armor 網路應用程式防火牆規則」。
預先設定的網路應用程式防火牆規則運算子
運算式 | 說明 |
---|---|
evaluatePreconfiguredWaf(string, MAP<string, dyn>) |
如果指定的 WAF 規則集合中任一 WAF 簽章傳回值為 true,則傳回值為 true。第一個引數是 WAF 規則集的名稱,例如 xss-v33-stable 。第二個引數 (選用) 是地圖,其中鍵為字串,而值則會根據鍵動態指定類型。這個引數的目的,是為了微調要評估哪些 WAF 簽章。可接受的鍵包括:
「opt_out_rule_ids」和「opt_in_rule_ids」鍵互斥,如果您想查看並手動啟用日後新增至現有規則集的 WAF 簽章,可以選擇使用「opt_in_rule_ids」。 |
evaluatePreconfiguredExpr(string, LIST) |
如果指定的預先設定網路應用程式防火牆規則中的任一運算式傳回「是」,則傳回「是」。 第一個引數是預先設定的網路應用程式防火牆規則名稱,例如 |
預先設定的網路應用程式防火牆規則範例
以下運算式會使用
xss-v33-stable
預先設定的網路應用程式防火牆規則,減輕 XSS 攻擊:evaluatePreconfiguredWaf('xss-v33-stable')
下列運算式會使用
xss-v33-stable
預先設定的網路應用程式防火牆規則中的所有運算式,但會排除成員 ID941100
和941110
:evaluatePreconfiguredWaf('xss-v33-stable', ['owasp-crs-v030301-id941100-xss', 'owasp-crs-v030301-id941110-xss'])
以下運算式會使用預先設定的網路應用程式防火牆規則,減輕來自
198.51.100.0/24
IP 位址範圍的 SQLi 攻擊:inIpRange(origin.ip, '198.51.100.0/24') && evaluatePreconfiguredWaf('sqli-v33-stable')