Skip to content

Instantly share code, notes, and snippets.

@yihyang
Last active September 6, 2022 16:42
Show Gist options
  • Save yihyang/15399009407e265c557b804d652a88b6 to your computer and use it in GitHub Desktop.
Save yihyang/15399009407e265c557b804d652a88b6 to your computer and use it in GitHub Desktop.
IAM Custom Roles
# Understanding IAM Custom Roles
<service>.<resource>.<verb>
# Viewing the available permissions for a resource
## List current permission
gcloud iam list-testable-permissions //cloudresourcemanager.googleapis.com/projects/$DEVSHELL_PROJECT_ID
# Getting the role metadata
gcloud iam roles describe [ROLE_NAME]
# Viewing the grantable roles on resources
gcloud iam list-grantable-roles //cloudresourcemanager.googleapis.com/projects/$DEVSHELL_PROJECT_ID
# Creating a custom role
gcloud iam roles create
# To create a custom role using a YAML file
title: [ROLE_TITLE]
description: [ROLE_DESCRIPTION]
stage: [LAUNCH_STAGE]
includedPermissions:
- [PERMISSION_1]
- [PERMISSION_2]
title: "Role Editor"
description: "Edit access for App Versions"
stage: "ALPHA"
includedPermissions:
- appengine.versions.create
- appengine.versions.delete
gcloud iam roles create editor --project $DEVSHELL_PROJECT_ID \
--file role-definition.yaml
# Create a custom role using flags
gcloud iam roles create viewer --project $DEVSHELL_PROJECT_ID \
--title "Role Viewer" --description "Custom role description." \
--permissions compute.instances.get,compute.instances.list --stage ALPHA
# Listing the custom roles
gcloud iam roles list --project $DEVSHELL_PROJECT_ID
gcloud iam roles list
# Editing an existing custom role
gcloud iam roles update
# To update a custom role using a YAML file
gcloud iam roles describe [ROLE_ID] --project $DEVSHELL_PROJECT_ID
nano new-role-definition.yaml
description: Edit access for App Versions
etag: BwVxIAbRq_I=
includedPermissions:
- appengine.versions.create
- appengine.versions.delete
- storage.buckets.get
- storage.buckets.list
name: projects/[PROJECT_ID]/roles/editor
stage: ALPHA
title: Role Editor
# To update a custom role using flags
gcloud iam roles update viewer --project $DEVSHELL_PROJECT_ID \
--add-permissions storage.buckets.get,storage.buckets.list
gcloud iam roles update [ROLE_ID] --project $DEVSHELL_PROJECT_ID \
--file new-role-definition.yaml
# Disabling a custom role
gcloud iam roles update viewer --project $DEVSHELL_PROJECT_ID \
--stage DISABLED
# Deleting a custom role
gcloud iam roles delete viewer --project $DEVSHELL_PROJECT_ID
# Undeleting a custom role
gcloud iam roles undelete viewer --project $DEVSHELL_PROJECT_ID
Securing Google Cloud with CFT Scorecard
# Setup environment
export GOOGLE_PROJECT=$DEVSHELL_PROJECT_ID
export CAI_BUCKET_NAME=cai-$GOOGLE_PROJECT
gcloud services enable cloudasset.googleapis.com \
--project $GOOGLE_PROJECT
git clone https://github.com/forseti-security/policy-library.git
cp policy-library/samples/storage_blacklist_public.yaml policy-library/policies/constraints/
gsutil mb -l us-central1 -p $GOOGLE_PROJECT gs://$CAI_BUCKET_NAME
# Collect the data using Cloud Asset Inventory (CAI)
# Export resource data
gcloud asset export \
--output-path=gs://$CAI_BUCKET_NAME/resource_inventory.json \
--content-type=resource \
--project=$GOOGLE_PROJECT
# Export IAM data
gcloud asset export \
--output-path=gs://$CAI_BUCKET_NAME/iam_inventory.json \
--content-type=iam-policy \
--project=$GOOGLE_PROJECT
# Analyze the CAI data with CFT Scorecard
curl -o cft https://storage.googleapis.com/cft-cli/latest/cft-linux-amd64
# make executable
chmod +x cft
./cft scorecard --policy-path=policy-library/ --bucket=$CAI_BUCKET_NAME
## Add a new policy to blacklist the IAM Owner Role
cat > policy-library/policies/constraints/iam_whitelist_owner.yaml << EOF
apiVersion: constraints.gatekeeper.sh/v1alpha1
kind: GCPIAMAllowedBindingsConstraintV1
metadata:
name: whitelist_owner
annotations:
description: List any users granted Owner
spec:
severity: high
match:
target: ["organization/*"]
exclude: []
parameters:
mode: whitelist
assetType: cloudresourcemanager.googleapis.com/Project
role: roles/owner
members:
- "serviceAccount:admiral@qwiklabs-services-prod.iam.gserviceaccount.com"
EOF
./cft scorecard --policy-path=policy-library/ --bucket=$CAI_BUCKET_NAME
export USER_ACCOUNT="$(gcloud config get-value core/account)"
export PROJECT_NUMBER=$(gcloud projects describe $GOOGLE_PROJECT --format="get(projectNumber)")
# Add a new policy to whitelist the IAM Editor Role
cat > policy-library/policies/constraints/iam_identify_outside_editors.yaml << EOF
apiVersion: constraints.gatekeeper.sh/v1alpha1
kind: GCPIAMAllowedBindingsConstraintV1
metadata:
name: identify_outside_editors
annotations:
description: list any users outside the organization granted Editor
spec:
severity: high
match:
target: ["organization/*"]
exclude: []
parameters:
mode: whitelist
assetType: cloudresourcemanager.googleapis.com/Project
role: roles/editor
members:
- "user:$USER_ACCOUNT"
- "serviceAccount:*$PROJECT_NUMBER*gserviceaccount.com"
- "serviceAccount:$GOOGLE_PROJECT*gserviceaccount.com"
EOF
# VPC Network Peering
# at project a
gcloud compute networks create network-a --subnet-mode custom
gcloud compute networks subnets create network-a-central --network network-a \
--range 10.0.0.0/16 --region us-central1
gcloud compute instances create vm-a --zone us-central1-a --network network-a --subnet network-a-central
gcloud compute firewall-rules create network-a-fw --network network-b --allow tcp:22,icmp
# at project b
gcloud compute networks create network-b --subnet-mode custom
gcloud compute networks subnets create network-b-central --network network-b \
--range 10.8.0.0/16 --region us-central1
gcloud compute instances create vm-b --zone us-central1-a --network network-b --subnet network-b-central
gcloud compute firewall-rules create network-b-fw --network network-b --allow tcp:22,icmp
User Authentication: Identity-Aware Proxy
# Download the Code
git clone https://github.com/googlecodelabs/user-authentication-with-iap.git
cd user-authentication-with-iap
# Deploy Application and Protect it with IAP
cd 1-HelloWorld
gcloud app deploy
gcloud app browse
# Access User Identity Information
cd ~/user-authentication-with-iap/2-HelloUser
gcloud app deploy
# Examine the Application Files
user_email = request.headers.get('X-Goog-Authenticated-User-Email')
user_id = request.headers.get('X-Goog-Authenticated-User-ID')
page = render_template('index.html', email=user_email, id=user_id)
Hello, {{ email }}! Your persistent ID is {{ id }}.
# Test the updated IAP
gcloud app browse
curl -X GET <your-url-here> -H "X-Goog-Authenticated-User-Email: totally fake email"
# Use Cryptographic Verification
cd ~/user-authentication-with-iap/3-HelloVerifiedUser
gcloud app deploy
# Examine the Application Files
def user():
assertion = request.headers.get('X-Goog-IAP-JWT-Assertion')
if assertion is None:
return None, None
info = jwt.decode(
assertion,
keys(),
algorithms=['ES256'],
audience=audience()
)
return info['email'], info['sub']
Getting Started with Cloud KMS
# Create a Cloud Storage bucket
BUCKET_NAME=<YOUR_NAME>_enron_corpus
gsutil mb gs://${BUCKET_NAME}
# Check out the data
gsutil cp gs://enron_emails/allen-p/inbox/1. .
tail 1.
# Enable Cloud KMS
gcloud services enable cloudkms.googleapis.com
# Create a Keyring and Cryptokey
KEYRING_NAME=test CRYPTOKEY_NAME=qwiklab
gcloud kms keyrings create $KEYRING_NAME --location global
gcloud kms keys create $CRYPTOKEY_NAME --location global \
--keyring $KEYRING_NAME \
--purpose encryption
# Encrypt Your Data
PLAINTEXT=$(cat 1. | base64 -w0)
curl -v "https://cloudkms.googleapis.com/v1/projects/$DEVSHELL_PROJECT_ID/locations/global/keyRings/$KEYRING_NAME/cryptoKeys/$CRYPTOKEY_NAME:encrypt" \
-d "{\"plaintext\":\"$PLAINTEXT\"}" \
-H "Authorization:Bearer $(gcloud auth application-default print-access-token)"\
-H "Content-Type: application/json"
curl -v "https://cloudkms.googleapis.com/v1/projects/$DEVSHELL_PROJECT_ID/locations/global/keyRings/$KEYRING_NAME/cryptoKeys/$CRYPTOKEY_NAME:encrypt" \
-d "{\"plaintext\":\"$PLAINTEXT\"}" \
-H "Authorization:Bearer $(gcloud auth application-default print-access-token)"\
-H "Content-Type:application/json" \
| jq .ciphertext -r > 1.encrypted
curl -v "https://cloudkms.googleapis.com/v1/projects/$DEVSHELL_PROJECT_ID/locations/global/keyRings/$KEYRING_NAME/cryptoKeys/$CRYPTOKEY_NAME:decrypt" \
-d "{\"ciphertext\":\"$(cat 1.encrypted)\"}" \
-H "Authorization:Bearer $(gcloud auth application-default print-access-token)"\
-H "Content-Type:application/json" \
| jq .plaintext -r | base64 -d
# gsutil cp 1.encrypted gs://${BUCKET_NAME}
# Configure IAM Permissions
USER_EMAIL=$(gcloud auth list --limit=1 2>/dev/null | grep '@' | awk '{print $2}')
gcloud kms keyrings add-iam-policy-binding $KEYRING_NAME \
--location global \
--member user:$USER_EMAIL \
--role roles/cloudkms.admin
# Back up data on the Command Line
gsutil -m cp -r gs://enron_emails/allen-p .
MYDIR=allen-p
FILES=$(find $MYDIR -type f -not -name "*.encrypted")
for file in $FILES; do
PLAINTEXT=$(cat $file | base64 -w0)
curl -v "https://cloudkms.googleapis.com/v1/projects/$DEVSHELL_PROJECT_ID/locations/global/keyRings/$KEYRING_NAME/cryptoKeys/$CRYPTOKEY_NAME:encrypt" \
-d "{\"plaintext\":\"$PLAINTEXT\"}" \
-H "Authorization:Bearer $(gcloud auth application-default print-access-token)" \
-H "Content-Type:application/json" \
| jq .ciphertext -r > $file.encrypted
done
gsutil -m cp allen-p/inbox/*.encrypted gs://${BUCKET_NAME}/allen-p/inbox
# Setting up a Private Kubernetes Cluster
# Set a zone
gcloud config set compute/zone us-central1-a
# Creating a private cluster
gcloud beta container clusters create private-cluster \
--enable-private-nodes \
--master-ipv4-cidr 172.16.0.16/28 \
--enable-ip-alias \
--create-subnetwork ""
# Viewing your subnet and secondary address ranges
gcloud compute networks subnets list --network default
# Enabling master authorized networks
gcloud compute instances create source-instance --zone us-central1-a --scopes 'https://www.googleapis.com/auth/cloud-platform'
gcloud compute instances describe source-instance --zone us-central1-a | grep natIP
gcloud container clusters update private-cluster \
--enable-master-authorized-networks \
--master-authorized-networks [MY_EXTERNAL_RANGE]
gcloud compute ssh source-instance --zone us-central1-a
gcloud components install kubectl
sudo apt-get install kubectl
gcloud container clusters get-credentials private-cluster --zone us-central1-a
kubectl get nodes --output wide
exit
# Clean Up
gcloud container clusters delete private-cluster --zone us-central1-a
# Creating a private cluster that uses a custom subnetwork
gcloud compute networks subnets create my-subnet \
--network default \
--range 10.0.4.0/22 \
--enable-private-ip-google-access \
--region us-central1 \
--secondary-range my-svc-range=10.0.32.0/20,my-pod-range=10.4.0.0/14
gcloud beta container clusters create private-cluster2 \
--enable-private-nodes \
--enable-ip-alias \
--master-ipv4-cidr 172.16.0.32/28 \
--subnetwork my-subnet \
--services-secondary-range-name my-svc-range \
--cluster-secondary-range-name my-pod-range
gcloud container clusters update private-cluster2 \
--enable-master-authorized-networks \
--master-authorized-networks [MY_EXTERNAL_RANGE]
gcloud compute ssh source-instance --zone us-central1-a
gcloud container clusters get-credentials private-cluster2 --zone us-central1-a
kubectl get nodes --output yaml | grep -A4 addresses
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment