App Engine サービス用の送信 IP アドレス

URL Fetch API、Sockets API、Mail API などのアウトバウンド サービスは、IP アドレスの大きなプールを利用します。このプールの IP アドレス範囲は、定期的な変更の対象です。実際、同じアプリからの 2 つの連続した API 呼び出しは、2 つの異なる IP アドレスから発生したように見えることがあります。

サービスからの送信トラフィックに関連付けられた IP アドレスを知る必要がある場合は、サービスの現在の IP アドレス範囲を確認するか、サービスに対して静的 IP アドレスを設定します。

App Engine サービス用の IP アドレス

App Engine サービスの現在の IP アドレス範囲は、Google が公開している IP 範囲情報に基づいて確認できます。

  • Google では、インターネット上でユーザーが使用できる IP 範囲の完全なリストを goog.json で公開しています。

  • また、お客様の Google Cloud リソースで使用可能なグローバルとリージョンの外部 IP アドレス範囲のリストを cloud.json に公開しています。

Google API とサービスで使用される IP アドレスは、goog.json の範囲から cloud.json のすべての範囲を除いて計算された範囲のリスト内に収まります。このリストは頻繁に更新されます。

次の Python スクリプトを使用して、Google API とサービスで使用されている IP アドレス範囲のリストを作成できます。

このスクリプトの実行については、実行方法をご覧ください。

from __future__ import print_function

import json

try:
    from urllib import urlopen
except ImportError:
    from urllib.request import urlopen
    from urllib.error import HTTPError

import netaddr

IPRANGE_URLS = {
    "goog": "https://www.gstatic.com/ipranges/goog.json",
    "cloud": "https://www.gstatic.com/ipranges/cloud.json",
}


def read_url(url):
    try:
        return json.loads(urlopen(url).read())
    except (IOError, HTTPError):
        print("ERROR: Invalid HTTP response from %s" % url)
    except json.decoder.JSONDecodeError:
        print("ERROR: Could not parse HTTP response from %s" % url)


def get_data(link):
    data = read_url(link)
    if data:
        print("{} published: {}".format(link, data.get("creationTime")))
        cidrs = netaddr.IPSet()
        for e in data["prefixes"]:
            if "ipv4Prefix" in e:
                cidrs.add(e.get("ipv4Prefix"))
            if "ipv6Prefix" in e:
                cidrs.add(e.get("ipv6Prefix"))
        return cidrs


def main():
    cidrs = {group: get_data(link) for group, link in IPRANGE_URLS.items()}
    if len(cidrs) != 2:
        raise ValueError("ERROR: Could process data from Google")
    print("IP ranges for Google APIs and services default domains:")
    for ip in (cidrs["goog"] - cidrs["cloud"]).iter_cidrs():
        print(ip)


if __name__ == "__main__":
    main()

外向きの静的 IP アドレスの設定

App Engine スタンダード環境サービスに静的 IP アドレスを設定するには、Cloud Router と Cloud NAT によるサーバーレス VPC アクセスを使用します。サーバーレス VPC アクセスを使用すると、Virtual Private Cloud(VPC)ネットワークに下り(外向き)トラフィックを送信できます。VPC でネットワーク アドレス変換(NAT)ゲートウェイを使用すると、App Engine のトラフィックを専用の IP アドレス経由で転送できます。

Cloud NAT ゲートウェイと Cloud Router はコントロール プレーンのみを提供し、パケットが Cloud NAT ゲートウェイまたは Cloud Router を通過しないため、Cloud NAT 経由でルーティングしても、ネットワーク スタックで追加のホップは行われません。

外向きの静的 IP アドレスは、URL 取得サービスを使用して送信されるトラフィックには構成できません。URL 取得サービスを使用して送信されたトラフィックでは、引き続きパブリック IP アドレスプールが使用されます。すべての送信トラフィックで静的 IP アドレスを使用する場合は、ソケットを使用して URL 取得のデフォルトを無効にし、urlfetch パッケージの明示的な使用を中止します。

