1. 소개
이 Codelab에서는 VPC 서비스 제어를 사용하여 BigQuery API를 보호하는 방법을 알아봅니다. 이 Codelab은 서비스 경계로 보호되는 API 서비스가 없는 상태에서 시작하므로 공개 데이터 세트에서 쿼리를 실행하고 결과를 프로젝트 테이블에 저장할 수 있습니다. 쿼리는 한 프로젝트에서 실행되고 결과가 저장되는 테이블은 다른 프로젝트에서 생성되어 한 프로젝트에 데이터를 저장할 수 있지만 다른 프로젝트를 사용하여 액세스해야 하는 설정을 모방합니다.
다음으로 데이터 프로젝트를 보호하기 위한 서비스 경계를 소개합니다. 인그레스 규칙과 이그레스 규칙을 사용하여 관찰된 위반사항을 수정하고 나중에 액세스 수준을 추가하여 내부 IP 주소를 사용하여 액세스를 제한하는 방법을 알아봅니다. 이 Codelab의 목표는 다음과 같습니다.
- 인그레스 및 이그레스 규칙을 사용하여 각각 인그레스 및 이그레스 위반을 수정하는 방법을 알아봅니다.
- 특정 위반이 발생한 이유를 파악합니다.
- 적용된 위반 수정의 범위를 분석합니다.
- 액세스 수준을 사용하여 VPC 네트워크의 내부 IP 주소에서 트래픽을 허용하는 옵션을 활용하여 범위를 변경하도록 수정사항 (인그레스 / 이그레스 규칙)을 수정합니다.
2. 리소스 설정 및 요구사항
시작하기 전에
이 Codelab에서는 다음 사항을 이미 알고 있다고 가정합니다.
- BigQuery 쿼리 실행의 기본사항: 이 Codelab에서 BigQuery의 Wikipedia 데이터 세트를 쿼리하는 방법을 확인할 수 있습니다.
- 폴더를 만들고 관리하는 방법
- 폴더에서 프로젝트를 만드는 방법 또는 폴더에서 기존 프로젝트를 이동하는 방법
- 범위가 지정된 액세스 정책을 만드는 방법
- 서비스 경계를 만들고 구성하는 방법
- 로그에서 보안 정책 위반을 찾는 방법
설정
초기 설정은 다음과 같이 설계됩니다.
- Google Cloud 조직
- 조직 아래의 폴더입니다. 이 Codelab에서는
codelab-folder이라고 부르겠습니다. codelab-folder폴더에 배치된 두 개의 Google Cloud 프로젝트 이 Codelab에서는project-1및project-2이라고 합니다.- 폴더와 프로젝트가 아직 생성되지 않은 경우 Google Cloud 콘솔에서 조직 아래에 폴더를 만들고 생성된 폴더 아래에 새 프로젝트 두 개를 만듭니다.
- 필요한 권한:
- 폴더 관리 IAM 역할: 폴더 수준에서 할당됨
- 프로젝트 관리용 IAM 역할: 프로젝트 수준에서 할당됨
- VPC 서비스 제어를 구성하는 데 필요한 IAM 역할: 조직 수준에서 할당됨
- BigQuery 관리용 IAM 역할: 프로젝트 수준에서 할당됨
- Compute Engine 인스턴스 관리용 IAM 역할: 프로젝트 수준에서 할당됨
- 두 프로젝트(
project-2및project-1)의 결제 계정
일반 서비스 경계 만들기
이 Codelab에서는 project-1를 보호하는 일반 서비스 경계를 사용합니다.
- 일반 경계(
perimeter-1)를 만들고project-1을 추가합니다.
Compute Engine VM 만들기
이 Codelab에서는 us-central1에 있고 default라는 기본 VPC 네트워크를 사용하는 project-2의 Compute Engine 인스턴스 1개를 사용합니다.
- 문서를 가이드라인으로 참고하여 공개 이미지에서 Compute Engine 인스턴스를 만들 수 있습니다.
비용
클라우드 리소스/API를 사용하려면 Google Cloud 콘솔에서 결제를 사용 설정해야 합니다. 이 Codelab을 마친 후 비용이 청구되지 않도록 사용한 리소스를 종료하는 것이 좋습니다. Google Cloud 신규 사용자는 미화 $300 상당의 무료 체험판 프로그램에 참여할 수 있습니다.
비용이 발생하는 리소스는 BigQuery 및 Compute Engine 인스턴스입니다. BigQuery 가격 계산기와 Compute Engine 가격 계산기를 사용하여 비용을 추정할 수 있습니다.
3. VPC 서비스 제어 제한 없이 BigQuery에 액세스
공개 데이터 세트 쿼리 및 결과를 project-1에 저장
project-2및project-1에 액세스하여 BigQuery Studio 페이지를 방문하여 BigQuery API에 액세스할 수 있는지 확인합니다.project-1가 서비스 경계에 있더라도 경계가 아직 서비스를 보호하지 않으므로 이 작업을 수행할 수 있습니다.project-2에서 다음 쿼리를 실행하여 공개 데이터 세트를 쿼리합니다.
SELECT name, SUM(number) AS total
FROM `bigquery-public-data.usa_names.usa_1910_2013`
GROUP BY name
ORDER BY total DESC
LIMIT 10;
공개 데이터 세트에 대한 쿼리를 실행한 후 (project-2에 남아 있는 상태):
- 결과 저장을 클릭하고 BigQuery 테이블을 선택합니다. (아래 스크린샷 참고)

