本頁內容適用於 Apigee 和 Apigee Hybrid。
查看
Apigee Edge 說明文件。
結果
您可以透過 AccessControl 政策,允許或拒絕特定 IP 位址存取 API。
這項政策是標準政策,可部署至任何環境類型。如要瞭解各環境類型適用的政策類型和可用性,請參閱「政策類型」。
影片:觀看短片,進一步瞭解如何允許或拒絕特定 IP 位址存取 API。
您可以在 API 代理流程中的任何位置附加這項政策,但最有可能是在流程開始時 ( Request / ProxyEndpoint / PreFlow) 檢查 IP 位址,甚至在驗證或配額檢查之前。
您也應考慮搭配使用 Google Cloud Armor 和 Apigee,做為保護 API 的替代方式。
範例
下列 IPv4 範例中的遮罩值會指出比對規則在允許或拒絕存取時,會考量四個八位元 (8、16、24、32 位元) 中的哪些位元。預設值為 32。詳情請參閱元素參考資料中的 mask
屬性。
拒絕 198.51.100.1
<AccessControl name="ACL"> <IPRules noRuleMatchAction = "ALLOW"> <MatchRule action = "DENY"> <SourceAddress mask="32">198.51.100.1</SourceAddress> </MatchRule> </IPRules> </AccessControl>
拒絕來自用戶端位址 198.51.100.1 的所有要求
允許來自任何其他用戶端位址的要求。
拒絕使用變數
<AccessControl name="ACL"> <IPRules noRuleMatchAction = "ALLOW"> <MatchRule action = "DENY"> <SourceAddress mask="{kvm.mask.value}">{kvm.ip.value}</SourceAddress> </MatchRule> </IPRules> </AccessControl>
假設您使用鍵/值對應 (KVM) 儲存遮蓋和 IP 的值。
這是在執行階段變更 IP 位址和遮蓋 IP 位址的實用方法,不必更新及重新部署 API Proxy。您可以使用 KeyValueMapOperations 政策,擷取含有 kvm.mask.value
和 kvm.ip.value
值的變數 (假設您在 KVM 政策中將變數命名為這些名稱,且這些變數含有來自 KVM 的遮罩和 IP 值)。如果您擷取的值為遮罩的 24
和 IP 位址的 198.51.100.1
,AccessControl 政策就會拒絕來自 198.51.100.* 的所有要求。
允許所有其他用戶端位址。
拒絕 198.51.100.*
<AccessControl name="ACL"> <IPRules noRuleMatchAction = "ALLOW"> <MatchRule action = "DENY"> <SourceAddress mask="24">198.51.100.1</SourceAddress> </MatchRule> </IPRules> </AccessControl>
拒絕來自用戶端位址 198.51.100.* 的所有要求
允許來自任何其他用戶端位址的要求。
198.51.*.*
<AccessControl name="ACL"> <IPRules noRuleMatchAction = "ALLOW"> <MatchRule action = "DENY"> <SourceAddress mask="16">198.51.100.1</SourceAddress> </MatchRule> </IPRules> </AccessControl>
拒絕來自用戶端地址 198.51.*.* 的所有要求
允許來自任何其他用戶端位址的要求。
拒絕 198.51.100.*,允許 192.0.2.1
<AccessControl name="ACL"> <IPRules noRuleMatchAction = "ALLOW"> <MatchRule action = "ALLOW"> <SourceAddress mask="32">192.0.2.1</SourceAddress> </MatchRule> <MatchRule action = "DENY"> <SourceAddress mask="24">198.51.100.1</SourceAddress> </MatchRule> </IPRules> </AccessControl>
拒絕來自用戶端位址 198.51.100.* 的所有要求,但允許 192.0.2.1。
允許來自任何其他用戶端位址的要求。
允許 198.51.*.*
<AccessControl name="ACL"> <IPRules noRuleMatchAction = "DENY"> <MatchRule action = "ALLOW"> <SourceAddress mask="16">198.51.100.1</SourceAddress> </MatchRule> </IPRules> </AccessControl>
允許來自位址 198.51.*.* 的所有要求
拒絕來自其他用戶端位址的要求。
允許多個 IP
<AccessControl name="ACL"> <IPRules noRuleMatchAction = "DENY"> <MatchRule action = "ALLOW"> <SourceAddress mask="24">198.51.100.1</SourceAddress> <SourceAddress mask="24">192.0.2.1</SourceAddress> <SourceAddress mask="24">203.0.113.1</SourceAddress> </MatchRule> </IPRules> </AccessControl>
允許來自用戶端位址的要求:198.51.100.* 192.0.2.* 203.0.113.*
拒絕所有其他地址。
拒絕多個 IP
<AccessControl name="ACL"> <IPRules noRuleMatchAction = "ALLOW"> <MatchRule action = "DENY"> <SourceAddress mask="24">198.51.100.1</SourceAddress> <SourceAddress mask="24">192.0.2.1</SourceAddress> <SourceAddress mask="24">203.0.113.1</SourceAddress> </MatchRule> </IPRules> </AccessControl>
拒絕來自用戶端位址的要求:198.51.100.* 192.0.2.* 203.0.113.*
允許所有其他地址。
允許多個 IP、拒絕多個 IP
<AccessControl name="ACL"> <IPRules noRuleMatchAction = "DENY"> <MatchRule action = "DENY"> <SourceAddress mask="24">198.51.100.1</SourceAddress> <SourceAddress mask="24">192.0.2.1</SourceAddress> <SourceAddress mask="24">203.0.113.1</SourceAddress> </MatchRule> <MatchRule action = "ALLOW"> <SourceAddress mask="16">198.51.100.1</SourceAddress> <SourceAddress mask="16">192.0.2.1</SourceAddress> <SourceAddress mask="16">203.0.113.1</SourceAddress> </MatchRule> </IPRules> </AccessControl>
允許:198.51.*.* 192.0.*.* 203.0.*.*
拒絕允許清單中的部分項目:198.51.100.* 192.0.2.* 203.0.113.*
使用須知
除了防範惡意 IP 存取 API,AccessControl 政策還能控管正當 IP 的存取權。舉例來說,如果您只允許企業控管的電腦存取測試環境中公開的 API,可以允許內部網路的 IP 位址範圍。在家工作的開發人員可以使用 VPN 存取這些 API。
設定及執行 AccessControl 政策時,需要進行下列作業:
- 定義一組「比對規則」,並為每項規則指定「允許」或「拒絕」動作。
- 針對每條比對規則,指定 IP 位址 (SourceAddress 元素)。
- 請參閱「政策如何選擇要評估的 IP 位址」,瞭解要設定規則來處理郵件中的哪些 IP 位址。
- 為每個 IP 位址設定遮罩。您可以根據 IP 位址的遮罩值允許或拒絕存取。請參閱「使用 CIDR 標記法遮蓋 IP 位址」一文。
- 指定規則的測試順序。
- 系統會依指定順序執行所有比對規則。如果規則相符,系統會執行相應動作,並略過後續比對規則。
- 如果為同一項規則設定 ALLOW 和 DENY 動作,系統會觸發順序中先定義的規則,並略過後續規則 (包含其他動作)。
政策如何選擇要評估的 IP 位址
IP 位址可能來自要求中的各種來源。舉例來說,X-Forwarded-For
標頭可能包含一或多個 IP 位址。本節說明如何設定 AccessControl 政策,評估您要評估的確切 IP 位址。
以下是 AccessControl 政策用來決定要評估哪個 IP 位址的邏輯:
X-Forwarded-For 標頭
Apigee 會自動在 X-Forwarded-For
標頭中填入從最後一次外部 TCP 交握收到的 IP 位址 (例如用戶端 IP 或路由器)。如果標頭中有多個 IP 位址,這些位址可能就是處理要求的伺服器鏈結。不過,地址清單也可能包含遭偽造的 IP 位址。那麼政策如何得知要評估哪些地址?
Apigee Analytics 中的 X-Forwarded-For 維度
Apigee Analytics 會將 X-Forwarded-For
標頭的值寫入 x_forwarded_for_ip
維度。如要判斷向 Apigee 提出要求的用戶端 IP,請使用 ax_resolved_client_ip
維度中的值,但排除 ax_true_client_ip
,因為 AccessControl 政策不支援這個值。請參閱「數據分析指標、維度和篩選器參考資料」。
使用 CIDR 標記法遮蓋 IP 位址
CIDR 標記法 (無類別跨網域路由) 是透過遮罩表示 IP 位址範圍的方法。這項限制適用於 IPv4 和 IPv6。運作方式如下:為簡單起見,我們會在範例中使用 IPv4。
IP 位址是由點號分隔的數字群組。以二進位來說,每個群組都是特定位元數 (IPv4 為 8 位元,IPv6 為 16 位元)。IPv4 位址 198.51.100.1 的二進位格式如下:
11000110.00110011.01100100.00000001
也就是 4 組 8 位元,總共 32 位元。使用 CIDR 時,您可以在 IP 位址中加入 /數字 (1 到 32),藉此指出範圍,例如:
198.51.100.1/24
在本例中,24 是您要在這項政策中使用的 mask
屬性值。
這個標記表示「前 24 位元保持不變,其餘位元可以是 0 到 255 之間的任何值」。例如:
請務必保留這些內容 | 最後一個群組的可能值 |
---|---|
198.51.100. | 0 到 255 |
請注意,遮罩會在第三個群組的結尾處發生。這樣一來,一切都會井然有序,本質上會建立類似 198.51.100.* 的遮罩。在大多數情況下,使用 8 的倍數 (IPv4) 和 16 的倍數 (IPv6) 即可達到所需的遮蓋程度:
IPv4:8、16、24、32
IPv6:16、32、48、64、80、96、112、128
不過,您可以使用其他數字進行更精細的控制,這需要進行一些二進位計算。以下範例使用 30 的遮罩,如 198.51.100.1/30,其中最後一個 1 在二進位中為 00000001:
請務必保留這些內容 | 可能的值 |
---|---|
11000110.00110011.01100100.000000 (前 30 位元) | 00000000、00000001、00000010 或 00000011 |
198.51.100. | 0、1、2 或 3 |
在這個範例中,如果設定為 <SourceAddress
mask="30">198.51.100.1</SourceAddress>
,系統會允許 (或拒絕,視規則而定) 下列 IP:
- 198.51.100.0
- 198.51.100.1
- 198.51.100.2
- 198.51.100.3
元素參考資料
元素參考資料說明 AccessControl 政策的元素和屬性。
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <AccessControl async="false" continueOnError="false" enabled="true" name="Access-Control-1"> <DisplayName>Access Control 1</DisplayName> <IPRules noRuleMatchAction = "ALLOW"> <MatchRule action = "ALLOW"> <SourceAddress mask="32">198.51.100.1</SourceAddress> </MatchRule> <MatchRule action = "DENY"> <SourceAddress mask="24">198.51.100.1</SourceAddress> </MatchRule> </IPRules> <ValidateBasedOn>X_FORWARDED_FOR_ALL_IP</ValidateBasedOn> </AccessControl>
<AccessControl> 屬性
<AccessControl async="false" continueOnError="false" enabled="true" name="Access-Control-1">
<ClientIPVariable> 元素
指定含有 IP 位址的流程變數,政策會根據 IPRules 檢查該位址。如果流程變數未包含有效的 IP 位址 (ipv4 或 ipv6),政策就會擲回錯誤。
假設流程變數設為 12.31.34.52
。在以下範例中,存取要求會遭到拒絕。如果變數設為 10.11.12.13
,系統就會授予存取權。
<AccessControl name='ACL'> <ClientIPVariable>FLOW_VARIABLE</ClientIPVariable> <IPRules noRuleMatchAction = 'DENY'> <MatchRule action = 'ALLOW'> <SourceAddress mask='32'>10.11.12.13</SourceAddress> </MatchRule> </IPRules> </AccessControl>
預設 | 不適用 |
---|---|
存在必要性 | 選用 |
類型 | 流程變數 |
<IgnoreTrueClientIPHeader> 元素
<IPRules> 元素
包含允許或拒絕 IP 位址的規則的上層元素。noRuleMatchAction
屬性可讓您定義如何處理比對規則未涵蓋的 IP 位址。
<IPRules noRuleMatchAction = "ALLOW">
預設 | 不適用 |
---|---|
存在必要性 | 選用 |
類型 | 不適用 |
屬性
屬性 | 說明 | 類型 | 預設 | 存在必要性 |
---|---|---|---|---|
noRuleMatchAction |
如果指定的相符規則未解析 (不相符),要採取的動作 (允許或拒絕存取)。
有效值:ALLOW 或 DENY
|
字串 | 允許 | 必填 |
<IPRules> 元素/<MatchRule> 元素
如果 IP 位址符合您定義的 SourceAddress (es),系統應採取的動作(允許或拒絕存取)。
<IPRules noRuleMatchAction = "ALLOW"> <MatchRule action = "ALLOW"> <SourceAddress mask="32">198.51.100.1</SourceAddress> </MatchRule> <MatchRule action = "DENY"> <SourceAddress mask="24">198.51.100.1</SourceAddress> </MatchRule> </IPRules>
預設 | 不適用 |
---|---|
存在必要性 | 選用 |
類型 | 不適用 |
屬性
屬性 | 說明 | 類型 | 預設 | 存在必要性 |
---|---|---|---|---|
動作 |
如果指定的相符規則未解析 (不相符),要採取的動作 (允許或拒絕存取)。 有效值:ALLOW 或 DENY |
字串 | 允許 | 必填 |
<IPRules>、<MatchRule>、<SourceAddress> 元素
用戶端的 IP 位址範圍。
有效值:有效的 IP 位址 (加點十進位標示法)。如要使用萬用字元行為,請使用 mask
屬性。
<IPRules noRuleMatchAction = "ALLOW"> <MatchRule action = "ALLOW"> <SourceAddress mask="{variable}">198.51.100.1</SourceAddress> </MatchRule> <MatchRule action = "DENY"> <SourceAddress mask="24">{variable}</SourceAddress> </MatchRule> </IPRules>
如上例所示,SourceAddress
元素也支援 mask
屬性或 IP 位址的訊息範本,也就是說,您可以使用 API Proxy 流程中目前可用的變數設定值。
舉例來說,您可以在鍵值對應 (KVM) 中儲存 IP 位址,並使用 KeyValueMapOperations 政策擷取 IP 位址,然後指派給變數 (例如 kvm.ip.value
)。接著,您就可以使用該變數做為 IP 位址:
<SourceAddress mask="24">{kvm.ip.value}</SourceAddress>
使用變數設定遮罩和/或 IP 位址,可讓您在執行階段變更值,不必修改及重新部署 API 代理。
預設 | 不適用 |
---|---|
存在必要性 | 選用 |
類型 | 字串 (僅限單一 IP 位址) |
屬性
屬性 | 說明 | 類型 | 預設 | 存在必要性 |
---|---|---|---|---|
遮蓋 |
相當於下列 CIDR 標記法: 198.51.100.1/24 有效值: IPv4:1-32 IPv6:1-128 只有 IP 0.0.0.0 適用零值 (0),因此不切實際。 使用變數設定遮罩
|
整數 | 不適用 | 必填 |
<ValidateBasedOn> 元素
如果 X-Forwarded-For
HTTP 標頭包含多個 IP 位址,請使用這個 ValidateBasedOn
元素控管要評估的 IP 位址。
只有在確定要評估的 IP 位址有效時,才使用這個方法。舉例來說,如果您選擇評估 X-Forwarded-For
標頭中的所有 IP 位址,就必須能夠信任這些位址的有效性,並/或設定全面的 DENY 或 ALLOW 規則,只允許受信任的 IP 呼叫您的 API Proxy。
標頭中最左側的 IP 位址屬於用戶端,最右側的 IP 位址則是將要求轉送至目前服務的伺服器。最右側或最後一個 IP 位址是 Apigee 從最後一次外部 TCP 交握收到的位址。
您可以在這個元素中輸入值,決定要檢查標頭中的所有 IP 位址 (預設)、第一個 IP 位址,還是最後一個 IP 位址。
<AccessControl async="false" continueOnError="false" enabled="true" name="Access-Control-1"> <DisplayName>Access Control 1</DisplayName> <IPRules noRuleMatchAction = "ALLOW"> <MatchRule action = "DENY"> <SourceAddress mask="32">198.51.100.1</SourceAddress> </MatchRule> </IPRules> <ValidateBasedOn>X_FORWARDED_FOR_ALL_IP</ValidateBasedOn> </AccessControl>
預設 | X_FORWARDED_FOR_ALL_IP |
---|---|
存在必要性 | 選用 |
有效值 |
|
結構定義
每個政策類型都是由 XML 結構定義 (.xsd) 定義。如需參考,請前往 GitHub 查看 政策結構定義。
錯誤參考資料
本節說明這項政策觸發錯誤時,Apigee 傳回的錯誤代碼和錯誤訊息,以及 Apigee 設定的錯誤變數。如果您要開發錯誤處理規則,就必須瞭解這項資訊。如需更多資訊,請參閱「關於政策錯誤的相關資訊」和「處理錯誤」。
執行階段錯誤
政策執行時可能會發生這些錯誤。
錯誤代碼 | HTTP 狀態 | 原因 | 修正 |
---|---|---|---|
accesscontrol.IPDeniedAccess |
403 |
用戶端 IP 位址或 API 要求中傳遞的 IP 位址,與存取控制政策 <MatchRule> 元素中 <SourceAddress> 元素中指定的 IP 位址相符,且 <MatchRule> 元素的 action 屬性設為 DENY 。 |
build |
accesscontrol.InvalidIPAddressInVariable |
500 |
<ClientIPVariable> 中的流程變數含有無效的 IP 位址。 |
錯誤變數
這些變數會在發生執行階段錯誤時設定。詳情請參閱「政策錯誤專屬變數」。
變數 | 地點 | 範例 |
---|---|---|
fault.name="fault_name" |
fault_name 是錯誤名稱,如上方「執行階段錯誤」表格所列。錯誤名稱是錯誤代碼的最後一個部分。 | fault.name Matches "IPDeniedAccess" |
acl.policy_name.failed |
policy_name 是擲回錯誤的政策的使用者指定名稱。 | acl.AC-AllowAccess.failed = true |
錯誤回應範例
{ "fault":{ "faultstring":"Access Denied for client ip : 52.211.243.3" "detail":{ "errorcode":"steps.accesscontrol.IPDeniedAccess" } } }
錯誤規則範例
<FaultRule name="IPDeniedAccess"> <Step> <Name>AM-IPDeniedAccess</Name> <Condition>(fault.name Matches "IPDeniedAccess") </Condition> </Step> <Condition>(acl.failed = true) </Condition> </FaultRule>