GCP Security Lab: Shielding Your Web Apps with Cloud Armor WAF

Table of contents
- Disclaimers & Personal Context
- Introduction
- Phase 0: Prerequisites & Environment Setup
- Phase 1: Deploying the Simple Web Application
- Phase 2: Setting Up the Global HTTP(S) Load Balancer
- Phase 3: Implementing Cloud Armor Basic Protection
- Phase 4: Simulating Attacks & Verifying Cloud Armor Blocks
- Phase 5: Monitoring & Analyzing Cloud Armor Logs
- Phase 6: Cleaning Up Your Lab Environment
- Conclusion & Next Steps

Disclaimers & Personal Context
My Views: This project and the views expressed in this blog post are my own and do not necessarily reflect the official stance or opinions of Google Cloud or any other entity.
Learning Journey: This lab is another opportunity for me to expand my self-learning journey across various cloud providers. I want to recognize that Google Cloud Platform has phenomenal, expertly built courses. If you're looking for structured, official training, check out Cloud Skills Boost – it's a fantastic resource!
Lab Environment: This lab is for educational purposes only. All activities are simulated within my dedicated lab project.
Cost & Cleanup: I'm using a fresh GCP account, similar to what a new user might experience. New GCP sign-ups typically come with a generous
$300 in free credits
, which should be more than enough to complete this lab without incurring significant costs. I'll provide a comprehensive cleanup section at the very end of this guide to help you remove all created resources and avoid any unexpected billing.Crucial Tip: Always perform cloud labs in a dedicated, isolated project to avoid impacting production environments or existing resources. Ask me how I know – I may or may not have broken things by testing in production before... and learned the hard way!
Introduction
Welcome back, Amigos! In the digital world, web applications are often the primary gateway for users to interact with services. Unfortunately, this also makes them prime targets for a wide array of cyberattacks, from Distributed Denial of Service (DDoS) attempts to sophisticated Web Application Attacks (like SQL injection or Cross-Site Scripting).
This is where a Web Application Firewall (WAF) comes in. A WAF acts as a shield, inspecting incoming traffic to your web application and blocking malicious requests before they even reach your servers. In GCP, Cloud Armor provides WAF capabilities, offering robust protection at the network edge.
This post is part of an ongoing GCP Cybersecurity Lab Series, where I explore various security tools and practices in Google Cloud through hands-on labs. In this lab, I'm here to explore Cloud Armor with a practical walkthrough. By the end, our goal is to set up a simple web application, protect it using Cloud Armor policies, and then verify that Cloud Armor successfully blocks simulated malicious traffic.
Be Prepared: This is a Comprehensive Lab! This guide covers a lot of ground and involves many steps. Depending on your experience and how many breaks you take, this lab could easily take 2-4 hours (or more) to complete from start to finish. Feel free to complete it in multiple sittings!
This lab is designed to be flexible: you can choose your preferred way to follow along:
Command Line Interface (CLI) Enthusiasts: Copy-paste the provided
gcloud CLI
commands directly into Cloud Shell or your local terminal. This is often faster and more repeatable.Console Explorers: For many steps, I'll also provide instructions on how to achieve the same results by clicking your way through the intuitive Google Cloud Console. This is great for visual learners and understanding where things live.
- Note for Console users: When following Console instructions, you won't be running the
gcloud CLI
commands. This means you'll need to manually retrieve details like internal VM IP addresses or Load Balancer IPs from the GCP Console UI when prompted.
- Note for Console users: When following Console instructions, you won't be running the
I recommend using Google Cloud Shell for this lab. It comes with the gcloud
CLI pre-installed and authenticated, saving you setup time. To access Cloud Shell, simply click the rectangle icon with >_
(typically located at the top-right of the GCP Console window).
Let's get started!
Phase 0: Prerequisites & Environment Setup
This initial phase ensures my GCP project is properly configured and ready to host my Cloud Armor lab.
1. Create or Select My Dedicated GCP Project
Why a dedicated project? Isolation is key for security labs. A dedicated project makes it easy to track resources, manage permissions, and clean up completely afterward.
Option A: Create a New Project (Cloud Console - Recommended):
Open the GCP Console.
At the top of the page, click on the project selector dropdown.
In the "Select a project" dialog, click NEW PROJECT or if you just set this account up you can use the default project.
Enter a descriptive Project name (e.g., gcp-cloudarmor-lab-jt).
Click CREATE.
Once the project is created, ensure it's selected in the project selector dropdown.
Option B: Select an Existing Project (gcloud CLI):
If you already created the project via the console, you can select it:
# My project ID for this lab will be GCP-CloudArmor-Lab-JT gcloud config set project gcp-cloudarmor-lab-jt
2. Set Project ID Environment Variable
Why an environment variable? Using an environment variable for my project ID makes
gcloud
commands cleaner, less prone to typos, and easily adaptable.Important Security Note: While I'm showing my project ID here for demonstration purposes, in real-world scenarios, it's generally good practice to keep your project IDs private.
How to set the variable (Cloud Shell or local terminal):
- Crucial: When you see
YOUR_PROJECT_ID
ingcloud
commands or Console instructions throughout this lab, replace it with your actual project ID. My example project ID for this lab isgcp-cloudarmor-lab-jt
.
- Crucial: When you see
# Set my project ID for the lab
export GCP_PROJECT_ID="gcp-cloudarmor-lab-jt"
echo "GCP_PROJECT_ID is set to: $GCP_PROJECT_ID"
3. Enable Required GCP APIs
Why enable APIs? Many GCP services require their specific APIs to be explicitly enabled in your project before you can interact with them. Enabling them now prevents errors later on.
How to enable (gcloud CLI - Recommended):
gcloud services enable \ compute.googleapis.com \ container.googleapis.com \ networksecurity.googleapis.com \ --project=$GCP_PROJECT_ID
- (This command may take a minute or two to complete as services are activated.)
How to enable (Cloud Console - Alternative):
In the GCP Console, navigate to APIs & Services > Enabled APIs & Services.
Click + ENABLE APIS AND SERVICES.
Search for and enable the following APIs one by one:
Compute Engine API
Cloud Load Balancing API
(often part of Compute Engine, but good to check)Cloud Armor API
(search for "Cloud Armor" or "Network Security API")
Important Note for Cloud Shell Users: Redeclaring Variables
If you're using Cloud Shell and decide to take a break, close your browser tab, or open a new Cloud Shell session, your shell's environment variables (like $GCP_PROJECT_ID
, $REGION
, $ZONE
, etc.) will not persist automatically.
To avoid "command not found" or "Project ID must be specified" errors, it's a good practice to re-export these variables at the beginning of each phase when you return to the lab.
Here are the essential variables you'll use throughout the lab. Copy and paste this block if you ever restart your Cloud Shell:
# Essential Variables to redeclare if your Cloud Shell session restarts
export GCP_PROJECT_ID="gcp-cloudarmor-lab-jt" # Your Project ID
export REGION="us-central1"
export ZONE="${REGION}-a"
# IPs and Names (will be updated as they are created)
# If you restart your session AFTER a resource is created, you'll need to manually set these from the console/gcloud list commands.
export WEB_SERVER_VM_NAME="web-server-vm"
export LB_IP_NAME="web-app-lb-ip"
export CA_POLICY_NAME="web-app-policy"
(When you see variable declarations like this at the start of a new phase, remember to run them if your session is fresh. Sometimes I keep italicized notes in the bottom as well for more information)
Phase 1: Deploying the Simple Web Application
Goal: My goal in this phase is to set up a basic web server on a Compute Engine VM. This VM will host a simple web page that I can then put behind a Load Balancer and protect with Cloud Armor. I'll configure it without an external IP address for security, as all external traffic will flow through the Load Balancer later.
1. Set Essential Variables (If Your Cloud Shell Session is New)
Why: If you're picking up this lab after a break or in a new Cloud Shell session, these variables might be unset. Re-exporting them ensures all subsequent commands work correctly.
How to set: Copy and paste this block into your Cloud Shell:
# Essential Variables to redeclare if your Cloud Shell session restarts export GCP_PROJECT_ID="gcp-cloudarmor-lab-jt" # Your Project ID export REGION="us-central1" export ZONE="${REGION}-a" # Names for resources export WEB_SERVER_VM_NAME="web-server-vm"
2. Deploy My Web Server VM (web-server-vm
)
Why: This will be the backend server that hosts my web application content. I'm keeping it simple with a basic Debian VM and no external IP, as it will sit behind a Load Balancer.
How to deploy (
gcloud CLI
- Recommended):echo "Deploying web server VM: $WEB_SERVER_VM_NAME in zone: $ZONE" gcloud compute instances create $WEB_SERVER_VM_NAME \ --project=$GCP_PROJECT_ID \ --zone=$ZONE \ --machine-type=e2-micro \ --network-interface=network=default,no-address \ --tags=http-server,ssh \ --create-disk=auto-delete=yes,boot=yes,device-name=$WEB_SERVER_VM_NAME,image=projects/debian-cloud/global/images/family/debian-12,mode=rw,size=10,type=pd-standard \ --metadata=startup-script="#! /bin/bash\n# Initial setup will be done manually via SSH" \ --labels=app=web-server,lab=cloud-armor
This command will take a couple of minutes to complete.
How to deploy (Cloud Console - Alternative):
Navigate to Compute Engine > VM instances in the GCP Console.
Click + CREATE INSTANCE.
Name:
web-server-vm
Region:
us-central1
Zone:
us-central1-a
Machine configuration: Series
E2
, Typee2-micro
.Boot disk: Click CHANGE. Select
Debian GNU/Linux
,Debian 12 (bookworm)
(or latest stable Debian). Size10 GB
,Standard persistent disk
. Click SELECT.Firewall: Ensure
Allow HTTP traffic
andAllow HTTPS traffic
are UNCHECKED.Advanced options > Networking, Disks, Security, Management...
Go to the Networking tab.
Under Network interfaces, click the pencil icon next to
default
(or your VPC network name).External IP: Select
None
.Network tags: Type
http-server
and press Enter. Then typessh
and press Enter.Click Done.
Click CREATE.
3. Configure Basic Firewall Rules for VM Management
Why: Even without an external IP, I need to be able to SSH into my VM for installation and configuration. This rule allows SSH access via Google's Identity-Aware Proxy (IAP), which is secure. I'll also add a firewall rule to allow the Load Balancer's health checks later.
How to configure (
gcloud CLI
- Recommended):# Allow SSH access via IAP gcloud compute firewall-rules create allow-ssh-iap-web-vm \ --project=$GCP_PROJECT_ID \ --network=default \ --action=ALLOW \ --direction=INGRESS \ --rules=tcp:22 \ --source-ranges=35.235.240.0/20 \ --target-tags=ssh \ --description="Allow SSH from IAP to web server VM" # Allow incoming traffic from Load Balancer health checks and proxies # These are specific Google-managed IP ranges gcloud compute firewall-rules create allow-lb-health-check \ --project=$GCP_PROJECT_ID \ --network=default \ --action=ALLOW \ --direction=INGRESS \ --rules=tcp:80 \ --source-ranges=130.211.0.0/22,35.191.0.0/16 \ --target-tags=http-server \ --description="Allow LB health checks and proxy traffic to web server"
How to configure (Cloud Console - Alternative):
Navigate to VPC Network > Firewall rules in the GCP Console.
Click + CREATE FIREWALL RULE.
For
allow-ssh-iap-web-vm
:Name:
allow-ssh-iap-web-vm
Direction: Ingress, Action: Allow
Targets: Specified target tags, enter
ssh
Source filter: IPv4 ranges, enter
35.235.240.0/20
Protocols and ports: Specified, TCP
22
. Click CREATE.
For
allow-lb-health-check
:Name:
allow-lb-health-check
Direction: Ingress, Action: Allow
Targets: Specified target tags, enter
http-server
Source filter: IPv4 ranges, enter
130.211.0.0/22,35.191.0.0/16
Protocols and ports: Specified, TCP
80
. Click CREATE.
4. Enable Outbound Internet Access for VM (Cloud NAT)
Why enable Cloud NAT? As discussed, my
web-server-vm
has no external IP. To allowsudo apt update
andsudo apt install apache2
to work, the VM needs outbound internet access to reach package repositories. Cloud NAT provides this securely, without exposing the VM to unsolicited inbound internet traffic.How to enable (
gcloud CLI
- Recommended):Create a Cloud Router: This is a prerequisite for a NAT gateway.
export ROUTER_NAME="nat-router-${REGION}" export NAT_NAME="nat-gateway-${REGION}" export NETWORK_NAME="default" # Assuming your VM is in the 'default' VPC gcloud compute routers create ${ROUTER_NAME} \ --project=$GCP_PROJECT_ID \ --region=${REGION} \ --network=${NETWORK_NAME} \ --description="Cloud Router for NAT in ${REGION}"
Create the NAT Gateway: This connects to the router and provides the NAT functionality for the subnet where your VM lives.
gcloud compute routers nats create ${NAT_NAME} \ --project=$GCP_PROJECT_ID \ --router=${ROUTER_NAME} \ --region=${REGION} \ --nat-all-subnet-ip-ranges \ --auto-allocate-nat-external-ips \ --enable-dynamic-port-allocation \ --enable-logging \ --log-filter=ERRORS_ONLY
This step may take a few minutes to complete as the NAT gateway provisions.
How to enable (Cloud Console - Alternative):
Navigate to Network Services > Cloud NAT in the GCP Console.
Click CREATE NAT GATEWAY.
Gateway name:
nat-gateway-us-central1
VPC network:
default
Region:
us-central1
Cloud Router: Select Create new router.
Name:
nat-router-us-central1
Click CREATE.
NAT mapping: Select Automatic (recommended).
Region subnets: Ensure your
us-central1
subnet is selected.NAT IP addresses: Select Automatic IP address allocation.
Click CREATE.
5. Install Web Server (Apache2) & Serve Simple Content
Why: I need a running web server on my VM to test the Load Balancer and Cloud Armor. Apache2 is a common choice. I'll also create a simple
index.html
file that Apache will serve.How to install (Inside VM SSH session - Recommended):
First, ensure your VM is running and confirm its internal IP (
gcloud compute instances list
).Then, SSH into
web-server-vm
from your Cloud Shell:gcloud compute ssh $WEB_SERVER_VM_NAME --zone=$ZONE --project=$GCP_PROJECT_ID
Once inside the
web-server-vm
SSH session, run the following commands:# Update package lists (this should now work due to Cloud NAT!) sudo apt update -y # Install Apache2 sudo apt install apache2 -y # Verify Apache is running sudo systemctl status apache2
If Apache is active and running, press
q
to exit the status view.
5.1. Create
index.html
ManuallyWhy: We need a simple web page for Apache to serve. Manually creating this file using a text editor inside the VM is the most reliable way to ensure its content and formatting are perfect.
How to create (Still inside
web-server-vm
SSH session):Open the
index.html
file for editing usingsudo nano
:sudo nano /var/www/html/index.html
(If
nano
isn't installed, you might need to install it first:sudo apt update && sudo apt install nano -y
, but it worked on my machine) ← it works on my machine is one of my favorite subtle jokes… 😂You might see some default Apache HTML content. Delete all existing content in the
nano
editor.Carefully copy and paste the entire HTML content below into the
nano
editor. Make sure you get all lines and no extra spaces:<!DOCTYPE html> <html> <head><title>Cloud Armor Lab</title></head> <body> <h1>Hello from Cloud Armor Lab!</h1> <p>This is my simple web page.</p> </body> </html>
Save and Exit:
Press
Ctrl+O
(Control + O) to "Write Out" (save).Press
Enter
to confirm the filename (/var/www/html/index.html
).Press
Ctrl+X
(Control + X) to exitnano
.
5.2. Verify Web Server Content Locally
Why: Confirm that Apache is now serving the content I just put into
index.html
.How to verify (Still inside
web-server-vm
SSH session):curl localhost
Expected Result: The
curl
localhost
command output should display the full HTML content of your web page:<!DOCTYPE html><html><head><title>Cloud Armor Lab</title></head><body><h1>Hello from Cloud Armor Lab!</h1><p>This is my simple web page.</p></body></html>
.After verifying, type
exit
to close the SSH session and return to Cloud Shell:exit
Phase 2: Setting Up the Global HTTP(S) Load Balancer
Goal: In this phase, I'll set up a Global External HTTP(S) Load Balancer. This Load Balancer will act as the public-facing entry point for my web application, distributing incoming traffic to my web-server-vm
. It's a critical component for enabling Cloud Armor protection, as Cloud Armor policies attach to Load Balancer backend services.
- Load Balancer Type: I'll be setting up a Global External HTTP(S) Load Balancer. This type of Load Balancer is Google's highly scalable, globally distributed proxy that can handle HTTP and HTTPS traffic and route it to backends in different regions.
1. Set Essential Variables (If Your Cloud Shell Session is New)
Why: If you're picking up this lab after a break or in a new Cloud Shell session, these variables might be unset. Re-exporting them ensures all subsequent commands work correctly.
How to set: Copy and paste this block into your Cloud Shell:
# Essential Variables to redeclare if your Cloud Shell session restarts export GCP_PROJECT_ID="gcp-cloudarmor-lab-jt" # Your Project ID export REGION="us-central1" export ZONE="${REGION}-a" # Names for resources (from previous phases) export WEB_SERVER_VM_NAME="web-server-vm" export LB_IP_NAME="web-app-lb-ip" export CA_POLICY_NAME="web-app-policy" # Will use this later
2. Create an Unmanaged Instance Group
Why: Load Balancers don't directly target individual VMs. They send traffic to instance groups. An unmanaged instance group allows me to explicitly add my
web-server-vm
to it.How to create (
gcloud CLI
- Recommended):echo "Creating unmanaged instance group..." gcloud compute instance-groups unmanaged create web-app-instance-group \ --zone=$ZONE \ --project=$GCP_PROJECT_ID echo "Adding web-server-vm to the instance group..." gcloud compute instance-groups unmanaged add-instances web-app-instance-group \ --instances=$WEB_SERVER_VM_NAME \ --zone=$ZONE \ --project=$GCP_PROJECT_ID
How to create (Cloud Console - Alternative):
Navigate to Compute Engine > Instance groups in the GCP Console.
Click + CREATE INSTANCE GROUP.
Name:
web-app-instance-group
Instance group type: Select
Unmanaged instance group
.Location:
Single zone
, selectus-central1-a
.Network:
default
.VM instances: Click ADD VM INSTANCES and select
web-server-vm
.Click CREATE.
3. Create a Health Check
Why: Load Balancers use health checks to determine if the backend instances are alive and responsive. Traffic is only sent to healthy instances. This is essential for proper load balancing and high availability.
How to create (
gcloud CLI
- Recommended):echo "Creating HTTP health check..." gcloud compute health-checks create http web-app-health-check \ --port=80 \ --check-interval=5s \ --timeout=5s \ --unhealthy-threshold=2 \ --healthy-threshold=2 \ --project=$GCP_PROJECT_ID
How to create (Cloud Console - Alternative):
Navigate to Network Services > Load balancing in the GCP Console.
In the left navigation, under "Load balancing resources," click Health checks.
Click + CREATE A HEALTH CHECK.
Name:
web-app-health-check
Protocol:
HTTP
.Port:
80
.Leave other defaults. Click CREATE.
4. Configure a Backend Service
Why: A Backend Service manages the connections between the Load Balancer and your instance groups. This is where the health check is applied, the Cloud Armor security policy will be attached, and crucially, access logging for requests will be enabled here.
How to configure (
gcloud CLI
- Recommended):echo "Creating backend service and enabling access logging..." gcloud compute backend-services create web-app-backend-service \ --protocol=HTTP \ --port-name=http \ --health-checks=web-app-health-check \ --timeout=30s \ --global \ --enable-cdn \ --enable-logging \ --logging-sample-rate=1.0 \ --project=$GCP_PROJECT_ID echo "Adding instance group to backend service..." gcloud compute backend-services add-backend web-app-backend-service \ --instance-group=web-app-instance-group \ --instance-group-zone=$ZONE \ --global \ --project=$GCP_PROJECT_ID
How to configure (Cloud Console - Alternative):
Navigate to Network Services > Load balancing in the GCP Console.
In the left navigation, under "Load balancing resources," click Backend services.
Click + CREATE A BACKEND SERVICE.
Name:
web-app-backend-service
Protocol:
HTTP
.Backend type:
Instance group
.Instance group: Select
web-app-instance-group
and its zoneus-central1-a
.Health check: Select
web-app-health-check
.Advanced configurations (for logging):
Under "Cloud CDN", select Enable Cloud CDN (even if not using CDN, this is required for logging).
Under "Logging", select Enable logging.
Sample rate:
100
(for 100%).
Click CREATE.
5. Reserve a Static External IP Address for the Load Balancer
Why: A static external IP address provides a permanent, public IP for your Load Balancer. This is necessary for external clients to reach your web application consistently.
How to reserve (
gcloud CLI
- Recommended):echo "Reserving static external IP for Load Balancer..." gcloud compute addresses create $LB_IP_NAME \ --ip-version=IPV4 \ --global \ --project=$GCP_PROJECT_ID # Capture the reserved IP address into a variable for later use export LB_IP=$(gcloud compute addresses describe $LB_IP_NAME --format="value(address)" --global --project=$GCP_PROJECT_ID) echo "Load Balancer External IP: $LB_IP"
How to reserve (Cloud Console - Alternative):
Navigate to VPC network > IP addresses in the GCP Console.
Click + RESERVE EXTERNAL STATIC ADDRESS.
Name:
web-app-lb-ip
Type:
Global
.Click RESERVE. Note down the reserved IP address.
6. Create a URL Map
Why: A URL Map directs incoming requests from the Load Balancer's frontend to the appropriate backend service based on URL paths or hostnames. For a simple app, it just points all traffic to our single backend service.
How to create (
gcloud CLI
- Recommended):echo "Creating URL map..." gcloud compute url-maps create web-app-url-map \ --default-service=web-app-backend-service \ --project=$GCP_PROJECT_ID
How to create (Cloud Console - Alternative):
Navigate to Network Services > Load balancing in the GCP Console.
In the left navigation, under "Load balancing resources," click URL maps.
Click + CREATE URL MAP.
Name:
web-app-url-map
Default backend: Select
web-app-backend-service
.Click CREATE.
7. Configure the Global Forwarding Rule (Frontend)
Why: The Forwarding Rule defines the external IP address, port, and protocol that the Load Balancer listens on. This is the final piece that exposes your application to the internet.
How to configure (
gcloud CLI
- Recommended):echo "Creating global HTTP forwarding rule..." gcloud compute target-http-proxies create http-proxy \ --url-map=web-app-url-map \ --project=$GCP_PROJECT_ID gcloud compute forwarding-rules create http-forwarding-rule \ --address=$LB_IP_NAME \ --global \ --target-http-proxy=http-proxy \ --ports=80 \ --project=$GCP_PROJECT_ID
This step can take several minutes for the Load Balancer to become fully provisioned and for its IP to become publicly accessible. Be patient! (Mostly a reminder for myself 👀)
How to configure (Cloud Console - Alternative):
Navigate to Network Services > Load balancing in the GCP Console.
Click CREATE LOAD BALANCER.
Select HTTP(S) Load Balancer. Click START CONFIGURATION.
Internet to your VMs or serverless services. Click CONTINUE.
Global external HTTP(S) Load Balancer. Click CONTINUE.
Backend configuration:
Click Backend services and backend buckets dropdown, then Create a backend service.
Name:
web-app-backend-service
(if not already created).Backend type:
Instance group
.Instance group: Select
web-app-instance-group
,us-central1-a
.Health check: Select
web-app-health-check
.Click CREATE.
Click OK.
Routing rules: Click Path rules and host rules dropdown. Ensure
Mode: Simple host and path rule
,Hosts: Any
,Paths: Any
, andBackends: web-app-backend-service
.Frontend configuration:
Click Add Frontend IP and port.
Name:
http-frontend
Protocol:
HTTP
IP address: Select Create IP Address.
Name:
web-app-lb-ip
Click RESERVE.
Port:
80
.Click DONE.
Review and finalize: Click Review and finalize.
Click CREATE.
After creation, note down the IP Address shown for your new Load Balancer (e.g.,
34.X.Y.Z
).
8. Verify Load Balancer Access
Why: Before applying Cloud Armor, I need to confirm that my web application is publicly accessible through the Load Balancer's external IP address.
How to verify (From your browser or Cloud Shell):
Go to your Cloud Shell. Ensure your
LB_IP
variable is set (if you used CLI to reserve) or manually copy the Load Balancer's external IP.In your Cloud Shell, run
echo $LB_IP
to see the IP.Now, use
curl
to access the web server through the Load Balancer's external IP:curl http://$LB_IP
Expected Result: You should see the HTML content:
<!DOCTYPE html><html><head><title>Cloud Armor Lab</title></head><body><h1>Hello from Cloud Armor Lab!</h1><p>This is my simple web page.</p></body></html>
You can also paste
http://YOUR_LOAD_BALANCER_IP
directly into your web browser to confirm.Be patient: It can take up to 5-10 minutes for a newly created Global Load Balancer to become fully active and propagate across Google's network. I am being serious, I literally closed my computer after trying 14 times in a row, walked over to make a cup of coffee and when I came back it started working.
Phase 3: Implementing Cloud Armor Basic Protection
Goal: In this phase, I'll create my first Cloud Armor security policy and attach it to my Load Balancer's backend service. This policy will contain a simple rule to block traffic from a specific IP address, demonstrating Cloud Armor's ability to filter malicious requests at the network edge. I'll create multiple rules demonstrating various WAF capabilities, including IP blocking, detecting common web application attacks (SQLi, XSS), and geo-blocking.
1. Set Essential Variables (If Your Cloud Shell Session is New)
Why: If you're picking up this lab after a break or in a new Cloud Shell session, these variables might be unset. Re-exporting them ensures all subsequent commands work correctly.
How to set: Copy and paste this block into your Cloud Shell:
# Essential Variables to redeclare if your Cloud Shell session restarts export GCP_PROJECT_ID="gcp-cloudarmor-lab-jt" # Your Project ID export REGION="us-central1" export ZONE="${REGION}-a" # Names for resources (from previous phases) export WEB_SERVER_VM_NAME="web-server-vm" export LB_IP_NAME="web-app-lb-ip" export CA_POLICY_NAME="web-app-policy" # Name for your Cloud Armor policy
You'll need your Load Balancer's External IP (LB_IP) from Phase 2, Part 5 for testing later. You can re-capture it with
export LB_IP=$(gcloud compute addresses describe $LB_IP_NAME --format="value(address)" --global --project=$GCP_PROJECT_ID)
if needed.
2. Create a Cloud Armor Security Policy
Why: A security policy is a collection of rules that define how Cloud Armor protects your application. I'll create an empty policy first, then add rules to it.
How to create (
gcloud CLI
- Recommended):echo "Creating Cloud Armor security policy: $CA_POLICY_NAME..." gcloud compute security-policies create $CA_POLICY_NAME \ --description="Comprehensive Cloud Armor policy for web app protection" \ --project=$GCP_PROJECT_ID
How to create (Cloud Console - Alternative):
Navigate to Network Security > Cloud Armor in the GCP Console.
Click CREATE POLICY.
Policy name:
web-app-policy
Policy type:
Edge security policy
.Description:
Comprehensive Cloud Armor policy for web app protection
.Leave other defaults. Click CREATE POLICY.
3. Add Multiple Rules for Different Attack Types
Why: Here, I'll configure Cloud Armor with several rules to demonstrate its versatility. Each rule will target a different type of threat or traffic filtering:
IP Blocking: Deny traffic from a specific malicious IP.
SQL Injection (SQLi) Protection: Use a preconfigured WAF rule to block common SQLi attack patterns.
Cross-Site Scripting (XSS) Protection: Use a preconfigured WAF rule to block common XSS attack patterns.
Geo-Blocking: Deny traffic from a specific country.
General Rule Structure: Each rule has a priority (lower numbers are higher priority), a match condition (e.g., IP range, WAF expression, geo-location), and an action (e.g.,
deny-403
). The default rule (priority 2147483647, alwaysallow
) acts as a fallback for traffic not matched by any other rule.How to add (
gcloud CLI
- Recommended):a. Rule: Deny a Specific IP Address (Priority 1000)
Why: A basic but effective way to block known malicious actors or test specific clients.
Action:
# IMPORTANT: Replace 'YOUR_EXTERNAL_IP_TO_BLOCK' with the actual IP you want Cloud Armor to block! # This should be your current home/office IP or a test IP you control. export BLOCK_IP_ADDRESS="YOUR_EXTERNAL_IP_TO_BLOCK" echo "Adding rule: Deny traffic from a specific IP ($BLOCK_IP_ADDRESS)..." gcloud compute security-policies rules create 1000 \ --security-policy=$CA_POLICY_NAME \ --description="Deny specific test IP" \ --src-ip-ranges=$BLOCK_IP_ADDRESS \ --action=deny-403 \ --project=$GCP_PROJECT_ID
b. Rule: Deny SQL Injection Attacks (Priority 1001)
Why: Cloud Armor provides preconfigured WAF rules that use ModSecurity Core Rule Set (CRS) signatures to detect common web application attacks like SQLi.
Action:
echo "Adding rule: Deny SQL Injection attacks using preconfigured WAF rule..." gcloud compute security-policies rules create 1001 \ --security-policy=$CA_POLICY_NAME \ --description="Deny SQL Injection attacks" \ --expression="evaluatePreconfiguredWaf('sqli-v33-stable')" \ --action=deny-403 \ --project=$GCP_PROJECT_ID
evaluatePreconfiguredWaf('sqli-v33-stable')
tells Cloud Armor to use its built-in SQLi detection rules.v33-stable
indicates the version of the rule set.
c. Rule: Deny Cross-Site Scripting (XSS) Attacks (Priority 1002)
Why: Similar to SQLi, preconfigured WAF rules detect XSS attacks, preventing malicious scripts from being injected into your web pages.
Action:
echo "Adding rule: Deny Cross-Site Scripting (XSS) attacks using preconfigured WAF rule..." gcloud compute security-policies rules create 1002 \ --security-policy=$CA_POLICY_NAME \ --description="Deny Cross-Site Scripting (XSS) attacks" \ --expression="evaluatePreconfiguredWaf('xss-v33-stable')" \ --action=deny-403 \ --project=$GCP_PROJECT_ID
d. Rule: Deny Traffic from a Specific Country (Geo-Blocking) (Priority 1003)
Why: Geo-blocking allows you to restrict access based on the geographic origin of the request. I'll block traffic from a country like "China" (CN) for demonstration. You can choose any country code (e.g., "RU" for Russia, "KP" for North Korea, etc.).
Action:
echo "Adding rule: Deny traffic from China (CN) using geo-blocking..." gcloud compute security-policies rules create 1003 \ --security-policy=$CA_POLICY_NAME \ --description="Deny traffic from China (CN)" \ --expression="origin.region_code == 'CN'" \ --action=deny-403 \ --project=$GCP_PROJECT_ID
You can replace
'CN'
with any ISO 3166-1 alpha-2 country code.
How to add (Cloud Console - Alternative):
Navigate to Network Security > Cloud Armor in the GCP Console.
Click on your policy name (
web-app-policy
).Go to the Rules tab.
Click ADD RULE for each rule below:
For IP Blocking (Priority 1000):
Priority:
1000
. Action:Deny
, HTTP response code:403 (Forbidden)
.IP addresses: In Source IP ranges, enter your
BLOCK_IP_ADDRESS
.Description:
Deny specific test IP
. Click DONE.
For SQLi Protection (Priority 1001):
Priority:
1001
. Action:Deny
, HTTP response code:403 (Forbidden)
.Condition (using a preconfigured WAF rule):
Click
Condition
.Select
Preconfigured WAF rules (OWASP Top 10)
.Select
SQL Injection (SQLi)
.Select
SQLI - Core Rule Set (CRS) v3.3
.Click
Done
.
Description:
Deny SQL Injection attacks
. Click DONE.
For XSS Protection (Priority 1002):
Priority:
1002
. Action:Deny
, HTTP response code:403 (Forbidden)
.Condition (using a preconfigured WAF rule):
Click
Condition
.Select
Preconfigured WAF rules (OWASP Top 10)
.Select
Cross-Site Scripting (XSS)
.Select
XSS - Core Rule Set (CRS) v3.3
.Click
Done
.
Description:
Deny Cross-Site Scripting (XSS) attacks
. Click DONE.
For Geo-Blocking (Priority 1003):
Priority:
1003
. Action:Deny
, HTTP response code:403 (Forbidden)
.Condition (using a custom expression):
Click
Condition
.In the text box, enter
origin.region_code == 'CN'
(replace 'CN' with your desired country code).Click
Done
.
Description:
Deny traffic from China (CN)
. Click DONE.
5. Attach the Security Policy to the Load Balancer's Backend Service
Why: The security policy needs to be explicitly attached to the backend service that serves your web application. This is the integration point where Cloud Armor starts inspecting traffic before it reaches your VM.
How to attach (
gcloud CLI
- Recommended):echo "Attaching Cloud Armor policy to Load Balancer backend service..." gcloud compute backend-services update web-app-backend-service \ --security-policy=$CA_POLICY_NAME \ --global \ --project=$GCP_PROJECT_ID
How to attach (Cloud Console - Alternative):
Navigate to Network Services > Load balancing in the GCP Console.
In the left navigation, click Backend services.
Click on your backend service name (
web-app-backend-service
).Click EDIT.
Scroll down to Google Cloud Armor security policy.
Select your
web-app-policy
from the dropdown.Click UPDATE.
Phase 4: Simulating Attacks & Verifying Cloud Armor Blocks
Goal: In this phase, I'll actively test my Cloud Armor security policy to confirm that it's correctly blocking various types of traffic I configured. This is where I see my WAF in action!
- Remember: Cloud Armor policies, once attached, can take a few minutes to propagate globally across Google's network. If your tests don't work immediately, wait 3-5 minutes and try again.
1. Set Essential Variables (If Your Cloud Shell Session is New)
Why: If you're picking up this lab after a break or in a new Cloud Shell session, these variables might be unset. Re-exporting them ensures all subsequent commands work correctly.
How to set: Copy and paste this block into your Cloud Shell:
# Essential Variables to redeclare if your Cloud Shell session restarts export GCP_PROJECT_ID="gcp-cloudarmor-lab-jt" # Your Project ID export REGION="us-central1" export ZONE="${REGION}-a" # Names for resources (from previous phases) export WEB_SERVER_VM_NAME="web-server-vm" export LB_IP_NAME="web-app-lb-ip" export CA_POLICY_NAME="web-app-policy" # Specific IP to block (from Phase 3) export BLOCK_IP_ADDRESS="YOUR_EXTERNAL_IP_TO_BLOCK" # Make sure this is still set to the IP you blocked
You'll need your Load Balancer's External IP (
LB_IP
) for testing. You can re-capture it withexport LB_IP=$(gcloud compute addresses describe $LB_IP_NAME --format="value(address)" --global --project=$GCP_PROJECT_ID)
if needed. Runecho $LB_IP
to see it.
2. Verify Normal Access to the Web Application (From an Allowed IP, like Cloud Shell)
Why: Before trying to block traffic, I need to confirm that my web application is still accessible as normal from an IP address that is not in my Cloud Armor deny list. This ensures the Load Balancer and web server are functioning correctly.
How to verify (From your browser or Cloud Shell):
Determine your current external IP address. You can use a website like
whatismyip.com
or Google "what is my ip". Make sure this IP is NOT the one you configured Cloud Armor to block ($BLOCK_IP_ADDRESS
). If it is, you'll need to use a different network/client for this test (e.g., your phone's mobile data, a VPN, your Cloud Shell, or a different computer).In your Cloud Shell, ensure your
LB_IP
variable is set (from Phase 2, Part 5) or manually copy the Load Balancer's external IP from the Console (VPC network -> IP addresses).Now, use
curl
from your Cloud Shell to access the web server through the Load Balancer's external IP:curl http://$LB_IP
Expected Result: You should see the HTML content of your web page:
<!DOCTYPE html><html><head><title>Cloud Armor Lab</title></head><body><h1>Hello from Cloud Armor Lab!</h1><p>This is my simple web page.</p></body></html>
.You can also paste
http://YOUR_LOAD_BALANCER_IP
directly into your web browser (ensuring your browser's IP is allowed) to confirm.
3. Simulate Attack: Access from the Blocked IP Address
Why: This is the core test of Cloud Armor's IP blocking effectiveness. I'll attempt to access the web application from the specific
BLOCK_IP_ADDRESS
that I configured in my Cloud Armor policy. Cloud Armor should intercept and deny this request.How to simulate (From a client with the
BLOCK_IP_ADDRESS
):Important: You need to perform this test from the actual IP address that you configured in your Cloud Armor policy as
BLOCK_IP_ADDRESS
.If
BLOCK_IP_ADDRESS
is your current home/office IP: Simply use your web browser or a localcurl
command from your computer.If
BLOCK_IP_ADDRESS
is a different IP (e.g., a test server you control): You'll need to run thecurl
command from that specific test server.
Using your browser, try to navigate to
http://YOUR_LOAD_BALANCER_IP
.Using
curl
from theBLOCK_IP_ADDRESS
source:curl -v http://$LB_IP
Expected Result: You should receive an HTTP
403 Forbidden
response. The browser will likely show a "403 Forbidden" error page. Thecurl -v
output will explicitly show:< HTTP/1.1 403 Forbidden
This confirms Cloud Armor successfully blocked the request based on the IP address.
4. Simulate Attack: SQL Injection (SQLi) Protection Test
Why: Now, let's test Cloud Armor's ability to detect and block common web application attacks using its preconfigured WAF rules. Even though our
index.html
isn't actually vulnerable to SQLi, Cloud Armor will still block requests containing common SQLi payloads.How to simulate (From any allowed client):
This test can be performed from any client whose IP address is not blocked by your policy. You can use your Cloud Shell's
curl
.I'll construct a
curl
command that attempts to send a common SQLi payload in the URL path.echo "Attempting a SQL Injection attack (EXPECTED TO BE BLOCKED)..." curl -v "http://$LB_IP/index.html?id=1%20OR%201=1"
%20
is the URL-encoded space character.
Expected Result: Just like with the IP block, you should receive an HTTP
403 Forbidden
response. Thecurl -v
output will showHTTP/1.1 403 Forbidden
. This confirms Cloud Armor's WAF rule detected the SQLi pattern.
5. Simulate Attack: Cross-Site Scripting (XSS) Protection Test
Why: Let's test another common web vulnerability – XSS. Cloud Armor has rules to detect XSS payloads that attempt to inject malicious client-side scripts.
How to simulate (From any allowed client):
This test can also be performed from any client whose IP address is not blocked.
I'll send a
curl
command with a common XSS payload in the URL path.echo "Attempting a Cross-Site Scripting (XSS) attack (EXPECTED TO BE BLOCKED)..." curl -v "http://$LB_IP/index.html?query=<script>alert('XSS');</script>"
Note the URL-encoded characters like
%3C
for<
and%3E
for>
.
Expected Result: Again, you should receive an HTTP
403 Forbidden
response. This confirms Cloud Armor's WAF rule detected the XSS pattern.
6. Simulate Attack: Geo-Blocking Test
Why: I configured Cloud Armor to deny traffic from a specific country (e.g., China - CN). This test verifies if the geo-blocking rule is working.
How to simulate (From a client in the blocked country - if possible):
This is the trickiest test, as it requires a client with an IP address from the country you chose to block.
You might need to use a VPN service and connect to a server in that country (e.g., China if you blocked CN).
Once connected via VPN, ensure your external IP reflects the blocked country.
Then, open your web browser and navigate to
http://YOUR_LOAD_BALANCER_IP
.
If you cannot get an IP from the blocked country: You can skip this step, but understand that in a real scenario, this is how you'd verify geo-blocking. Cloud Armor's logs (in Phase 5) will still show attempts from the blocked country if they happen organically.
Expected Result: If testing from a truly blocked country IP, you should receive an HTTP
403 Forbidden
response.
Phase 5: Monitoring & Analyzing Cloud Armor Logs
Goal: In this phase, I'll dive into Cloud Logging to find the evidence of Cloud Armor's work. I want to confirm that Cloud Armor correctly logged the request from the blocked IP address and indicated that it took a "deny" action. This is crucial for auditing, incident response, and understanding my security posture.
1. Set Essential Variables (If Your Cloud Shell Session is New)
Why: If you're picking up this lab after a break or in a new Cloud Shell session, these variables might be unset. Re-exporting them ensures all subsequent commands work correctly.
How to set: Copy and paste this block into your Cloud Shell:
# Essential Variables to redeclare if your Cloud Shell session restarts export GCP_PROJECT_ID="gcp-cloudarmor-lab-jt" # Your Project ID export REGION="us-central1" export ZONE="${REGION}-a" # Names for resources (from previous phases) export WEB_SERVER_VM_NAME="web-server-vm" export LB_IP_NAME="web-app-lb-ip" export CA_POLICY_NAME="web-app-policy" export BLOCK_IP_ADDRESS="YOUR_EXTERNAL_IP_TO_BLOCK" # Make sure this is still set to the IP you blocked
You'll also need your Load Balancer's External IP (
LB_IP
) from Phase 2, Part 5 for reference. You can re-capture it withexport LB_IP=$(gcloud compute addresses describe $LB_IP_NAME --format="value(address)" --global --project=$GCP_PROJECT_ID)
if needed.
2. Access Cloud Logging (Logs Explorer)
Why: Cloud Logging is where all audit and activity logs from Cloud Armor are sent. The Logs Explorer interface allows me to query and analyze these logs.
How to access:
- Navigate to Operations > Logging > Logs Explorer in the GCP Console.
3. Query for Cloud Armor Block Logs
What I'm looking for: I want to find the log entry generated by Cloud Armor when it blocked the request from my
BLOCK_IP_ADDRESS
. These logs are associated with the Load Balancer resource type and carry details from thenetworksecurity.googleapis.com
service.How to find (Logs Explorer Query):
In Logs Explorer, clear any previous text from the main "Query" text box.
Then, paste the entire query below into that main "Query" text box.
Important: Adjust the time range! Make sure your time range selected at the top of Logs Explorer covers the exact time you performed the attack simulations in Phase 4. Set it to "Last 1 hour" or "Last 30 minutes" for recent events, or "Last 7 days" if you took a break.
Note on variables: Remember to replace
${GCP_PROJECT_ID}
with your actual Project ID, andYOUR_EXTERNAL_IP_TO_BLOCK
with the actual IP you used.
resource.type="http_load_balancer"
logName="projects/${GCP_PROJECT_ID}/logs/requests"
jsonPayload.statusDetails="denied_by_security_policy"
jsonPayload.enforcedSecurityPolicy.name="web-app-policy"
- Click Run query.
Analyze the Log Entry:
Look for logs with
jsonPayload.statusDetails
set to"denied_by_security_policy"
.Expand the log entries that are found.
You should be able to see:
jsonPayload.remoteIp
: This shows the IP that was blocked (your IP from your tests).jsonPayload.enforcedSecurityPolicy.outcome
: This will showDENY
.jsonPayload.enforcedSecurityPolicy.priority
: This will be1000
,1001
,1002
, or1003
depending on which rule was matched.httpRequest.requestUrl
: This shows the URL that was accessed, which will contain your SQLi or XSS payloads for those tests.
This log provides a clear audit trail of all the blocked malicious attempts.
What this means: This log entry serves as definitive proof that Cloud Armor successfully intercepted and denied the traffic based on your configured policies. In a real-world scenario, this log would be crucial for your security operations center (SOC) to identify and respond to attacks.
Phase 6: Cleaning Up Your Lab Environment
- Why clean up? This is a critical final step in any cloud lab! To avoid incurring unnecessary costs for resources you're no longer using and to keep your GCP project tidy, it's essential to delete all the resources we created during this lab.
I'll provide gcloud CLI
commands for quick cleanup, and I'll outline the Console steps as well.
Important Note on Deletion Order: Resources sometimes have dependencies (e.g., you can't delete a network router if a NAT gateway is using it, or a service account if it's attached to a running VM). I'll provide the commands in a logical order to minimize dependency errors.
1. Delete Cloud Armor Security Policy
Why: The Cloud Armor policy must be detached from the backend service before it can be deleted. This two-step process is crucial.
How to delete (
gcloud CLI
- Recommended):echo "Attempting to detach Cloud Armor policy from backend service..." gcloud compute backend-services update web-app-backend-service \ --security-policy="" \ --global \ --project=$GCP_PROJECT_ID \ --quiet || true echo "Deleting Cloud Armor security policy: $CA_POLICY_NAME..." gcloud compute security-policies delete $CA_POLICY_NAME \ --project=$GCP_PROJECT_ID \ --quiet || true
How to delete (Cloud Console - Alternative):
Navigate to Network Services > Load balancing > Backend services in the GCP Console.
Click on your backend service name (
web-app-backend-service
).Click EDIT.
Scroll down to Google Cloud Armor security policy and select
None
. Click UPDATE.Now, navigate to Network Security > Cloud Armor.
Select the checkbox next to
web-app-policy
.Click the DELETE button at the top and confirm the deletion.
2. Delete Load Balancer Components
Why: Load Balancer components (forwarding rule, proxy, URL map, backend service) must be deleted in a specific order.
How to delete (
gcloud CLI
- Recommended):echo "Deleting Load Balancer forwarding rule..." gcloud compute forwarding-rules delete http-forwarding-rule \ --global \ --project=$GCP_PROJECT_ID \ --quiet || true echo "Deleting Load Balancer target HTTP proxy..." gcloud compute target-http-proxies delete http-proxy \ --global \ --project=$GCP_PROJECT_ID \ --quiet || true echo "Deleting Load Balancer URL map..." gcloud compute url-maps delete web-app-url-map \ --project=$GCP_PROJECT_ID \ --quiet || true echo "Deleting Load Balancer backend service..." gcloud compute backend-services delete web-app-backend-service \ --global \ --project=$GCP_PROJECT_ID \ --quiet || true
How to delete (Cloud Console - Alternative):
Go to Network Services > Load balancing.
In the left menu, navigate to each resource type (e.g., Forwarding Rules, Target Proxies, etc.) and delete them in the order listed above.
3. Delete the Web Server VM and Related Resources
Why: This removes the VM, its instance group, and the health check.
How to delete (
gcloud CLI
- Recommended):echo "Deleting Load Balancer health check..." gcloud compute health-checks delete web-app-health-check \ --project=$GCP_PROJECT_ID \ --quiet || true echo "Deleting unmanaged instance group..." gcloud compute instance-groups unmanaged delete web-app-instance-group \ --zone=$ZONE \ --project=$GCP_PROJECT_ID \ --quiet || true echo "Deleting Web Server VM: $WEB_SERVER_VM_NAME..." gcloud compute instances delete $WEB_SERVER_VM_NAME --zone=$ZONE --project=$GCP_PROJECT_ID --quiet || true
How to delete (Cloud Console - Alternative):
Navigate to Compute Engine > VM instances in the GCP Console.
Select the checkbox next to
web-server-vm
.Click the DELETE button at the top and confirm the deletion.
Then, delete the Health Check and Instance Group from the Load Balancing menu.
4. Delete Networking and Final Cleanup
Why: This removes the NAT gateway, Cloud Router, and static IP address, which are all billable resources.
How to delete (
gcloud CLI
- Recommended):echo "Deleting Cloud NAT Gateway..." export ROUTER_NAME="nat-router-${REGION}" export NAT_NAME="nat-gateway-${REGION}" gcloud compute routers nats delete ${NAT_NAME} --router=${ROUTER_NAME} --region=$REGION --project=$GCP_PROJECT_ID --quiet || true echo "Deleting Cloud Router..." gcloud compute routers delete ${ROUTER_NAME} --region=$REGION --project=$GCP_PROJECT_ID --quiet || true echo "Releasing static external IP address: $LB_IP_NAME..." gcloud compute addresses delete $LB_IP_NAME --global --project=$GCP_PROJECT_ID --quiet || true
How to delete (Cloud Console - Alternative):
Navigate to Network Services > Cloud NAT. Delete the NAT gateway.
Navigate to Network Services > Cloud Routers. Delete the router.
Navigate to VPC network > IP addresses. Delete the static IP address.
5. Delete the Entire GCP Project (Most Comprehensive Cleanup)
Why: This is the most thorough way to ensure all resources and associated configurations are removed, guaranteeing no further costs.
How to delete (Cloud Console - Recommended):
Go to IAM & Admin > Settings in the GCP Console.
Click SHUT DOWN.
Enter your Project ID (
gcp-cloudarmor-lab-jt
) to confirm. Note: Project deletion can take several days to complete fully.
Conclusion & Next Steps
Phew! If you've made it this far, congratulations! You've successfully navigated a comprehensive GCP cybersecurity lab. You've built a multi-VM environment, simulated various attack scenarios, meticulously enabled logging and monitoring, and then acted as a digital detective to unearth the evidence of those attacks using Cloud Logging and Monitoring.
It's important to note that this lab was simplified for clarity and accessibility. In the real world, detecting a sophisticated threat actor is a far more complex challenge, involving advanced threat intelligence, anomaly detection, security information and event management (SIEM) systems, and deep forensic analysis. However, this lab serves as an excellent foundation and a great way to familiarize yourself with where crucial security signals reside within GCP. Understanding where to look and how logs and metrics behave in a simulated compromise is an invaluable skill.
Your Challenge: To deepen your learning, I challenge you to go back to Cloud Logging's Logs Explorer and Cloud Monitoring's Metrics Explorer. Don't just copy-paste my queries. Instead:
Try to generate the log queries on your own. Experiment with different filters.
Think about what other types of events or metrics you could use to detect these scenarios.
Consider what insights you would genuinely benefit from in a real security operations center (SOC) for each attack type. How would you prioritize the information?
What's Next? This lab touched upon just a few facets of GCP security. Consider exploring:
Security Command Center's other capabilities (even in the Free Tier).
Setting up VPC Service Controls for data perimeter security.
Implementing Identity-Aware Proxy for applications, not just SSH.
Diving deeper into Cloud IAM best practices.
Just like always, the journey of learning cybersecurity never truly ends.
Thanks for making it to the end and thank you for reading. Keep learning!
jt
Subscribe to my newsletter
Read articles from José Toledo directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