- 대상 프로젝트로
project-1을 선택합니다. - 데이터 세트 이름을
codelab_dataset로 지정합니다. (기존 데이터 세트를 사용하지 않는 경우 새 데이터 세트 만들기를 선택합니다.)
- 테이블 이름을
codelab-table로 지정합니다. - 저장을 클릭합니다.
project-2에서 쿼리를 실행한 결과 공개 데이터 세트 데이터가 project-1에 저장되었습니다.
project-2에서 project-1에 저장된 데이터 세트 쿼리
project-2 BigQuery Studio에 머무른 상태에서 다음 쿼리를 실행하여 다음에서 데이터를 선택합니다.
- 프로젝트:
project-1 - 데이터 세트:
codelab_dataset - 테이블:
codelab-table
SELECT name, total
FROM `project-1.codelab_dataset.codelab-table`
ORDER BY total DESC
LIMIT 10;
project-2와 project-1 모두 BigQuery 사용이 제한되지 않으므로 쿼리가 성공적으로 실행됩니다. 사용자에게 적절한 IAM 권한이 있는 경우 어디에서나 BigQuery에 액세스할 수 있습니다.
이 다이어그램은 주 구성원이 BigQuery 데이터 세트를 쿼리할 때의 프로세스를 보여줍니다. 각 BigQuery 쿼리는 BigQuery 작업을 시작하고 이 작업은 이 시나리오에서 데이터를 가져오는 실제 작업을 실행합니다. Compute Engine 인스턴스 및 인터넷에서 주 구성원 액세스가 시연되며, 공개 데이터 세트 및 별도의 Google Cloud 프로젝트에서 쿼리합니다. 데이터를 쿼리하는 프로세스 (
GetData)는 VPC 서비스 제어에 의해 차단되지 않고 성공합니다.
4. 소스 데이터 세트 프로젝트에서 BigQuery API 보호
경계 perimeter-1의 구성을 수정하고 보호된 리소스가 project-1인 BigQuery API 서비스를 제한합니다.

서비스 경계 시행 확인
project-2에서 이전 단계와 같이 BigQuery Studio에서 다음 쿼리를 실행합니다.
SELECT name, total
FROM `project-1.codelab_dataset.codelab-table`
ORDER BY total DESC
LIMIT 10;
VPC 서비스 제어 RESOURCES_NOT_IN_SAME_SERVICE_PERIMETER 위반이 발생합니다.

