< Lab >
Securing a Cloud SQL for PostgreSQL Instance
PostgreSQL 인스턴스용 Cloud SQL 보안
- CMEK가 사용 설정된 PostgreSQL용 Cloud SQL 인스턴스 만들기
- Cloud SQL용 제품별, 프로젝트별 서비스 계정 만들기 :
클라우드 셸에서 Cloud SQL CMEK에 필요한 서비스 계정 생성
export PROJECT_ID=$(gcloud config list \ --format 'value(core.project)') gcloud beta services identity create \ --service=sqladmin.googleapis.com \ --project=$PROJECT_ID
- Cloud Key Management Service 키링 및 키 만들기 :
CMEK와 함께 사용할 Cloud KMS 키링 및 키 생성 후 서비스 계정에 결합
export KMS_KEYRING_ID=cloud-sql-keyring export REGION=us-central1 gcloud kms keyrings create $KMS_KEYRING_ID \ --location=$REGION export KMS_KEY_ID=cloud-sql-key gcloud kms keys create $KMS_KEY_ID \ --location=us-central1 \ --keyring=$KMS_KEYRING_ID \ --purpose=encryption export PROJECT_NUMBER=$(gcloud projects describe ${PROJECT_ID} \ --format 'value(projectNumber)') gcloud kms keys add-iam-policy-binding $KMS_KEY_ID \ --location=$REGION \ --keyring=$KMS_KEYRING_ID \ --member=serviceAccount:service-${PROJECT_NUMBER}@gcp-sa-cloud-sql.iam.gserviceaccount.com \ --role=roles/cloudkms.cryptoKeyEncrypterDecrypter
- CMEK가 사용 설정된 Cloud SQL 인스턴스 만들기 :
bastion-vm 인스턴스의 외부 IP 주소와 클라우드 셸의 외부 IP 주소를 찾은 후 PostgreSQL용 Cloud SQL 생성
export ZONE=us-central1-a export AUTHORIZED_IP=$(gcloud compute instances describe bastion-vm \ --zone=$ZONE \ --format 'value(networkInterfaces[0].accessConfigs.natIP)') echo Authorized IP: $AUTHORIZED_IP export CLOUD_SHELL_IP=$(curl ifconfig.me) echo Cloud Shell IP: $CLOUD_SHELL_IP export KEY_NAME=$(gcloud kms keys describe $KMS_KEY_ID \ --keyring=$KMS_KEYRING_ID --location=$REGION \ --format 'value(primary.name)') export CLOUDSQL_INSTANCE=postgres-orders gcloud sql instances create $CLOUDSQL_INSTANCE \ --project=$PROJECT_ID \ --authorized-networks=${AUTHORIZED_IP}/32,$CLOUD_SHELL_IP/32 \ --disk-encryption-key=$KEY_NAME \ --database-version=POSTGRES_13 \ --cpu=1 \ --memory=3840MB \ --region=$REGION \ --root-password=supersecret!
- PostgreSQL용 Cloud SQL 데이터베이스에서 pgAudit 사용 설정 및 구성
- 클라우드 셸에서 Cloud SQL 인스턴스에 pgAufit 데이터베이스 플래그를 추가한 후 콘솔창의 SQL에서 다시 시작 클릭
gcloud sql instances patch $CLOUDSQL_INSTANCE \ --database-flags cloudsql.enable_pgaudit=on,pgaudit.log=all
- SQL의 인스턴스의 Overview에서 클라우드 셸 열기를 클릭한 후 psql에서 orders 데이터베이스를 생성하고
pgAudit 확장을 활성화해 모든 읽기 및 쓰기를 기록
CREATE DATABASE orders; \c orders; supersecret! CREATE EXTENSION pgaudit; ALTER DATABASE orders SET pgaudit.log = 'read,write';
- Cloud Console에서 감사 로깅 사용 설정 :
콘솔의 IAM 및 관리자 - 감사 로그를 클릭한 후 필터 상자의 드롭다운 목록에서 Cloud SQL을 선택하고 정보 패널을 선택 후 저장
- PostgreSQL용 Cloud SQL에서 데이터베이스 채우기 :
클라우드 셸에서 새 탭을 열고 데이터 및 데이터베이스 채우기 스크립트를 다운로드해서 데이터베이스를 만들고 채움
새 탭에서의 터미널 세션을 종료export SOURCE_BUCKET=gs://cloud-training/gsp920 gsutil -m cp ${SOURCE_BUCKET}/create_orders_db.sql . gsutil -m cp ${SOURCE_BUCKET}/DDL/distribution_centers_data.csv . gsutil -m cp ${SOURCE_BUCKET}/DDL/inventory_items_data.csv . gsutil -m cp ${SOURCE_BUCKET}/DDL/order_items_data.csv . gsutil -m cp ${SOURCE_BUCKET}/DDL/products_data.csv . gsutil -m cp ${SOURCE_BUCKET}/DDL/users_data.csv . export CLOUDSQL_INSTANCE=postgres-orders export POSTGRESQL_IP=$(gcloud sql instances describe $CLOUDSQL_INSTANCE --format="value(ipAddresses[0].ipAddress)") export PGPASSWORD=supersecret! psql "sslmode=disable user=postgres hostaddr=${POSTGRESQL_IP}" \ -c "\i create_orders_db.sql"
나머지 클라우드 셸 탭의 psql 세션에서 특정 관계에 대한 모든 작업을 추가로 기록exit
그 후 사용자 주문 요약, 개별 제품별 요약, 물류센터별 주문에 따른 쿼리를 실행CREATE ROLE auditor WITH NOLOGIN; ALTER DATABASE orders SET pgaudit.role = 'auditor'; GRANT SELECT ON order_items TO auditor;
출력이 500행이므로 프롬프트로 돌아가려면 q와 콜론 프롬프트를 클릭
SELECT users.id AS users_id, users.first_name AS users_first_name, users.last_name AS users_last_name, COUNT(DISTINCT order_items.order_id ) AS order_items_order_count, COALESCE(SUM(order_items.sale_price ), 0) AS order_items_total_revenue FROM order_items LEFT JOIN users ON order_items.user_id = users.id GROUP BY 1, 2, 3 ORDER BY 4 DESC LIMIT 500; SELECT products.id AS products_id, products.name AS products_name, products.sku AS products_sku, products.cost AS products_cost, products.retail_price AS products_retail_price, products.distribution_center_id AS products_distribution_center_id, COUNT(DISTINCT order_items.order_id ) AS order_items_order_count, COALESCE(SUM(order_items.sale_price ), 0) AS order_items_total_revenue FROM order_items LEFT JOIN inventory_items ON order_items.inventory_item_id = inventory_items.id LEFT JOIN products ON inventory_items.product_id = products.id GROUP BY 1, 2, 3, 4, 5, 6 ORDER BY 7 DESC LIMIT 500; SELECT order_items.order_id AS order_id, distribution_centers.id AS distribution_centers_id, distribution_centers.name AS distribution_centers_name, distribution_centers.latitude AS distribution_centers_latitude, distribution_centers.longitude AS distribution_centers_longitude FROM order_items LEFT JOIN inventory_items ON order_items.inventory_item_id = inventory_items.id LEFT JOIN products ON inventory_items.product_id = products.id LEFT JOIN distribution_centers ON products.distribution_center_id = distribution_centers.id GROUP BY 1, 2, 3, 4, 5 ORDER BY 2 LIMIT 500;
psql 종료
\q
- pgAudit 로그 보기 :
콘솔 창에서 Operations - 로깅 - 로그 탐색기를 클릭 후 쿼리 탭에 쿼리를 실행 후
표시된 히스토그램을 통해 DDL 삽입 및 SELECT 쿼리와 관련된 감사 활동을 볼 수 있음
- Cloud SQL IAM 데이터베이스 인증 구성
- Cloud SQL IAM 인증을 구성하기 전에 Cloud IAM 사용자를 사용하여 데이터베이스 액세스를 테스트 :
Cloud SQL IAM 사용자가 아직 생성되지 않았기 때문에 에러 메시지 표시
export USERNAME=$(gcloud config list --format="value(core.account)") export CLOUDSQL_INSTANCE=postgres-orders export POSTGRESQL_IP=$(gcloud sql instances describe $CLOUDSQL_INSTANCE --format="value(ipAddresses[0].ipAddress)") export PGPASSWORD=$(gcloud auth print-access-token) psql --host=$POSTGRESQL_IP $USERNAME --dbname=orders
- Cloud SQL IAM 사용자 만들기 :
SQL - postgres-orders 인스턴스를 클릭 후 Overview의 Configuration에서 데이터베이스 플래그 목록 확인
Users를 클릭한 후 사용자 계정 추가
- Cloud IAM 사용자에게 Cloud SQL 데이터베이스 테이블에 대한 액세스 권한 부여 :
클라우드 셸에서 postgres-orders 인스턴스에 연결한 후 orders 데이터베이스로 전환하고
사용자에게 order_items 테이블에 대한 모든 권한을 부여
gcloud sql connect postgres-orders --user=postgres --quiet supersecret! \c orders supersecret! GRANT ALL PRIVILEGES ON TABLE order_items TO "student-04-c3ea8f6fdb56@qwiklabs.net"; \q
- Cloud SQL IAM 인증이 구성된 후 Cloud IAM 사용자를 사용하여 데이터베이스 액세스를 테스트 :
클라우드 셸에서 Cloud IAM 데이터베이스 사용자를 사용하여 order_items 데이터베이스에 연결 후 액세스 권한을 테스트
그 후 다른 테이블에 대해서는 액세스 권한이 없는지 확인
export PGPASSWORD=$(gcloud auth print-access-token) psql --host=$POSTGRESQL_IP $USERNAME --dbname=orders SELECT COUNT(*) FROM order_items; SELECT COUNT(*) FROM users;