App Engine 서비스의 아웃바운드 IP 주소

URL 가져오기, Socket, Mail API와 같은 아웃바운드 서비스는 대규모 IP 주소 풀을 사용합니다. 이러한 풀의 IP 주소 범위는 계속 변합니다. 실제로, 동일한 애플리케이션에서 연달아 실행된 2개의 API 호출은 서로 다른 2개의 IP 주소에서 시작된 것처럼 보일 것입니다.

서비스의 아웃바운드 트래픽과 연결된 IP 주소를 알아야 하는 경우 서비스의 현재 IP 주소 범위를 찾거나 서비스의 고정 IP 주소를 설정할 수 있습니다.

App Engine 서비스의 IP 주소

Google이 게시하는 IP 범위 정보를 기반으로 App Engine 서비스의 현재 IP 주소 범위를 찾을 수 있습니다.

  • Google은 인터넷 사용자에게 제공되는 IP 범위의 전체 목록을 goog.json에 게시합니다.

  • 또한 Google은 고객이 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) 게이트웨이를 사용하여 전용 IP 주소를 통해 App Engine 트래픽을 라우팅할 수 있습니다.

Cloud NAT 게이트웨이 및 Cloud Router가 제어 영역만 제공하고, 패킷이 Cloud NAT 게이트웨이 또는 Cloud Router를 통과하지 않기 때문에 Cloud NAT를 통해 트래픽을 라우팅해도 네트워킹 스택에 추가 홉이 발생하지 않습니다.

URL Fetch 서비스를 사용하여 전송된 트래픽에는 고정 아웃바운드 IP 주소를 구성할 수 없습니다. URL Fetch 서비스를 사용하여 전송된 트래픽은 공개 IP 주소 풀을 계속 사용합니다. 모든 아웃바운드 트래픽에 고정 IP 주소를 사용하려면 소켓을 사용하여 URL Fetch 기본값을 사용 중지하고 urlfetch 패키지의 명시적 사용을 중단합니다.

다음 단계는 App Engine 표준 환경 서비스의 고정 아웃바운드 IP 주소를 설정하는 방법을 보여줍니다.

  1. roles/compute.networkAdmin 역할 또는 동일한 권한을 가진 커스텀 역할이 있어야 합니다.

  2. App Engine 트래픽의 VPC 네트워크 내에 서브네트워크(서브넷)를 만듭니다. 이렇게 하면 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 네트워크로만 전송합니다 외부 대상으로 보낼 트래픽을 VPC 네트워크로 전송하려면 VPC 네트워크에서 지정된 고정 IP 주소를 사용하도록 이그레스 설정을 변경해야 합니다.

    서비스의 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