위반 감사 로그는 경계를 교차하는 위반이 발생한 project-1에 있습니다. 관찰된 vpcServiceControlsUniqueId로 로그를 필터링할 수 있습니다 (VPC_SC_DENIAL_UNIQUE_ID을 관찰된 고유 ID로 대체).
severity=ERROR
resource.type="audited_resource"
protoPayload.metadata.@type="type.googleapis.com/google.cloud.audit.VpcServiceControlAuditMetadata"
protoPayload.metadata.vpcServiceControlsUniqueId="[*VPC_SC_DENIAL_UNIQUE_ID*]"
위반은 다음이 포함된 egressViolations입니다.
principalEmail: [쿼리를 실행하는 사용자 계정]callerIp: [쿼리를 실행하는 사용자 에이전트의 IP 주소]
"egressViolations": [
{
"targetResource": "projects/project-2",
"sourceType": "Resource",
"source": "projects/project-1",
"servicePerimeter": "accessPolicies/REDACTED/servicePerimeters/perimeter-1",
"targetResourcePermissions": [ "bigquery.jobs.create"]
} ],
5. BigQuery 작업을 만들기 위한 위반 수정
이 다이어그램은 주 구성원이
project-1의 데이터 세트에 대해 project-2에서 쿼리를 실행하는 경우를 보여줍니다. 쿼리가 실행되는 프로젝트 (project-2)의 데이터 세트 프로젝트 (project-1)에서 BigQuery 작업을 만드는 작업이 BigQuery API를 보호하는 서비스 경계 perimeter-1로 인해 VPC 서비스 제어 이그레스 위반으로 실패합니다. 경계가 설정된 경우 서비스 경계 구성에서 허용하지 않는 한 project-1에서 경계 외부로 또는 경계 외부에서 보호된 프로젝트로 BigQuery API 요청을 시작할 수 없습니다.
이그레스 위반은 다음을 기반으로 하는 이그레스 규칙을 만들어 해결할 수 있습니다.
- 소스 (FROM): 사용자 이메일 주소 및 컨텍스트 (예: 호출자 IP 주소, 기기 상태, 위치 등)
- 대상 (TO): 즉, 타겟 리소스, 서비스, 메서드 또는 권한입니다.
관찰된 이그레스 위반을 해결하려면 BigQuery 서비스에서 쿼리를 실행하는 사용자 계정 (user@example.com)과 bigquery.jobs.create 메서드/ 권한이 targetResource (project-2)로 향하는 트래픽을 허용하는 이그레스 규칙을 만드세요.

구성된 이그레스 규칙에서 예상되는 동작은 다음과 같습니다.
- FROM | ID: 지정된 ID(
user@example.com)만 경계 경계를 넘을 수 있어야 합니다. - TO | projects: 지정된 ID는 대상이 지정된 프로젝트
project-2인 경우에만 경계 경계를 넘을 수 있습니다. - TO | 서비스: 지정된 ID는 API 호출이 지정된 서비스 및 메서드에 대한 경우에만 경계 외부에서 지정된 프로젝트를 향해 트래픽을 시작할 수 있습니다. 그렇지 않으면 예를 들어 서비스 경계로 보호되는 다른 서비스를 시도하는 경우 다른 서비스는 허용되지 않으므로 작업이 차단됩니다.
수정사항 테스트: 이그레스 규칙
이그레스 규칙이 적용되면 동일한 쿼리를 실행합니다.
SELECT name, total
FROM `project-1.codelab_dataset.codelab-table`
ORDER BY total DESC
LIMIT 10;
이번에는 NO_MATCHING_ACCESS_LEVEL 인그레스 위반이 발생합니다. 새 위반은 타겟 프로젝트와 메서드 측면에서 첫 번째 위반과 다릅니다.

