每條 Google Cloud Armor 安全性政策規則都有優先順序、相符條件和動作。Cloud Armor 會對符合要求的優先順序最高規則執行動作。如果規則的優先順序低於優先順序最高的相符規則,即使兩者具有相同的相符條件,系統也不會評估該規則。
每項安全性政策規則都支援兩種類型的比對條件:
- 基本比對條件包含 IP 位址清單或 IP 位址範圍清單。使用 Google Cloud CLI 建立規則時,請使用
--src-ip-ranges
旗標定義基本比對條件。 - 進階比對條件包含最多五個子運算式的運算式,可比對連入要求的各種屬性。使用 Google Cloud CLI 建立規則時,可透過
--expression
標記定義進階比對條件。
本頁面將說明進階比對條件,以及用來在安全性政策規則的進階比對條件中編寫運算式的 Cloud Armor 自訂規則語言。Cloud Armor 自訂規則語言是一般運算語言 (CEL) 的子集。以 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 位址,在 Cloud Armor 安全性政策規則中使用該運算式時,從配額角度來看,該規則仍視為具有進階比對條件的規則。詳情請參閱「Cloud Armor 配額與限制」。
作業
以下參考資料說明可搭配屬性 (以 x
、y
和 k
表示) 使用的運算子,用於定義規則運算式。
作業 | 運算式 | 說明 |
---|---|---|
平等 | x == y |
如果 x 等於 y,則傳回 true。 |
相等、字串常值 | x == "foo" |
如果 x 等於指定的常數字串常值,則傳回 true。 |
Equality,原始字串常值 | 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 內,則傳回 true。 |
小寫 | 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 中使用,則傳回 true。 |
轉換為整數 | int(x) |
將 x 的字串結果轉換為 int 型別。然後使用標準算術運算子 (例如 > 和 <=) 進行整數比較。這只適用於應為整數的值。 |
長度 | size(x) |
傳回字串 x 的長度。 |
解碼網址 | x.urlDecode() |
傳回 x 的網址解碼值;%## 格式的字元序列會替換為非 ASCII 等效字元,而 + 則會替換為空格。系統會原封不動地傳回無效的編碼。 |
解碼網址 (Unicode) | x.urlDecodeUni() |
傳回 x 的網址解碼值;除了 urlDecode() 之外,這也會處理 %u### 格式的 Unicode 字元序列。系統會原封不動地傳回無效的編碼。 |
將 UTF-8 轉換為 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_ja4_fingerprint |
字串 | JA4 TLS/SSL 指紋
如果用戶端使用 HTTPS 、HTTP/2 或 HTTP/3 連線,如果無法取得,則會傳回空白字串。 |
origin.tls_ja3_fingerprint |
字串 | JA3 TLS/SSL 指紋
如果用戶端使用 HTTPS 、HTTP/2 或 HTTP/3 連線,如果無法取得,則會傳回空白字串。 |
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 國家/地區代碼的規則或運算式,Cloud Armor 會個別處理每個代碼。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
下列運算式會比對標頭長度大於或等於 1024 個字元的要求:
x-data
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 文字的 Unicode 字串的流量
下列運算式會比對 Cookie 值等於
¬
的要求:has(request.headers['cookie']) && request.headers['cookie'].utf8ToUnicode() == '%u00ac'
根據已知的 JA4 指紋允許或拒絕流量
下列運算式會比對 JA4 指紋等於
t13d1516h2_8daaf6152771_b186095e22b6
的要求:origin.tls_ja4_fingerprint == 't13d1516h2_8daaf6152771_b186095e22b6'
根據 JA4 指紋清單允許或拒絕流量
下列運算式會比對 JA4 指紋,要求必須符合下列任一 JA4 指紋:
t00d0000h0_000000000000_000000000000
t13d1516h2_8daaf6152771_b186095e22b6
origin.tls_ja4_fingerprint == 't00d0000h0_000000000000_000000000000' || origin.tls_ja4_fingerprint == 't13d1516h2_8daaf6152771_b186095e22b6'
預先設定的網路應用程式防火牆規則
預先設定的 WAF 規則會使用預先設定的靜態簽章、正則運算式或兩者,比對 HTTP 要求主體、HTTP 要求標頭和查詢參數。可用的預先設定 WAF 規則是以 OWASP 核心規則集 3.3 版為準。Cloud Armor 提供多項預先定義的預先設定 WAF 規則。 如需預先設定的網路應用程式防火牆規則完整清單,請參閱「Cloud Armor 預先設定的網路應用程式防火牆規則總覽」。
如要列出所有可用的預先設定 WAF 規則,請參閱「列出可用的預先設定 WAF 規則」。
如要進一步瞭解預先設定的 WAF 規則,請參閱「使用預先設定的 WAF 規則防範應用程式層攻擊」一文。
預先設定的 WAF 規則名稱
預先設定的網路應用程式防火牆規則名稱格式為 <attack category>-<OWASP CRS version>-<version field>
。攻擊類別會指定您要防範的攻擊類型,例如 xss
(跨網站指令碼) 或 sqli
(SQL 植入)。
支援的版本欄位為 stable
和 canary
。規則的增修內容會先在 canary
版中發布,當新增內容和修改項目被視為安全且穩定時,就會升級至 stable
版本。
預先設定的 WAF 規則成員 ID
預先設定的 WAF 規則包含多個運算式,每個運算式都有自己的簽章。
舉例來說,預先設定的網路應用程式防火牆規則 xss-v33-stable
包含名為 owasp-crs-v030301-id941100-xss
的運算式,對應於 3.3 版的規則 ID id941100
。您可以使用簽章排除特定運算式,這在特定運算式持續觸發誤判時非常實用。詳情請參閱誤判疑難排解資訊。
如要瞭解核心規則集,以及如何調整不同敏感度層級,請參閱「調整 Google Cloud Armor 網路應用程式防火牆規則」。
預先設定的 WAF 規則的運算子
運算式 | 說明 |
---|---|
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) |
如果指定預先設定的網路應用程式防火牆規則中,有任何一個運算式傳回 true,則傳回 true。 第一個引數是預先設定的網路應用程式防火牆規則名稱,例如 |
預先設定的網路應用程式防火牆規則範例
下列運算式使用
xss-v33-stable
預先設定的網路應用程式防火牆規則,防範跨網站指令碼攻擊:evaluatePreconfiguredWaf('xss-v33-stable')
下列運算式會使用預先設定的網路應用程式防火牆規則中的所有運算式,但成員 ID
941100
和941110
除外:xss-v33-stable
evaluatePreconfiguredWaf('xss-v33-stable', {'opt_out_rule_ids': ['owasp-crs-v030301-id941100-xss', 'owasp-crs-v030301-id941110-xss']})
下列運算式使用預先設定的網路應用程式防火牆規則,防範來自
198.51.100.0/24
IP 位址範圍的 SQL 注入攻擊:inIpRange(origin.ip, '198.51.100.0/24') && evaluatePreconfiguredWaf('sqli-v33-stable')
其他運算子
運算式 | 說明 |
---|---|
evaluateThreatIntelligence(string) evaluateThreatIntelligence(string, LIST) evaluateThreatIntelligence(string, string, LIST)
|
如果來源 IP 位址與指定 IP 清單中的任何 IP 範圍相符,則傳回 true,除非使用排除清單明確排除。 第一個引數是 Google Threat Intelligence 資訊動態消息名稱,例如 |
evaluateAddressGroup(string, string) evaluateAddressGroup(string, string, LIST) evaluateOrganizationAddressGroup(string, string) evaluateOrganizationAddressGroup(string, string, LIST)
|
如果來源 IP 位址符合指定位址群組中的任何 IP 範圍,則傳回 true,除非使用排除清單明確排除。 第一個引數是位址群組名稱。第二個引數會決定要從何處擷取 IP 位址,可以是 |
evaluateAdaptiveProtection(string) |
如果要求與 Adaptive Protection 產生的攻擊簽章相符,則傳回 true。 這個引數是 Adaptive Protection 在偵測到攻擊時產生的特定快訊 ID。 |
evaluateAdaptiveProtectionAutoDeploy() |
如果要求來自與 Adaptive Protection 偵測到的持續攻擊相符的攻擊簽章,則傳回 true。 |
範例
下列運算式會根據 Google Threat Intelligence
iplist-known-malicious-ips
資訊動態饋給比對傳入要求,防範已知惡意 IP 清單中的 IP:evaluateThreatIntelligence('iplist-known-malicious-ips')
下列運算式會根據 Google 威脅情報
iplist-known-malicious-ips
動態消息比對傳入的要求,防範已知惡意 IP 清單中的 IP,但104.135.0.0/16
中的 IP 除外:evaluateThreatIntelligence('iplist-known-malicious-ips', ['104.135.0.0/16'])
下列運算式會將使用者 IP 的自訂要求標頭與名為
my-own-list-of-bad-ips
的位址群組進行比對:evaluateAddressGroup('my-own-list-of-bad-ips', origin.user_ip)