次の手順は、App Engine スタンダード環境サービスに対して外向きの静的 IP アドレスを設定する方法を示しています。

  1. roles/compute.networkAdmin ロールまたは同じ権限を持つカスタムロールがあることを確認します。

  2. VPC ネットワーク内に App Engine トラフィック用のサブネットワーク(サブネット)を作成します。これにより、VPC ネットワーク内の他のリソースが静的 IP アドレスを使用できなくなります。

    gcloud compute networks subnets create SUBNET_NAME \
        --range=RANGE \
        --network=NETWORK_NAME \
        --region=REGION

    上記のコマンドの要素をそれぞれ次のように置き換えます。

    • SUBNET_NAME は、サブネットに付ける名前に置き換えます。
    • RANGE は、このサブネットに割り当てる CIDR 形式の IP 範囲10.124.0.0/28 など)に置き換えます。
    • NETWORK_NAME は、VPC ネットワークの名前です。
    • REGION は、App Engine サービスのリージョンに置き換えます。
  3. App Engine サービスをサブネットに接続します。

    ガイドの VPC ネットワークへの接続に沿って、前のステップで作成したサブネットの名前をコネクタ サブネットに指定します。

  4. 新しい Cloud Router を作成します。Cloud Router は、Cloud NAT に必要なコントロール プレーン コンポーネントです。

    gcloud compute routers create ROUTER_NAME \
        --network=NETWORK_NAME \
        --region=REGION

    上記のコマンドの要素をそれぞれ次のように置き換えます。

    • ROUTER_NAME は、作成する Cloud Router リソースの名前に置き換えます。
    • NETWORK_NAME は、VPC ネットワークの名前です。
    • REGION には、NAT ゲートウェイを作成するリージョンを指定します。
  5. 静的 IP アドレスを予約します。

    これは、サービスが送信トラフィックの送信に使用するアドレスです。予約済み IP アドレス リソースは、関連付けられているリソースが削除されて再作成されるときに、元の IP アドレスを保持します。この IP アドレスは、Google Cloud プロジェクトの静的 IP アドレスの割り当てにカウントされます。

    gcloud compute addresses create ORIGIN_IP_NAME \
        --region=REGION

    上記のコマンドの要素をそれぞれ次のように置き換えます。

    • ORIGIN_IP_NAME は、IP アドレス リソースに割り当てる名前で置き換えます。
    • REGION は、Cloud NAT ルーターを実行するリージョンに置き換えます。レイテンシとネットワーク コストを最小限に抑えるには、App Engine サービスと同じリージョンを指定してください。

    結果を表示するには、compute addresses describe コマンドを使用します。

    gcloud compute addresses describe ORIGIN_IP_NAME
  6. Cloud NAT ゲートウェイを作成して、IP アドレスを指定します。

    サブネットからのトラフィックは、このゲートウェイを通過し、前のステップで予約した静的 IP アドレスを使用します。

    gcloud compute routers nats create NAT_NAME \
        --router=ROUTER_NAME \
        --region=REGION \
        --nat-custom-subnet-ip-ranges=SUBNET_NAME \
        --nat-external-ip-pool=ORIGIN_IP_NAME
      

    上記のコマンドの要素をそれぞれ次のように置き換えます。

    • NAT_NAME は、作成する Cloud NAT ゲートウェイ リソースの名前に置き換えます。
    • ROUTER_NAME は、Cloud Router の名前に置き換えます。
    • REGION には、NAT ゲートウェイを作成するリージョンを指定します。
    • ORIGIN_IP_NAME は、前の手順で作成した予約済み IP アドレス リソースの名前で置き換えます。
  7. サーバーレス VPC アクセスの下り(外向き)設定all-traffic に設定します。

    デフォルトでは、サーバーレス VPC アクセスを使用する App Engine サービスは、内部トラフィックのみを VPC ネットワークに送信します。指定した静的 IP アドレスを持つように、外部の宛先を含むトラフィックを VPC ネットワークに送信するには、下り(外向き)設定を変更する必要があります。

    サービスの app.yaml ファイルで下り(外向き)設定を指定します。

    vpc_access_connector:
      name: projects/PROJECT_ID/locations/REGION/connectors/CONNECTOR_NAME
      egress_setting: all-traffic

    次のように置き換えます。

    • PROJECT_ID は、Google Cloud プロジェクト ID に置き換えます。
    • REGION は、コネクタが存在するリージョンに置き換えます。
    • CONNECTOR_NAME は、コネクタの名前に置き換えます。

    サービスをデプロイします。

     gcloud app deploy