새 위반은 다음을 포함하는 인그레스 위반입니다.
principalEmail: [쿼리를 실행하는 사용자 계정]callerIp: [쿼리를 실행하는 사용자 에이전트의 IP 주소]
ingressViolations: [
0: {
servicePerimeter: "accessPolicies/REDACTED/servicePerimeters/perimeter-1"
targetResource: "projects/project-1"
targetResourcePermissions: [0: "bigquery.tables.getData"]}
]
bigquery.tables.getData 메서드의 위반은 BigQuery 테이블에서 데이터를 가져오려고 하는 BigQuery 작업에서 시작된 API 호출로 인해 발생합니다.
6. 위반사항을 수정하여 BigQuery 테이블 데이터 가져오기
인그레스 규칙은 인그레스 위반을 수정하는 동시에 서비스 경계 교차가 허용되는 사용자와 소스/ 타겟 프로젝트, 액세스할 수 있는 API 메서드와 같은 허용된 액세스의 컨텍스트를 세부적으로 제어할 수 있도록 지원합니다.
인그레스 위반은 다음과 같이 구성된 인그레스 규칙으로 수정됩니다.
- 소스 (FROM): 사용자 이메일 주소 및 컨텍스트 (예: 호출자 IP 주소, 기기 상태, 위치 등)
- 대상 (TO): 즉, 타겟 리소스, 서비스, 메서드 또는 권한입니다.
인그레스 규칙은 지정된 서비스 및 메서드에서 지정된 사용자가 project-1로 향하는 트래픽을 허용합니다.

구성된 인그레스 규칙에서 예상되는 동작은 다음과 같습니다.
- FROM | ID: 지정된 ID(
user@example.com)만 경계 경계를 넘을 수 있어야 합니다. - TO | projects: 지정된 ID는 대상이 지정된 프로젝트
project-1인 경우에만 경계 경계를 넘을 수 있습니다. - TO | 서비스: 지정된 메서드
bigquery.tables.getData가 BigQuery API에 대한 API 호출인 경우에만 지정된 ID가 경계 내에서 트래픽을 시작할 수 있습니다.
이후에는 동일한 쿼리를 실행해도 VPC 서비스 제어 위반 없이 적절하게 작동해야 합니다.
project-1에서 BigQuery API를 user@example.com에서만 사용하고 user2@example.com에서는 사용할 수 없도록 제한했습니다.
이 다이어그램은 두 개의 서로 다른 주체가 동일한 데이터 세트를 쿼리하려고 시도하는 방법을 보여줍니다.
user2@example.com (파란색 점선)의 액세스는 VPC 서비스 제어에 의해 거부됩니다. 서비스 경계 구성에 따라 project-1에서 또는 project-1을 향해 BigQuery 작업을 실행할 수 없기 때문입니다. user@example.com (녹색 실선)의 액세스는 VPC 서비스 제어 구성에 따라 project-1에서 시작하거나 project-1을 향하는 작업을 실행할 수 있으므로 성공합니다.
7. 내부 IP 주소에 따라 서비스 경계에서 허용되는 트래픽 제한
현재 구성에서는 지정된 사용자가 데이터 쿼리 IAM 권한을 부여받고 계정을 사용하는 한 인터넷상의 어느 위치에서든 project-1의 BigQuery에서 쿼리를 실행할 수 있습니다. 보안 관점에서 이는 계정이 해킹된 경우 계정에 액세스할 수 있는 모든 개인이 추가 제한 없이 BigQuery 데이터에 액세스할 수 있음을 의미합니다.
인그레스 및 이그레스 규칙에서 액세스 수준을 활용하여 사용자 컨텍스트를 지정하면 추가 제한을 구현할 수 있습니다. 예를 들어 호출자 ID별 액세스를 승인하는 이전에 구성된 수신 규칙과 함께 소스 IP 기반 액세스를 허용할 수 있습니다. 사용자 클라이언트에 공개 IP가 할당된 경우 공개 IP CIDR 범위에 대해 소스 IP별 액세스가 가능하며, 사용자 클라이언트가 Google Cloud 프로젝트에서 작동하는 경우 내부 IP 주소를 사용하여 액세스할 수 있습니다.
내부 IP 주소 액세스 조건으로 액세스 수준 만들기
범위가 지정된 액세스 정책 폴더에서 Access Context Manager 페이지를 열어 액세스 수준을 만듭니다.
- Access Context Manager 페이지에서 액세스 수준 만들기를 선택합니다.
- '새 액세스 수준' 창에서 다음을 수행합니다.
- 제목을 제공합니다.
codelab-al를 사용할 수 있습니다. - '조건' 섹션에서 IP 서브네트워크를 클릭합니다.
- 비공개 IP 탭을 선택하고 VPC 네트워크 선택을 클릭합니다.
- VPC 네트워크 추가 창에서
default네트워크를 찾아보거나//compute.googleapis.com/projects/project-2/global/networks/default형식으로 전체 네트워크 이름을 수동으로 입력할 수 있습니다. - VPC 네트워크 추가를 클릭합니다.
- IP 서브넷 선택을 클릭합니다.
- VM 인스턴스가 있는 리전을 선택합니다. 이 Codelab에서는
us-central1입니다. - 저장을 클릭합니다.
- 제목을 제공합니다.
액세스 수준을 만들었지만 아직 어떤 경계나 인그레스/이그레스 정책에도 적용되지 않습니다.

