Set Up a Security Group for Web Traffic
Learn to configure an AWS security group for web traffic — define inbound rules, attach to instances, and avoid common pitfalls in this hands-on tutorial.
Focus: set up a security group for web traffic
You've launched your EC2 instance, connected via SSH, and installed a web server. But when you try to hit that public IP in a browser, the connection times out. You've checked the server config, restarted nginx a dozen times, and still nothing — the problem is almost certainly your security group. By default, AWS blocks all inbound traffic. This lesson shows you exactly how to set up a security group for web traffic so HTTP/HTTPS requests actually reach your instance, and how to avoid the common pitfalls that trip up beginners.
The problem this lesson solves
Your web server is running, but the outside world can't reach it. This is one of the most frustrating issues for new AWS users. The culprit: security groups act as a virtual firewall for your EC2 instances. When you launch an instance without explicitly allowing web traffic, AWS denies all inbound connections by default. That means port 22 (SSH) might be open for you to administer the server, but port 80 (HTTP) and port 443 (HTTPS) are silently dropped.
Think of it like a bouncer at a club: the default bouncer lets no one in. Your job is to tell the bouncer, "Let in anyone who wants to see the band (web traffic) on these specific doors (ports)." Without that instruction, your band plays to an empty room — no matter how good they are.
This lesson solves exactly that: you'll learn to define inbound rules that allow web traffic, attach the security group to your instance, and verify that your site is publicly accessible.
Core concept / mental model
A security group is a stateful virtual firewall that controls inbound and outbound traffic for one or more EC2 instances. Stateful means that if you allow an inbound request, the response is automatically allowed back out, regardless of outbound rules. You don't need to create a return rule for replies.
Key definitions: - Inbound rule: What traffic is allowed to reach your instance (e.g., HTTP on port 80 from anywhere). - Outbound rule: What traffic your instance is allowed to send (default: all allowed). - Source: Where the inbound traffic comes from, defined by IP address ranges, security group IDs, or prefixes. - Protocol & port range: The specific service you're opening (e.g., TCP on port 443 for HTTPS).
Mental model: Imagine your EC2 instance is a house. The security group is the door lock. You can choose which doors (ports) are unlocked, and who has the key (source IPs). By default, all doors are locked. To let web visitors in, you unlock the front door (port 80) and the side door (port 443) for everyone (source 0.0.0.0/0).
Important: Security groups are allow-only. There's no way to explicitly deny traffic — you just don't add an allow rule. Also, a single security group can be attached to many instances, and one instance can have multiple security groups. Rules are evaluated together, so if any group allows the traffic, it's permitted.
How it works step by step
The process of setting up a security group for web traffic follows a logical flow. Here's the high-level sequence:
- Decide which traffic to allow: Typically HTTP (port 80) and HTTPS (port 443). For a basic tutorial, you might only need HTTP.
- Create a security group (or edit an existing one) with a clear name like
web-traffic-sgand a description. - Add inbound rules to the group specifying protocol, port, and source (often
0.0.0.0/0for public web traffic). - Attach the security group to your EC2 instance during launch or by modifying the instance's network settings.
- Verify by accessing your instance's public IP in a browser or using
curl.
The cause-and-effect relationship: Adding a rule tells the AWS network layer to forward packets that match the rule to your instance. Without a rule, packets are discarded before they reach your server — that's why the server appears unreachable even though it's running.
Hands-on walkthrough
Let's put this into practice. We'll do it two ways: through the AWS Management Console (GUI) and via the AWS CLI (faster for automation).
Step 1: Identify your instance
In the AWS Console, go to EC2 > Instances. Note the Instance ID (e.g., i-0123456789abcdef0) and its Public IPv4 address.
Step 2: Create a security group for web traffic
Using the CLI, create a security group with a clear name:
aws ec2 create-security-group \
--group-name web-traffic-sg \
--description "Allows HTTP/HTTPS from anywhere" \
--vpc-id vpc-0123456789abcdef0
Replace the VPC ID with your instance's VPC. You can find it in the instance description or via aws ec2 describe-instances. The command returns a GroupId — save it.
Step 3: Add inbound rules
Now add rules to allow HTTP and HTTPS:
aws ec2 authorize-security-group-ingress \
--group-id sg-0123456789abcdef0 \
--ip-permissions \
IpProtocol=tcp,FromPort=80,ToPort=80,IpRanges=[{CidrIp=0.0.0.0/0,Description="HTTP from anywhere"}] \
IpProtocol=tcp,FromPort=443,ToPort=443,IpRanges=[{CidrIp=0.0.0.0/0,Description="HTTPS from anywhere"}]
Expected output: No output if successful. Check with:
aws ec2 describe-security-groups --group-id sg-0123456789abcdef0
The output shows your security group with the two inbound rules listed.
Step 4: Attach the security group to your instance
Getting the security group attached is critical. You can do it during launch, but for an existing instance, you have two options:
Option A (Console): Go to your instance, click Actions > Security > Change security groups, then select your new group and remove any others if desired.
Option B (CLI): Modify the instance's security groups. However, there's no direct modify-instance-attribute for security groups. Instead, you must detach and attach via network interfaces:
aws ec2 modify-network-interface-attribute \
--network-interface-id eni-0123456789abcdef0 \
--groups sg-0123456789abcdef0
Get the network interface ID from the instance description (or use the console).
Step 5: Verify
SSH into your instance (if needed) and confirm web traffic is allowed:
curl -I http://YOUR_PUBLIC_IP
If you have a web server running, you'll see HTTP/1.1 200 OK. If you get curl: (7) Failed to connect, the security group might not be attached, or a rule is missing.
Compare options / when to choose what
You have a few ways to set up a security group. Here's a comparison to help you choose:
| Method | Pros | Cons | Best for |
|---|---|---|---|
| AWS Console | Visual, easy for beginners | Click-heavy, hard to automate | One-off setups, learning |
| AWS CLI | Scriptable, precise, versionable | Requires AWS CLI configured | Automation, repeatable deployments |
| Infrastructure as Code (Terraform, CloudFormation) | Reproducible, reviewable | Learning curve | Production environments, teams |
| Default VPC security group | Already exists, easy to edit | May conflict with other resources | Quick tests, but not recommended for real projects |
When to choose what: - For a single test instance, use the Console. - For reproducibility, use the CLI once and keep the command in a script. - For production, use IaC so changes are tracked and reviewed.
Also consider: do you need to restrict web traffic to specific IPs? For a public website, 0.0.0.0/0 is standard, but for a staging server, restrict to your office IP (e.g., 203.0.113.5/32). For internal services, reference another security group as the source instead of CIDR.
Troubleshooting & edge cases
Common errors and fixes
- Connection still times out after adding rules
- Verify the security group is actually attached to the instance: check the instance's
Security groupscolumn in the console. - Confirm the rule uses TCP protocol, not UDP, for web traffic. - Ensure the server itself is listening on the correct port:sudo netstat -tulpn | grep :80. - Check if the instance has a firewall like ufw that's blocking traffic independently:sudo ufw status. - Accidentally locked yourself out of SSH - If you type the wrong CIDR and remove SSH access, you may be unable to connect. Use the console to re-add SSH rule (port 22) from your current IP.
- Rule added to the wrong security group - If you have multiple security groups, you may have edited one that's not attached. Double-check the group ID.
Edge cases
- Multiple security groups: If an instance has multiple groups, inbound traffic is allowed if any group allows it. So a restrictive group doesn't override a permissive one — the permissive one wins.
- Empty source for IPv6: For IPv6 web traffic, add a separate rule with source
::/0. - Security group as source: You can allow traffic only from instances with a particular security group (e.g., allow a load balancer to talk to your app). This is more secure than IP ranges.
Debugging flow
If your site isn't accessible, follow this order:
- Try
curlfrom a different network (e.g., your phone on cellular) to rule out local network issues. - Use
ping(ICMP) — if it times out, likely security group or network ACL blocks it. (Note: ICMP is often disabled by default; enable it intentionally for testing.) - Check security group rules in the console — are your port 80/443 rules present?
- Check if the instance is stopped or terminated — obviously, no traffic.
What you learned & what's next
You've now mastered set up a security group for web traffic. You understand the core concept (a stateful allow-only firewall), you can apply it step-by-step in the console or CLI, you know how to compare different setup methods, and you can troubleshoot common issues. You even know how to attach the group to an instance and verify with curl.
This knowledge directly supports your goal of running a public-facing web server on EC2. Next in the AWS Tutorial track, you'll likely explore elastic IPs for stable public IPs, or load balancers to distribute traffic — both of which rely on proper security group configuration. You now have the foundation to follow those lessons confidently.
Keep your security groups as restrictive as possible, and always document why each rule exists. Now go make your web app publicly accessible!
Practice recap
Now try it yourself: Create a new security group, add an inbound rule for HTTP (port 80) from 0.0.0.0/0, and attach it to a running EC2 instance with a simple web server (like sudo python3 -m http.server 80). Then visit the instance's public IP in a browser to see the directory listing — this confirms your security group works. For bonus practice, restrict the rule to your own IP address and observe how the site becomes unreachable from other networks.
Common mistakes
- Adding a rule to a security group that isn't attached to the instance — check the instance's Security groups column to confirm.
- Using the wrong protocol (e.g., UDP instead of TCP) for HTTP/HTTPS rules — web traffic is always TCP.
- Forgetting to allow both IPv4 and IPv6 if you use dual-stack subnets — add separate rules with
0.0.0.0/0and::/0. - Locking yourself out by removing the SSH rule (port 22) from the default group — always keep a remote-access rule from your IP.
- Assuming the security group is the only firewall — the instance's OS firewall (like ufw) can still block traffic.
Variations
- Use AWS CloudFormation or Terraform to define security group rules as code for reproducible infrastructure.
- Harness the console's 'Edit inbound rules' feature to add web traffic rules without recreating a security group.
- Employ a security group as a source (instead of an IP range) to restrict access to specific instances like a load balancer.
Real-world use cases
- Allow public HTTP/HTTPS traffic to a company website hosted on a single EC2 instance behind an internet-facing load balancer.
- Expose a REST API on port 443 to external clients, while restricting SSH access to a corporate VPN IP range.
- Enable web traffic for a staging environment by allowing only your office's static IP via a CIDR-based rule.
Key takeaways
- Security groups are stateful, allow-only virtual firewalls — no explicit deny rules, and replies are automatically let back out.
- The default security group denies all inbound traffic; you must explicitly allow HTTP (80) and HTTPS (443) to make a web server publicly reachable.
- A security group can be attached to multiple instances, and multiple groups can be attached to one instance — any allow rule wins.
- You can set up a security group via console, CLI, or infrastructure as code — choose CLI for automation and IaC for production.
- When troubleshooting, check that the security group is attached, uses TCP protocol, and the instance's OS firewall is also configured.
Keep learning
Related tutorials, quizzes, and articles for this topic.
Discussion
Questions, corrections, and tips help everyone reading this page.
0 comments
Add a comment
No comments yet — start the thread.