AccessControl ポリシー

概要

Access Control ポリシーを使用すると、API に対する特定の IP アドレスからのアクセスを許可または拒否できます。

動画: 特定の IP アドレスごとに API へのアクセスを許可または拒否する方法については、この短い動画をご覧ください。

このポリシーは、API プロキシフロー中の任意の場所に接続できます。しかし、フロー(Request / ProxyEndpoint / PreFlow)の最初や、認証の前、または割り当ての確認の前に IP アドレスをチェックする可能性が高いと思われます。

サンプル

次に示す IPv4 のサンプルでは、マスク値によって、照合ルールがアクセスを許可または拒否する際に 4 オクテット(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>

マスクと IP の値の保存に、Key-Value マップ(KVM)を使用していると仮定します。その場合は、API プロキシの更新と再デプロイが必要なく、ランタイムに IP の変更やマスキングが簡単にできます。KeyValueMapOperations ポリシーを使用して、kvm.mask.valuekvm.ip.value の値を含む変数を取得できます(KVM のマスク値と IP 値を含む KVM ポリシーの変数にそのような名前を付けていると仮定)。取得したマスク値が 24、IP アドレスが 198.51.100.1 である場合、「198.51.100.*」からのすべてのリクエストが、AccessControl ポリシーによって拒否されます。

その他のクライアント アドレスは、すべて許可されます。

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.*


使用上の注意

Access Control ポリシーは、悪意のある IP から API を保護するだけでなく、正当な IP からアクセスを制御することも可能とします。たとえば、テスト環境内で一般公開している API へのアクセスを自社の管理下にあるコンピュータに限定するために、内部ネットワーク IP アドレスの範囲だけを許可できます。在宅勤務のデベロッパーは、VPN を使用することで API にアクセスできます。

Access Control ポリシーの構成と実行は、次のとおりです。

  • 照合ルールのセットを定義し、それぞれに関連付けられた 2 つのアクション(ALLOW または DENY)のいずれかを指定します。
  • 照合ルールごとに、IP アドレスを指定します(SourceAddress 要素)。
  • ルールを試行する順序を指定します。
  • すべての照合ルールが指定された順に実行されます。照合ルールが一致すると、それに対応するアクションが実行され、その後の照合ルールはスキップされます。
    • 同じルールに ALLOW と DENY の両方のアクションが構成されている場合、最初に定義されたルールがトリガーされ、後のルールは(その他のアクションとともに)スキップされます。

評価する IP アドレスの選択方法

IP アドレスは、リクエスト内のさまざまなソースから取得できます。たとえば、True-Client-IP メッセージ ヘッダーには IP アドレス、X-Forwarded-For ヘッダーには 1 つ以上の IP アドレスがそれぞれ含まれます。このセクションでは、目的の IP アドレスが評価されるように、AccessControl ポリシーを構成する方法について説明します。

AccessControl ポリシーで、評価対象となる IP アドレスの決定に使用されるロジックは次のとおりです。

1. True-Client-IP ヘッダー

このポリシーでは、最初に True-Client-IP ヘッダーの IP アドレスが確認されます。ヘッダーに有効な IP アドレスが含まれている場合、ポリシーはそのアドレスを評価します。

2. X-Forwarded-For ヘッダー

True-Client-IP ヘッダーが存在しない場合、または <IgnoreTrueClientIPHeader> 要素を true に設定した場合は、ポリシーは X-Forwarded-For ヘッダーの IP アドレスを評価します。

Edge によって、最後の外部 TCP handshake(クライアント IP やルーターなど)から受信した IP アドレスが X-Forwarded-For ヘッダーに事前入力されます。ヘッダーに複数の IP アドレスが入力されている場合、それらのアドレスはリクエストを処理した一連のサーバーである可能性があります。しかし、アドレスのリストになりすましの IP アドレスが含まれている可能性もあります。このとき、ポリシーが評価するアドレスは何に基づいて決定されるでしょうか。

ポリシーが評価する X-Forwarded-For アドレスは、組織構成とポリシー構成によって決定されます。

組織に feature.enableMultipleXForwardCheckForACL プロパティが設定されているかどうかを確認します。これは、Get Organization API を使用して確認できます。次に、以下のように指定します。

  • 組織のプロパティ リストに feature.enableMultipleXForwardCheckForACL が表示されない場合は、プロパティが false(デフォルト)に設定されていることを表します。このプロパティを false に設定すると、ポリシーは、Edge が最後の外部 TCP handshake から受信した IP アドレスであるヘッダー内の最後のアドレス(Trace ツールに表示)を評価します。
  • 組織の feature.enableMultipleXForwardCheckForACL が true に設定されている場合は、ポリシーが評価する IP アドレスが特定されるように <ValidateBasedOn> 要素を構成します。

feature.enableMultipleXForwardCheckForACL プロパティの変更

Edge 組織管理者は、組織プロパティ更新 API を使用して、feature.enableMultipleXForwardCheckForACL プロパティを設定できます。

次の API の例では、Edge for Private Cloud でプロパティを設定しています。その他のプロパティが組織に設定されている場合は、それも含めます。含めなかった場合は、削除されます

curl -u email:password -X POST -H "Content-type:application/xml" http://host:8080/v1/o/myorg -d \
"<Organization type="trial" name="MyOrganization">
    <DisplayName>MyOrganization</DisplayName>
    <Properties>
        <Property name="feature.enableMultipleXForwardCheckForACL">true</Property>
        <!-- Include other existing properties as well. -->
    </Properties>
</Organization>"

Edge for Private Cloud で、feature.enableMultipleXForwardCheckForACL プロパティの値を変更した後、個々のコンポーネントの起動 / 停止 / 再起動の説明に従ってメッセージ プロセッサを再起動します。

Apigee Analytics の X-Forwarded-For ディメンション

Edge Analytics によって、X-Forwarded-For ヘッダーの値が x_forwarded_for_ip ディメンションに書き込まれます。Edge にリクエストを送信したクライアント IP を特定するには、ax_true_client_ip または ax_resolved_client_ip ディメンションの値を使用します。詳しくは、アナリティクスの指標、ディメンション、フィルタのリファレンスをご覧ください。

CIDR 表記での IP マスキングについて

CIDR(クラスレス ドメイン間ルーティング)表記は、IP アドレスの範囲をマスキングによって示す方法です。これは、IPv4 と IPv6 の両方に適用されます。ここでその仕組みについて説明します。次に示す例では、簡単にするため IPv4 を使用しています。

IP アドレスは、ピリオドで区切られた数字のグループです。バイナリの場合、各グループは特定のビット数(IPv4 では 8、IPv6 では 16)になります。IPv4 アドレス「198.51.100.1」は、バイナリでは次のようになります。

11000110.00110011.01100100.00000001

8 ビットのグループが 4 つあるので、合計 32 ビットになります。CIDR を使用すると、次のように IP アドレスに「/数字(1-32)」を追加して、範囲を指定できます。

198.51.100.1/24

この場合、24 はこのポリシーの mask 属性値に使用する数字です。

この表記は、「最初の 24 ビットをそのまま維持し、残りのビットは 0~255 の任意の値でよい」という意味です。次に例を示します。

この値はそのまま維持 最後のグループの可能値
198.51.100. 0~255

グループ 3 の最後でマスクが発生している点が重要です。これによって整えられた「198.51.100.*」のようなマスクが生成されます。ほとんどの場合、8 の倍数(IPv4 の場合)と 16 の倍数(IPv6 の場合)を使用すると、必要なマスキング レベルが得られます。

IPv4: 8、16、24、32

IPv6: 16、32、48、64、80、96、112、128

ただし、細かいバイナリ計算を含む微調整には、その他の数字も使用できます。たとえば、198.51.100.1/30(最後の 1 はバイナリの 00000001)はマスクとして 30 を設定した例です。

この値はそのまま維持 可能値
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

要素リファレンス

この要素リファレンスでは、Access Control ポリシーの要素と属性について説明します。

<?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">

次の表に、ポリシーのすべての親要素に共通の属性を記載します。

属性 説明 デフォルト 要否
name

ポリシーの内部名。name 属性の値には、文字、数字、スペース、ハイフン、アンダースコア、ピリオドを使用できます。255 文字を超える値を指定することはできません。

必要に応じて、管理 UI プロキシ エディタで <DisplayName> 要素を使用してポリシーに別のわかりやすい名前でラベルを付けます。

なし 必須
continueOnError

ポリシーが失敗した場合にエラーを返すには、false に設定します。これはほとんどのポリシーで想定される動作です。

ポリシーが失敗してもフロー実行を続行するには、true に設定します。

false 省略可
enabled

ポリシーを適用するには true に設定します。

ポリシーを無効にするには false に設定します。その場合、ポリシーはフローに接続されていているとしても適用されません。

true 省略可
async

この属性は非推奨となりました。

false 非推奨

<DisplayName> 要素

name 属性に加えて、管理 UI プロキシ エディタのポリシーに別のわかりやすい名前でラベルを付けるために使います。

<DisplayName>Policy Display Name</DisplayName>
デフォルト:

なし

この要素を省略した場合、ポリシーの name 属性の値が使用されます

要否: 省略可
型: 文字列

<IgnoreTrueClientIPHeader> 要素

true に設定すると、ポリシーは True-Client-IP ヘッダーを無視し、構成した X-Forwarded-For 評価動作に従って X-Forwarded-For ヘッダーの IP アドレスを評価します。


<AccessControl async="false" continueOnError="false" enabled="true" name="Access-Control-1">
    <DisplayName>Access Control-1</DisplayName>
    <IgnoreTrueClientIPHeader>true</IgnoreTrueClientIPHeader>
    ...
</AccessControl>

デフォルト false
要否 省略可
ブール値

<IPRules> 要素

IP アドレスを許可または拒否するルールを含む、親要素。noRuleMatchAction 属性を使用すると、照合ルールの対象ではない IP アドレスの処理方法を定義できます。

<IPRules noRuleMatchAction = "ALLOW">
デフォルト なし
要否 省略可
なし

属性

属性 説明 デフォルト 要否
noRuleMatchAction
指定した照合ルールが解決されなかった場合(不一致の場合)に実行するアクション(アクセスの許可または拒否)。
有効な値: ALLOW または DENY
文字列 ALLOW 必須

<IPRules>/<MatchRule> 要素

IP アドレスが、定義した SourceAddress に一致した場合に実行するアクション(アクセスの許可または拒否)。

<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

文字列 ALLOW 必須

<IPRules> / <MatchRule> / <SourceAddress> 要素

クライアントの IP アドレス範囲。

有効な値: 有効な IP アドレス(ドット区切りの 10 進表記)。ワイルドカードの動作には、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 プロキシフロー内で利用できる変数を使用して値を設定できるということです。

たとえば、Key-Value マップ(KVM)に IP アドレスを保存し、KeyValueMapOperations ポリシーを使用して IP アドレスを取得して、変数(kvm.ip.value など)に割り当てることができます。この変数を IP アドレスに使用できます。

<SourceAddress mask="24">{kvm.ip.value}</SourceAddress>

マスクまたは IP アドレスを変数で設定すると、API プロキシを再デプロイすることなく、ランタイムに値を柔軟に変更できるようになります。

デフォルト なし
要否 省略可
文字列(単一 IP アドレスのみ)

属性

属性 説明 デフォルト 要否
マスク

mask 属性は、許可または拒否する IP アドレスの範囲を指定する方法です。CIDR(クラスレス ドメイン間ルーティング)表記を使用するマスクと同等です。例:

<SourceAddress mask="24">198.51.100.1</SourceAddress>

は次の CIDR 表記と同等です。

198.51.100.1/24

有効な値:

IPv4: 1~32

IPv6: 1~128

値をゼロ(0)とするのは IP「0.0.0.0」に対してのみ有効になるため、実際的ではありません。

マスクを変数で設定する

mask 属性に対しては、メッセージ テンプレートもサポートされます。API プロキシフローで現在利用可能な変数を使用して値を設定できます。たとえば、マスク値を KVM に格納し、KeyValueMapOperations ポリシーを使用してそれを変数に割り当てることができます。変数で IP マスクを設定するには、次の形式を使用します(変数の名前が kvm.mask.value であると仮定)。

mask="{kvm.mask.value}"

整数 なし 必須

<ValidateBasedOn> 要素

X-Forwarded-For HTTP ヘッダーに複数の IP アドレスが含まれている場合は、この ValidateBasedOn 要素を使用して、評価する IP アドレスの選択を制御します。

この方法は、評価する IP アドレスの有効性が確実な場合にのみ、IP アドレスを評価するために使用します。たとえば、X-Forwarded-For ヘッダーのすべての IP アドレスを評価する場合は、それらのアドレスの有効性を信頼できるか、信頼できる IP だけが API プロキシを呼び出せるように包括的 DENY ルールまたは ALLOW ルールを設定する必要があります(両方が必要な場合もあります)。

ヘッダーの左端の IP アドレスはクライアントに属するもので、右端は現在のサービスにリクエストを転送したサーバーです。右端(最後の IP アドレス)は、最後の外部 TCP handshake から Edge が受信したアドレスです。

この要素に入力する値によって、ヘッダー内の 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
要否 省略可
文字列
有効な値
  • X_FORWARDED_FOR_ALL_IP(デフォルト)
  • X_FORWARDED_FOR_FIRST_IP
  • X_FORWARDED_FOR_LAST_IP

スキーマ

各ポリシータイプは XML スキーマ(.xsd)で定義されています。GitHub に参照用のポリシー スキーマが用意されています。

エラー リファレンス

このセクションでは、このポリシーでエラーが発生したときに返される障害コードとエラー メッセージ、Edge によって設定される障害変数について説明します。これは、障害を処理するルールを作成する際に重要な情報となります。詳細については、ポリシーエラーについて知っておくべきこと障害の処理をご覧ください。

ランタイム エラー

ポリシーの実行時に次のエラーが発生することがあります。

障害コード HTTP ステータス 原因
steps.accesscontrol.ClientIpExtractionFailed 500 障害文字列を参照してください。
steps.accesscontrol.IPDeniedAccess 403 障害文字列を参照してください。

デプロイエラー

このポリシーを含むプロキシのデプロイで、次のエラーが発生することがあります。

エラー名 原因
InvalidIPAddress エラー メッセージを参照してください。
InvalidIPv4Address エラー メッセージを参照してください。
InvalidIPv6Address エラー メッセージを参照してください。
InvalidRulePattern エラー メッセージを参照してください。

障害変数

ランタイム エラーが発生すると、次の変数が設定されます。詳しくは、ポリシーエラーに固有の変数をご覧ください。

変数 説明
fault.name="fault_name" fault_name は障害名です。詳しくは、上のランタイム エラーの表をご覧ください。障害コードの最後の部分が障害名になります。 fault.name Matches "IPDeniedAccess"
acl.policy_name.failed policy_name は、障害が発生したユーザー指定のポリシー名です。 acl.AC-AllowAccess.failed = true

障害レスポンスの例

    {
       "fault":{
          "detail":{
             "errorcode":"steps.accesscontrol.IPDeniedAccess"
          },
          "faultstring":"Access Denied for client ip : 52.211.243.3"
       }
    }
    

障害ルールの例

    <FaultRule name="IPDeniedAccess">
        <Step>
            <Name>AM-IPDeniedAccess</Name>
            <Condition>(fault.name Matches "IPDeniedAccess") </Condition>
        </Step>
        <Condition>(acl.failed = true) </Condition>
    </FaultRule>