인그레스 규칙에 액세스 수준 추가
인그레스 규칙에 의해 허용된 사용자가 액세스 수준에 대해 확인되도록 하려면 인그레스 규칙에서 액세스 수준을 구성해야 합니다. 데이터 쿼리 액세스를 승인하는 인그레스 규칙은 perimeter-1에 있습니다. 인그레스 규칙을 변경하여 소스를 액세스 수준 codelab-al로 정의합니다.

새 구성 테스트
인그레스 규칙에 액세스 수준이 추가된 후에는 프로젝트 project-2의 VPC 네트워크 default에 있는 클라이언트에서 실행하지 않는 한 동일한 BigQuery 쿼리가 실패합니다. 이 동작을 확인하려면 엔드포인트 기기가 인터넷에 연결된 상태에서 Google Cloud 콘솔에서 쿼리를 실행하세요. 쿼리가 실패로 종료되며 인그레스 위반이 표시됩니다.
project-2에 있는 VPC 네트워크 default에서 동일한 쿼리를 실행할 수 있습니다. 마찬가지로 VPC 네트워크 default을 사용하여 project-2에 있는 Compute Engine 인스턴스에서 동일한 BigQuery 쿼리를 실행해도 실패합니다. 인그레스 규칙이 여전히 주 구성원 user@example.com만 허용하도록 구성되어 있기 때문입니다. 하지만 VM은 Compute Engine 기본 서비스 계정을 사용하고 있습니다.
project-2의 Compute Engine 인스턴스에서 동일한 명령어를 실행하려면 다음을 확인하세요.
- VM에 BigQuery API를 사용할 수 있는 액세스 범위가 있습니다. VM 액세스 범위로 모든 Cloud API에 대한 전체 액세스 허용을 선택하면 됩니다.
- VM에 연결된 서비스 계정에는 다음을 수행할 수 있는 IAM 권한이 필요합니다.
project-2에서 BigQuery 작업 만들기project-1에 있는 BigQuery 테이블에서 BigQuery 데이터를 가져옵니다.
- 기본 Compute Engine 서비스 계정은 인그레스 및 이그레스 규칙에 의해 허용되어야 합니다.
이제 BigQuery 테이블에서 데이터를 가져올 수 있도록 인그레스 규칙에 Compute Engine 기본 서비스 계정을 추가하고 BigQuery 작업을 만들 수 있도록 이그레스 규칙에 추가해야 합니다.

