Investigate Traffic and Enforce Governance
Monitor VPC network traffic and enforce security compliance with AWS Config.
Introduction
30 Second Summary
Companies hire cloud security analysts to do two things: watch what traffic is flowing through their networks, and make sure every resource follows security rules. These two skills, monitoring and governance, are the foundation of every cloud security role.
In this project, you will build a security investigation and governance lab on AWS. You will deploy a web server, intentionally leave its firewall wide open, then use VPC Flow Logs and AWS Config to catch and fix the misconfiguration.
What You'll Build
You will open a compliance dashboard showing your security group status flip from non-compliant to compliant, backed by real network traffic records proving exactly when the fix took effect.
By the end of this project, you'll have:
- A live web server running in a VPC you built from scratch, proving you understand cloud networking.
- VPC Flow Log records showing accepted and rejected traffic in CloudWatch, proving you can investigate network activity.
- An AWS Config compliance dashboard showing your security group went from NON_COMPLIANT to COMPLIANT, proving you can enforce governance.
- Secret Mission: Add a second compliance rule that catches even more network misconfigurations.
Are there any prerequisites?
You need an AWS account with free tier eligibility. Familiarity with IAM and CloudTrail from a previous security monitoring project is helpful but not required.
Before We Start
Before we dive in, let's get clear on what you're about to build and why it matters.
In this project, you'll construct a cloud security investigation and governance lab from scratch. You'll deploy a web server, monitor its network traffic with VPC Flow Logs, and use AWS Config to automatically catch and fix security misconfigurations.
Build the Network Foundation
Every cloud security investigation starts with a network. Before you can deploy servers, monitor traffic, or enforce governance rules, you need a virtual network with internet access.
In this step, you will build a custom VPC from scratch in AWS. This includes a subnet for placing resources, an internet gateway for external connectivity, and a route table to direct traffic.
In this step, get ready to:
- Create a VPC and a public subnet for your security lab.
- Connect the VPC to the internet with a gateway and route table.
- Verify all networking components are linked together.
Create the VPC and public subnet
Your security lab needs its own isolated network. You will create a VPC with a large address range, then carve out a smaller subnet inside it where your server will live.
- Sign in to the AWS Management Console at https://console.aws.amazon.com/.
- In the search bar at the top of the console, type VPC and select VPC from the results.
- On the VPC dashboard, click Create VPC.
- For Resources to create, select VPC only.
- In the Name tag field, enter security-lab-vpc.
- For IPv4 CIDR block, select IPv4 CIDR manual input and enter 10.0.0.0/16.
- Leave all other settings at their defaults and click Create VPC.
You should see a green success banner confirming your VPC was created.
What is a VPC?
A VPC (Virtual Private Cloud) is your own isolated network inside AWS. Think of it as renting a private floor in a shared office building.
The CIDR block 10.0.0.0/16 defines the range of IP addresses available in your network, giving you over 65,000 addresses to work with.
Now you need a subnet inside this VPC where you will place your server.
- In the left sidebar, click Subnets.
- Click Create subnet.
- Under VPC ID, select security-lab-vpc from the dropdown.
- In the Subnet name field, enter security-lab-subnet.
- Choose any Availability Zone from the dropdown.
- In the IPv4 subnet CIDR block field, enter 10.0.1.0/24.
- Click Create subnet.
A green success banner confirms your subnet was created.
What is a subnet?
A subnet is a smaller network inside your VPC. Your VPC has the full 10.0.0.0/16 range, and this subnet carves out 10.0.1.0/24, giving you 256 addresses.
You will place your EC2 instance in this subnet in the next step.
Don't see your VPC in the subnet dropdown?
Make sure you are in the same AWS region where you created the VPC. Check the region selector in the top-right corner of the console.
Help me find my security-lab-vpc in the subnet creation dropdown.
Connect the VPC to the internet
Your VPC is isolated by default. To allow traffic in and out, you need two things: an internet gateway (the door to the public internet) and a route table (the map that tells traffic which door to use).
- In the left sidebar, click Internet gateways.
- Click Create internet gateway.
- In the Name tag field, enter security-lab-igw.
- Click Create internet gateway.
After creation, a banner appears at the top of the page. You need to attach this gateway to your VPC.
- Click Attach to a VPC from the banner at the top of the screen.
- Select security-lab-vpc from the Available VPCs dropdown.
- Click Attach internet gateway.
The State of your internet gateway now shows Attached.
What is an internet gateway?
An internet gateway connects your VPC to the public internet. Without one, nothing inside your VPC can reach the outside world, and nobody outside can reach your resources.
Attaching the gateway alone is not enough. You still need a route table that tells traffic to use the gateway as its exit path.
Now create the route table and point it at your internet gateway.
- In the left sidebar, click Route tables.
- Click Create route table.
- In the Name field, enter security-lab-rt.
- Under VPC, select security-lab-vpc.
- Click Create route table.
Your route table is created but has no route to the internet yet. Time to add one.
- On the route table detail page, click the Routes tab.
- Click Edit routes.
- Click Add route.
- In the Destination field, enter 0.0.0.0/0.
- In the Target dropdown, select Internet Gateway, then select security-lab-igw.
- Click Save changes.
The route is saved. Now associate this route table with your subnet so resources in the subnet use it.
- Click the Subnet associations tab.
- Click Edit subnet associations.
- Check the box next to security-lab-subnet.
- Click Save associations.
What does the route table do?
A route table acts as a map for network traffic. The route you added says: any traffic heading to an address outside this VPC (0.0.0.0/0 means "anywhere") should go through the internet gateway.
Associating the route table with your subnet means resources in that subnet follow this map. This is what makes a subnet "public."
Confirm everything is connected
You created four networking components. Before moving on, confirm they are all connected correctly.
Before you check, can you name all four components you created and describe how they connect to each other?
- In the left sidebar, click Your VPCs.
- Confirm security-lab-vpc appears with CIDR 10.0.0.0/16.
- Click Subnets in the sidebar.
- Confirm security-lab-subnet appears with CIDR 10.0.1.0/24 and is associated with security-lab-vpc.
- Click Internet gateways in the sidebar.
- Confirm security-lab-igw shows Attached to security-lab-vpc.
- Click Route tables in the sidebar and select security-lab-rt.
- On the Routes tab, confirm 0.0.0.0/0 points to security-lab-igw. On the Subnet associations tab, confirm security-lab-subnet is listed.
All four components are in place and connected. Your VPC has a subnet for resources, a gateway for internet access, and a route table directing traffic through that gateway.
Something missing or not connected?
If your internet gateway shows Detached, select it, click Actions, then Attach to VPC, and select security-lab-vpc.
If the route table has no 0.0.0.0/0 route, click the Routes tab, then Edit routes, and add the route with security-lab-igw as the target.
If the subnet association is missing, click the Subnet associations tab, then Edit subnet associations, and check the box next to security-lab-subnet.
Help me troubleshoot my VPC networking setup for the security lab.
Your network foundation is ready. Next up, you will deploy a web server inside this VPC and intentionally leave its firewall wide open.
Deploy a Web Server with an Open Firewall
Your network foundation is in place. Now you need something running inside it to generate real traffic worth investigating.
In this step, you'll deploy a web server on an EC2 instance inside your VPC. You'll also deliberately leave SSH open to the entire internet, creating the exact misconfiguration that cloud security analysts are hired to find.
In this step, get ready to:
- Create a security group with intentionally overpermissive firewall rules.
- Launch an EC2 instance running Apache as a web server.
- Verify the web page loads from the public internet.
Create a security group with open inbound rules
A security group acts as a virtual firewall for your instance. Each rule you add controls which traffic is allowed in or out. You're going to create one with two inbound rules, one of which is deliberately overpermissive.
- In the AWS Console search bar at the top, type EC2 and select EC2 from the results.
- In the left sidebar under Network & Security, click Security Groups.
- Click Create security group.
- For Security group name, enter security-lab-sg.
- For Description, enter Security lab firewall rules.
- For VPC, click the dropdown, remove the default VPC, and select security-lab-vpc.
Now add two inbound rules to control what traffic can reach your instance.
- In the Inbound rules section, click Add rule.
- For Type, select SSH.
- For Source, select Anywhere-IPv4 (0.0.0.0/0).
- Click Add rule again to add a second rule.
- For Type, select HTTP.
- For Source, select Anywhere-IPv4 (0.0.0.0/0).
- Scroll to the bottom and click Create security group.
The security group detail page opens. You should see security-lab-sg listed with two inbound rules: SSH on port 22 and HTTP on port 80, both open to 0.0.0.0/0.
Why leave SSH open to the entire internet?
In production, opening SSH to 0.0.0.0/0 lets anyone on the internet attempt to connect to your server on port 22. This is one of the most common misconfigurations cloud security analysts find.
You're creating this misconfiguration on purpose. Later in this project, you'll use AWS Config to automatically detect it and then fix it to prove compliance.
Launch a free-tier EC2 instance
With your security group ready, you can now launch a server that uses it. The instance will automatically install Apache and serve a web page using a startup script called user data.
- In the left sidebar, click Instances.
- Click Launch instances.
- For Name, enter security-lab-server.
- Under Application and OS Images, keep the default Amazon Linux AMI selected.
- Under Instance type, select a free-tier eligible instance type for your account.
Which instance type should I pick?
Your free-tier eligible instance type depends on when you created your AWS account.
- If your account was created before July 15, 2025, select t2.micro.
- If your account was created on or after July 15, 2025, select t3.micro.
- Under Key pair (login), click the dropdown and select Proceed without a key pair (Not recommended).
Why no key pair?
A key pair lets you SSH into your instance. You won't need direct SSH access for this project. All commands will run through AWS CloudShell later.
Now configure the network settings to place your instance in the VPC you built in Step 1.
- Under Network settings, click Edit.
- For VPC, select security-lab-vpc.
- For Subnet, select security-lab-subnet.
- For Auto-assign public IP, select Enable.
- Under Firewall (security groups), select Select existing security group.
- From the Common security groups dropdown, select security-lab-sg.
Finally, add a startup script that installs Apache and creates your web page automatically when the instance boots.
- Scroll down and expand Advanced details at the bottom of the page.
- Scroll to the User data field at the very bottom.
- Paste the following script into the User data field:
#!/bin/bash
yum update -y
yum install -y httpd
systemctl start httpd
systemctl enable httpd
echo "<h1>Security Investigation Lab</h1>" > /var/www/html/index.html
What does this script do?
- yum update -y updates all system packages on the Amazon Linux instance.
- yum install -y httpd installs the Apache web server.
- systemctl start httpd starts Apache immediately.
- systemctl enable httpd ensures Apache starts automatically if the instance reboots.
- The echo command creates a simple web page with the heading "Security Investigation Lab".
- Click Launch instance.
You should see a success message confirming your instance is launching.
Seeing an error when launching?
- If you see a VPC-related error, go back and confirm you selected security-lab-vpc and security-lab-subnet in the network settings.
- If you see an instance type error, try selecting t3.micro instead of t2.micro (or vice versa).
- Make sure the User data script starts with #!/bin/bash on the very first line.
help me troubleshoot my EC2 instance launch error
Verify your web server is live
Your instance needs a minute or two to boot up and run the startup script that installs Apache.
- Click View all instances on the success page, or click Instances in the left sidebar.
- Find your instance named security-lab-server.
- Wait until the Instance state column shows Running and the Status check column shows 2/2 checks passed.
Refresh the instance list
Click the refresh icon at the top of the Instances table to update the status. The status checks can take 2-3 minutes to complete.
- Select your instance by clicking its name or checkbox.
- In the details panel below, find the Public IPv4 address field and copy the IP address.
Before you paste this IP address into your browser, what do you expect to see? Think about what the user data script created.
- Open a new browser tab and paste the public IP address into the address bar.
- Press Enter.
You should see a page displaying the heading "Security Investigation Lab". This confirms your EC2 instance is running, Apache is serving traffic, and your VPC networking is correctly configured.
Don't see the web page?
- Make sure you're using http:// and not https://. Apache is serving on port 80 (HTTP), not 443 (HTTPS).
- Verify the instance state shows Running with 2/2 checks passed. If the status checks are still initializing, wait another minute and try again.
- Check that security-lab-sg has the HTTP inbound rule allowing port 80 from 0.0.0.0/0.
- Confirm that Auto-assign public IP was set to Enable when you launched the instance. If the Public IPv4 address field is empty, the instance has no public IP.
help me troubleshoot why my EC2 web page is not loading
Your web server is live and your firewall is deliberately misconfigured. Next up, you'll enable VPC Flow Logs to investigate every connection hitting your server.
Investigate Traffic with VPC Flow Logs
Your web server is live and serving its page to anyone who visits. But right now, you have zero visibility into what traffic is actually reaching your server.
VPC Flow Logs record every connection attempt hitting your network. In this step, you will enable flow logs on your VPC and search the records in CloudWatch Logs to see exactly who is connecting to your server and whether traffic is being allowed or blocked.
In this step, get ready to:
- Create an IAM role that allows VPC Flow Logs to write to CloudWatch Logs.
- Enable VPC Flow Logs on your VPC.
- Search flow log records to find your HTTP traffic.
Create the IAM policy for VPC Flow Logs
VPC Flow Logs need permission to create and write to CloudWatch Logs log groups. You will create an IAM policy that grants these specific permissions, then create a role that the VPC Flow Logs service can assume.
- In the AWS Console search bar at the top, type IAM and select IAM.
- In the left navigation pane, click Policies.
- Click Create policy.
- In the Policy editor section, choose the JSON option.
- Delete any existing template text, then paste the following policy:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"logs:CreateLogGroup",
"logs:CreateLogStream",
"logs:PutLogEvents",
"logs:DescribeLogGroups",
"logs:DescribeLogStreams"
],
"Resource": "*"
}
]
}
What does this policy do?
This policy allows the VPC Flow Logs service to interact with CloudWatch Logs. The five actions cover creating log groups and streams, writing log events, and describing existing log groups and streams.
Without these permissions, flow logs would have no way to deliver the network traffic records to CloudWatch.
- Click Next.
- On the Review and create page, enter FlowLogsPolicy in the Policy name field.
- Click Create policy.
You should see a green success banner confirming the policy was created. FlowLogsPolicy now appears in your policies list.
Seeing a JSON syntax error?
Make sure you deleted all of the existing template text before pasting. Any leftover characters will cause a validation error. Copy the full JSON block above and paste it fresh.
Help me fix my IAM policy JSON.
Create the IAM role for VPC Flow Logs
Now you need a role that the VPC Flow Logs service can assume. This role uses a custom trust policy that specifically names vpc-flow-logs.amazonaws.com as the trusted entity.
- In the left navigation pane, click Roles.
- Click Create role.
- Select Custom trust policy as the trusted entity type.
- In the Custom trust policy section, delete the existing template and paste the following trust policy:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "vpc-flow-logs.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}
What is a trust policy?
A trust policy defines who is allowed to assume this role. By specifying vpc-flow-logs.amazonaws.com as the principal, you are telling AWS that only the VPC Flow Logs service can use this role. No users or other services can assume it.
- Click Next.
- In the permissions search bar, type FlowLogsPolicy.
- Select the checkbox next to FlowLogsPolicy.
- Click Next.
- Enter FlowLogsRole in the Role name field.
- Click Create role.
You should see a confirmation that FlowLogsRole was created. You can click on the role name to verify that FlowLogsPolicy appears under the Permissions tab.
Can't find FlowLogsPolicy when attaching?
The search can take a moment to index new policies. Try clearing the search field and typing FlowLogsPolicy again. Make sure you are searching in the filter bar on the permissions page, not the main IAM search bar.
Help me attach my FlowLogsPolicy to my role.
Enable VPC Flow Logs on your VPC
With the IAM role ready, you can now enable flow logs on your VPC. Every connection attempt to any resource inside security-lab-vpc will be recorded and sent to a CloudWatch Logs log group.
- In the AWS Console search bar, type VPC and select VPC.
- In the left navigation pane, click Your VPCs.
- Select the checkbox next to security-lab-vpc.
- Click Actions, then select Create flow log.
- Set the Filter to All. This captures both accepted and rejected traffic.
- Set the Destination to Send to CloudWatch Logs.
- In the Destination log group field, enter security-lab-flow-logs. CloudWatch will create this log group automatically.
- In the IAM role dropdown, select FlowLogsRole.
Why capture all traffic?
Setting the filter to All captures both accepted connections (traffic your security group allowed) and rejected connections (traffic your firewall blocked). Seeing both sides is essential for a complete security investigation.
- Click Create flow log.
You should see a green success banner confirming the flow log was created. The flow log now appears in the Flow logs tab of your VPC details.
FlowLogsRole not appearing in the dropdown?
New IAM roles can take a minute to propagate. Try refreshing the page and checking the dropdown again. Make sure the role's trust policy uses vpc-flow-logs.amazonaws.com as the service principal. Roles with other trusted entities will not appear in this dropdown.
Help me connect my IAM role to my VPC flow log.
Search your flow log records in CloudWatch
Your flow log is now recording traffic, but the records take a few minutes to appear in CloudWatch. You need to generate some traffic first, then search for it.
- Switch to the browser tab with your web server's Security Investigation Lab page.
- Refresh the page 5-10 times to generate HTTP traffic to your server.
Why do I need to wait?
VPC Flow Logs can take several minutes (up to 10 minutes or more) to appear in CloudWatch Logs after creation. The log group itself is only created in CloudWatch once the first traffic records are delivered. If you do not see the log group right away, wait a few minutes and refresh.
- Wait 3-5 minutes for the flow log records to be delivered to CloudWatch.
- In the AWS Console search bar, type CloudWatch and select CloudWatch.
- In the left navigation pane, expand Logs and click Log groups.
- Click on the security-lab-flow-logs log group.
- Click Search log group.
- Paste the following filter pattern into the search field to find your HTTP traffic:
[version, accountid, interfaceid, srcaddr, dstaddr, srcport, dstport = 80, protocol, packets, bytes, start, end, action = ACCEPT, logstatus]
What does this filter pattern do?
This pattern maps each space-delimited field in a flow log record to a named variable. The 14 fields match the default flow log format: version, account ID, interface ID, source address, destination address, source port, destination port, protocol, packets, bytes, start time, end time, action, and log status.
By adding = 80 to dstport and = ACCEPT to action, you are filtering for only accepted HTTP traffic on port 80. Everything else is hidden from the results.
- Click Search (or press Enter).
Before you look at the results, what do you expect to see? Think about who has been connecting to your server on port 80.
You should see flow log records containing your own IP address as the source, with destination port 80 and action ACCEPT. These records confirm that your browser's HTTP requests reached the server and the security group allowed them through.
No records appearing?
- Flow logs can take up to 10 minutes to appear. Wait a few more minutes and try searching again.
- Make sure you are looking at the correct log group: security-lab-flow-logs.
- If the log group itself does not exist yet, go back and generate more traffic by refreshing your web page several more times, then wait.
Help me find my VPC flow log records.
Flow logs show you individual connections, but they cannot tell you whether your security group configuration actually follows security best practices. Next, you will set up AWS Config to automatically detect and flag that wide-open SSH rule as a compliance violation.
Enforce Governance with AWS Config
In the last step, you enabled VPC Flow Logs and investigated the traffic hitting your web server. You can now see exactly who connected, on which port, and whether the connection was accepted or rejected.
Flow logs are great for investigating individual connections. But they cannot tell you whether your security group configuration violates security best practices. You need automated governance that continuously evaluates your resources against compliance rules and flags violations without you having to manually inspect each one. That is exactly what AWS Config does.
In this step, get ready to:
- Set up AWS Config to record resources in your region.
- Add the restricted-ssh managed rule to detect insecure SSH configurations.
- Verify that the rule flags your open security group as non-compliant.
Set up AWS Config
AWS Config continuously records how your AWS resources are configured and evaluates those configurations against rules you define. Think of it as a compliance auditor that never sleeps.
Cost warning
AWS Config does not have a free tier. It charges $0.003 per configuration item recorded and $0.001 per rule evaluation. For this project with only a handful of resources, your total AWS Config cost will be well under $0.50.
Make sure to follow the cleanup instructions in the Before You Go section to stop AWS Config when you are done.
- In the AWS Management Console, search for Config in the top search bar and open the AWS Config console.
- Click 1-click setup.
What does 1-click setup do?
The 1-click setup automatically configures three things for you. It sets AWS Config to record all supported resource types in this region using continuous recording.
It creates an S3 bucket to store configuration snapshots. It also assigns the default AWS Config service-linked role, which has all the permissions Config needs to read your resources.
You are taken directly to the Review page because the defaults are already selected.
- Review the settings, then click Confirm to finish setting up AWS Config.
After a moment, the AWS Config dashboard loads. AWS Config is now recording configuration changes for all supported resources in your region.
Seeing an error about the recorder?
If you see a message saying the configuration recorder already exists, someone may have set up AWS Config in this region before. Navigate to Settings in the left sidebar and confirm that the recorder status shows recording is on.
If you are still stuck, help me troubleshoot my AWS Config setup.
Add the restricted-ssh managed rule
AWS Config comes with hundreds of managed rules that check for common misconfigurations. The restricted-ssh rule checks whether any security group allows SSH from 0.0.0.0/0 or ::/0 and flags it as NON_COMPLIANT.
- In the left navigation, click Rules.
- Click Add rule.
You land on the Specify rule type page.
- Type restricted-ssh in the search field to filter the list of managed rules.
- Select the restricted-ssh rule from the results.
- Click Next.
What is the restricted-ssh rule?
This managed rule has the identifier INCOMING_SSH_DISABLED. It checks every security group in your account and evaluates whether inbound SSH (port 22) is open to the entire internet.
This rule maps to real compliance frameworks including NIST 800-53 and PCI DSS. It is one of the most common rules cloud security teams deploy first.
You land on the Configure rule page.
- Leave all the defaults as they are. The rule name, evaluation mode, and trigger type are pre-configured.
- Click Next.
- On the Review and create page, review the settings and click Add rule.
The rule is now created. You should see restricted-ssh listed on the Rules page with a compliance status of Evaluating... while AWS Config checks your resources.
Don't see the rule listed?
Make sure you clicked Add rule on the Review and create page, not just Next. If the rule still does not appear, refresh the Rules page.
If you need more help, help me add the restricted-ssh rule in AWS Config.
Check the compliance status
AWS Config needs a few minutes to evaluate your resources against the new rule. The initial evaluation typically takes 1 to 3 minutes.
- Wait 1 to 3 minutes for the evaluation to complete.
- Refresh the Rules page until the compliance status changes from Evaluating... to a result.
Before you click into the rule, think about what you expect to see. Your security-lab-sg security group currently allows SSH from 0.0.0.0/0. Will the rule consider that compliant or non-compliant?
- Click on the restricted-ssh rule name to open its details.
The rule shows NON_COMPLIANT with your security-lab-sg security group listed as the non-compliant resource. AWS Config automatically detected the same misconfiguration you built on purpose in Step 2.
Why does this matter?
In a real environment, you could have hundreds of security groups across dozens of accounts. Manually checking each one for overpermissive SSH rules is not realistic.
AWS Config automates that inspection continuously. Every time a security group changes, the rule re-evaluates and flags anything that violates the policy. This is the foundation of cloud governance.
Still seeing Evaluating?
AWS Config initial evaluations can take up to 3 minutes. Keep refreshing the page every 30 seconds. Make sure the AWS Config recorder is running by checking Settings in the left navigation.
If the status still shows Evaluating after 5 minutes, help me troubleshoot my AWS Config rule evaluation.
Your security group misconfiguration is now officially flagged. Next up, you will fix the violation, re-evaluate the rule, and prove compliance from both a governance and monitoring perspective.
Remediate and Prove Compliance
Your AWS Config dashboard now shows the result every cloud security analyst dreads: a NON_COMPLIANT flag on your security group. You know exactly what caused it. SSH is open to the entire internet.
Finding the violation is only half the job. In this step, you will fix the misconfiguration, prove it passes the compliance check, and verify through flow logs that unauthorized SSH traffic is actually being blocked.
In this step, get ready to:
- Lock down the SSH inbound rule to allow only your IP address.
- Re-evaluate the AWS Config rule and confirm COMPLIANT status.
- Verify remediation through VPC Flow Logs by generating and observing REJECT entries.
Restrict SSH access to your IP address only
Right now, anyone on the internet can attempt an SSH connection to your server. The fix is simple: change the SSH rule so only your IP address is allowed.
- Return to the EC2 console by typing EC2 in the AWS Console search bar and selecting it.
- In the left sidebar under Network & Security, click Security Groups.
- Select security-lab-sg.
- Click the Inbound rules tab.
- Click Edit inbound rules.
- Find the SSH rule (port 22) with source 0.0.0.0/0.
- Click the Source dropdown for the SSH rule and select My IP.
- Click Save rules.
Why keep HTTP open?
Your web server needs to be publicly accessible for anyone to visit your site. The security concern was SSH, not HTTP.
Restricting SSH to My IP means only you can remotely manage the server. The HTTP rule (port 80) stays open to 0.0.0.0/0 so the public web page remains reachable.
- Open your EC2 instance's public IP in a new browser tab to confirm the web page still loads.
You should still see the "Security Investigation Lab" page. HTTP traffic is unaffected by your change.
Web page not loading?
- Make sure you only changed the SSH rule, not the HTTP rule. Go back to Edit inbound rules and confirm the HTTP rule (port 80) still has source 0.0.0.0/0.
- Confirm your EC2 instance is still in the Running state in the EC2 dashboard.
- help me debug why my web page stopped loading after editing my security group rules
Re-evaluate the Config rule and confirm compliance
Your security group is now locked down, but AWS Config still shows the old NON_COMPLIANT result from its last evaluation. You need to trigger a fresh evaluation so Config re-checks your updated rule.
- Return to the AWS Config console by typing Config in the AWS Console search bar and selecting it.
- Click Rules in the left sidebar.
- Select the restricted-ssh rule.
- Click Actions.
- Click Re-evaluate.
The evaluation takes 1-2 minutes to complete. Before you refresh the page, think about this: do you expect the rule to show COMPLIANT or NON_COMPLIANT now that SSH is no longer open to 0.0.0.0/0?
- Wait 1-2 minutes, then refresh the page.
The compliance status now shows COMPLIANT. Your security-lab-sg security group passes the check because SSH is restricted to your IP address only.
What just happened from a governance perspective?
The restricted-ssh rule (identifier: INCOMING_SSH_DISABLED) checks whether any security group allows SSH from 0.0.0.0/0 or ::/0. Since your SSH source is now a single IP address, the rule evaluates as COMPLIANT.
This is the detection-to-remediation workflow that GRC engineers and cloud security analysts perform daily. You detected the violation, fixed the configuration, and proved compliance through re-evaluation.
Still seeing NON_COMPLIANT?
- Confirm that you clicked Save rules after changing the SSH source. Go back to the EC2 security group and check the Inbound rules tab to verify the SSH source is no longer 0.0.0.0/0.
- Wait a full 2 minutes and refresh again. The re-evaluation can sometimes take longer than expected.
- help me figure out why my restricted-ssh rule still shows NON_COMPLIANT after changing SSH to My IP
Verify remediation in VPC Flow Logs
The governance side is proven. Now you need to verify from the monitoring side that your firewall is actually blocking unauthorized SSH traffic. You will use AWS CloudShell to attempt an SSH connection to your server and then look for the REJECT entry in your flow logs.
Why use CloudShell for this test?
CloudShell runs on AWS infrastructure, so it has a different IP address than your browser. When you restricted SSH to My IP, you allowed your browser's IP address. CloudShell's IP is not on that list, so the security group will block its SSH attempt. That blocked attempt is exactly the evidence you want in your flow logs.
- In the AWS Console, click the CloudShell icon in the top navigation bar to open a terminal session.
First time opening CloudShell?
CloudShell may take a moment to initialize the first time. Wait for the command prompt to appear before continuing.
- Attempt an SSH connection to your EC2 instance by running this command:
ssh -o ConnectTimeout=5 ec2-user@[[EC2_PUBLIC_IP="your EC2 instance public IP"]]
What does this command do?
- ssh tries to open a secure shell connection to your server.
- -o ConnectTimeout=5 tells SSH to give up after 5 seconds instead of hanging for the default timeout.
- ec2-user is the default username on Amazon Linux instances.
After about 5 seconds, the connection will fail with a timeout. This is exactly what you want. The security group blocked the attempt because CloudShell's IP address is not your allowed "My IP" address.
That failed connection just created a flow log record. Now you need to find it in CloudWatch Logs. Flow log records can take several minutes to appear, so give it 3-5 minutes before searching.
- Navigate to the CloudWatch console by typing CloudWatch in the AWS Console search bar and selecting it.
- In the left sidebar, expand Logs and click Log groups.
- Click the security-lab-flow-logs log group.
- Click Search log group.
Before you search, think about what you expect to find. Your SSH attempt was blocked by the security group. What action value should appear in the flow log record: ACCEPT or REJECT?
- Paste the following filter pattern into the search field to find rejected SSH traffic:
[version, accountid, interfaceid, srcaddr, dstaddr, srcport, dstport = 22, protocol, packets, bytes, start, end, action = REJECT, logstatus]
What does this filter pattern do?
This pattern matches flow log records where the destination port is 22 (SSH) and the action is REJECT. Compare it to the filter you used in the previous step, which searched for dstport = 80 and action = ACCEPT. Same structure, different values.
- Press Enter or click Run query to search.
You should see one or more records with REJECT on port 22. The source address in these records is the CloudShell IP that your security group blocked. Your firewall is doing its job.
No REJECT records showing up?
- Flow log records can take up to 10 minutes to appear. Wait a few more minutes, then click Run query again.
- Make sure you ran the ssh command in CloudShell and saw the connection timeout. If the command succeeded instead of timing out, your security group SSH rule may still be set to 0.0.0.0/0.
- Double-check that the filter pattern is pasted exactly as shown, with spaces around the = signs.
- help me find REJECT entries in my VPC Flow Logs for SSH traffic
Why does this matter for a security career?
You just completed the full investigation-to-remediation workflow. You detected a violation with AWS Config (governance), fixed the root cause in the security group, proved compliance through re-evaluation, and confirmed enforcement through VPC Flow Logs (monitoring).
This is the daily loop for cloud security analysts and GRC engineers. Governance tells you what should be true. Monitoring tells you what actually happened. Together, they prove your security posture.
Secret mission
Add a Second Compliance Rule
You've locked down SSH and proven compliance with one rule. But real cloud environments face multiple types of network misconfigurations at once. Can you add a second governance rule, intentionally trigger a new violation, and remediate it on your own?
Clean Up Your Resources
Clean Up Your Resources
This project uses AWS cloud resources that can incur small ongoing charges if left running. Decide whether to keep your resources running, pause them to come back later, or delete them entirely.
Cost warning
Your EC2 instance consumes free tier hours while running. AWS Config charges $0.003 per configuration item recorded and $0.001 per rule evaluation. VPC Flow Logs to CloudWatch incur vended log charges. If left running, these will accumulate small charges over time. Choose Pause or Delete below to stop ongoing costs.
Resources you used:
- 1 EC2 instance (free tier eligible).
- 1 VPC with subnet, internet gateway, and route table (no cost).
- 1 security group (security-lab-sg).
- 1 VPC Flow Log publishing to CloudWatch Logs (vended log charges).
- 1 CloudWatch Logs log group (security-lab-flow-logs).
- 1 IAM role and policy for flow logs.
- AWS Config recorder, delivery channel, S3 bucket, and 2 managed rules.
Keep everything running
No action needed. Choose this if you are still actively building or want to experiment with VPC Flow Logs and AWS Config rules further.
- Your EC2 instance will continue consuming free tier hours.
- AWS Config will continue recording configuration items and evaluating rules, accumulating small charges over time.
- VPC Flow Logs will continue publishing to CloudWatch Logs, incurring minimal vended log charges.
Pause - I'll come back to this later
Shut down running processes to free up free tier hours and stop ongoing Config charges. Your VPC and networking resources can remain without significant cost.
- In the EC2 console, select your instance, choose Instance state, then Stop instance. This preserves your instance but stops free tier hour consumption.
- In the AWS Config console, choose Rules in the left navigation. Select the restricted-ssh rule, choose Actions, then Delete rule. Type Delete to confirm. Repeat for the vpc-sg-port-restriction-check rule.
- In the AWS Config console, choose Settings. On the Customer managed recorder tab, choose Stop recording, then Confirm. This halts configuration item recording and stops ongoing Config charges.
- Your VPC, subnet, flow logs, and CloudWatch log group can remain without significant cost.
Delete - I don't want to use this again
Remove all project resources and start fresh. Follow these steps in order to avoid dependency errors.
Delete AWS Config rules and stop the recorder
- In the AWS Config console, choose Rules in the left navigation.
- Select the restricted-ssh rule, choose Actions, then Delete rule. Type Delete (case-sensitive) and choose Delete.
- Repeat for the vpc-sg-port-restriction-check rule.
- Choose Settings in the left navigation. On the Customer managed recorder tab, choose Stop recording, then Confirm.
Delete the Config recorder and delivery channel
Deleting the configuration recorder and delivery channel requires the AWS CLI. Open CloudShell from the AWS Console toolbar.
- Delete the configuration recorder by running:
aws configservice delete-configuration-recorder --configuration-recorder-name default
- Delete the delivery channel by running:
aws configservice delete-delivery-channel --delivery-channel-name default
Delete the Config S3 bucket
- Open the S3 console. Find the bucket that AWS Config created (it starts with config-bucket- followed by a number).
- Select the bucket, choose Empty, type permanently delete to confirm, and choose Empty.
- Select the now-empty bucket, choose Delete, type the bucket name to confirm, and choose Delete bucket.
Delete the VPC Flow Log and CloudWatch log group
- In the VPC console, choose Your VPCs in the navigation pane. Select security-lab-vpc.
- Choose the Flow logs tab. Select the flow log, choose Actions, then Delete flow logs. Type delete and choose Delete.
- Open the CloudWatch console. Choose Log groups in the left navigation.
- Select the security-lab-flow-logs log group, choose Actions, then Delete. Confirm the deletion.
Terminate the EC2 instance
- In the EC2 console, choose Instances in the left navigation.
- Select your instance, choose Instance state, then Terminate instance. Confirm the termination.
- Wait for the instance state to show Terminated before proceeding.
Delete the VPC and networking resources
The VPC console automatically deletes the subnet, route table, internet gateway, and security group when you delete the VPC, as long as the EC2 instance is terminated first.
- In the VPC console, choose Your VPCs in the navigation pane.
- Select security-lab-vpc, choose Actions, then Delete VPC.
- Review the list of resources that will be deleted (subnet, route table, internet gateway, security group). Type delete and choose Delete.
Delete the IAM role and policy
- Open the IAM console. Choose Roles in the left navigation.
- Search for your flow logs role (e.g. FlowLogsRole). Select it, then choose Delete. Type the role name to confirm and choose Delete.
- Choose Policies in the left navigation. Search for your flow logs policy (e.g. FlowLogsPolicy). Select it, choose Actions, then Delete. Type the policy name to confirm and choose Delete.
Nice Work!
Nice Work!
You just built a cloud security investigation and governance lab from scratch. You deployed a web server, monitored its traffic, caught a misconfiguration with automated compliance rules, and proved your fix worked.
You've learned how to:
- Build a custom VPC with a public subnet, internet gateway, and route table, then deploy a live web server on an EC2 instance with an intentionally overpermissive security group to simulate a real-world misconfiguration.
- Enable VPC Flow Logs to capture every network connection and investigate traffic records in CloudWatch Logs using filter patterns to find accepted and rejected traffic.
- Set up AWS Config with the restricted-ssh managed rule to automatically flag your open SSH security group as NON_COMPLIANT, then remediate the misconfiguration and prove compliance from both a governance and monitoring perspective.
- Secret Mission: Added a second compliance rule (vpc-sg-port-restriction-check) to catch additional network security violations and practiced the full detection-to-remediation workflow independently.
Ready to quiz yourself?