default VPC 네트워크의 project-2에 있는 Compute Engine 인스턴스에서 다음 bq query 명령어를 실행합니다.
bq query --nouse_legacy_sql \
'SELECT name, total
FROM `project-1.codelab_dataset.codelab-table`
ORDER BY total DESC
LIMIT 10;'
현재 구성에서는 다음 조건이 충족되는 경우에만 BigQuery 명령어가 성공합니다.
project-2의 기본 VPC 네트워크를 사용하여 VM에서 실행- 지정된
us-central1리전에 있으며 (IP 서브네트워크) - 서비스 경계에 구성된 기본 Compute Engine 서비스 계정을 사용하여 실행됩니다.
BigQuery 명령어 쿼리는 다음을 비롯한 다른 위치에서 실행하면 실패합니다.
project-2의 기본 VPC 네트워크를 사용하는 VM에서 실행되지만 액세스 수준에 추가된 서브넷과 다른 리전에 있는 경우- 인터넷에서 사용자 클라이언트를 사용하여
user@example.com사용자가 실행하는 경우
이 다이어그램은 인터넷과 Compute Engine 인스턴스라는 두 위치에서 동일한 주 구성원(
user@example.com)이 시작한 액세스를 보여줍니다. 인터넷에서 직접 BigQuery에 액세스 (파란색 점선)하는 것은 VPC 서비스 제어에 의해 차단되지만 Compute Engine 기본 서비스 계정을 가장하는 VM (녹색 실선)에서의 액세스는 허용됩니다. 허용된 액세스는 내부 IP 주소에서 보호된 리소스에 액세스할 수 있도록 서비스 경계가 구성되어 있기 때문입니다.
8. 삭제
서비스를 사용하지 않을 때는 VPC 서비스 제어 사용에 대한 별도의 요금이 부과되지 않지만 이 실습에서 사용한 설정을 정리하는 것이 좋습니다. VM 인스턴스, BigQuery 데이터 세트 또는 Google Cloud 프로젝트를 삭제하여 비용 청구를 방지할 수도 있습니다. Cloud 프로젝트를 삭제하면 해당 프로젝트 내에서 사용되는 모든 리소스에 대한 청구가 중단됩니다.
- VM 인스턴스를 삭제하려면 다음 단계를 완료하세요.
- Google Cloud 콘솔에서 VM 인스턴스 페이지로 이동합니다.
- VM 인스턴스 이름 왼쪽에 있는 체크박스를 선택한 다음 삭제를 선택하고 다시 삭제를 클릭하여 확인합니다.

- 서비스 경계를 삭제하려면 다음 단계를 완료하세요.
- Google Cloud 콘솔에서 액세스 정책의 범위가 지정된 수준(이 경우 폴더 수준)에서 보안을 선택한 다음 VPC 서비스 제어를 선택합니다.
- VPC 서비스 제어 페이지에서 삭제할 경계에 해당하는 표 행에서 삭제를 클릭합니다.
- 액세스 수준을 삭제하려면 다음 단계를 완료하세요.
- Google Cloud 콘솔에서 폴더 범위의 Access Context Manager 페이지를 엽니다.
- 그리드에서 삭제할 액세스 수준의 행을 찾아 점 3개로 된 메뉴를 선택한 다음 삭제를 선택합니다.
- 프로젝트를 종료하려면 다음 단계를 완료하세요.
- Google Cloud 콘솔에서 삭제하려는 프로젝트의 IAM 및 관리자 설정 페이지로 이동합니다.
- IAM 및 관리자 설정 페이지에서 종료를 선택합니다.
- 프로젝트 ID를 입력하고 무시하고 종료를 선택합니다.
9. 축하합니다.
이 Codelab에서는 VPC 서비스 제어 경계를 만들고, 적용하고, 문제를 해결했습니다.
자세히 알아보기
다음 시나리오도 살펴볼 수 있습니다.
- 프로젝트가 VPC 서비스 제어로 보호된 후 공개 데이터 세트에서 동일한 쿼리를 실행합니다.
project-1과 동일한 경계에project-2를 추가합니다.project-2을 자체 경계에 추가하고project-1을 현재 경계에 유지합니다.- 데이터를 가져오는 것뿐만 아니라 테이블의 데이터를 업데이트하는 쿼리를 실행합니다.
라이선스
이 작업물은 Creative Commons Attribution 2.0 일반 라이선스에 따라 사용이 허가되었습니다.