When I launched my first Amazon EC2 instance, everything looked fine in the AWS Console.
- Instance state: Running
- System status checks: Passed
- Public IP assigned: Yes
But when I tried to connect:
- SSH → Timeout
- Browser → Connection refused
At first, this felt confusing. If the instance is running, why can’t I access it?
This post explains why this happens, what I misunderstood, and how I fixed it.
The Problem
I faced two common symptoms:
1. SSH Access Failed
ssh ec2-user@192.168.1.0
Result:
- Connection timed out
- Or connection refused
2. Web App Not Opening
- Browser showed "This site can’t be reached" Despite the EC2 instance being healthy, network access was blocked. The Key Realization Running EC2 ≠ Accessible EC2
AWS separates:
- Compute (EC2 instance)
- Network security (Security Groups + NACLs)
- Networking (Public vs Private IP)
If any one of these is misconfigured, access will fail.
Security Groups vs NACLs (Most Common Confusion)
Security Groups
- Act as a virtual firewall
- Work at the instance level
- Are stateful (responses are automatically allowed)
If inbound traffic is not explicitly allowed → access denied.
Network ACLs (NACLs)
- wOrk at the subnet level
- Are stateless
- Require both inbound and outbound rules. Even if your Security Group is correct, a restrictive NACL can still block traffic. Required Ports Explained Depending on your use case, these ports must be open:
| Use Case | Port | Protocol |
|---|---|---|
| SSH | 22 | TCP |
| HTTP | 80 | TCP |
| HTTPS | 443 | TCP |
Missing even one required port = connection failure
Public IP vs Private IP (Critical Detail)
Public IP
- Required to access EC2 from the internet
Changes when instance is stopped/started (unless Elastic IP is used)
Private IPWorks only inside the VPC
Not accessible from your local machine
If you use a private IP from your laptop, the connection will never work.
The Fix: Security Group Configuration
My issue was missing inbound rules in the Security Group.
Example: Allow SSH Access (Port 22)
{
"IpProtocol": "tcp",
"FromPort": 22,
"ToPort": 22,
"IpRanges": [
{
"CidrIp": "0.0.0.0/0",
"Description": "Allow SSH access"
}
]
}
Example: Allow HTTP Access (Port 80)
{
"IpProtocol": "tcp",
"FromPort": 80,
"ToPort": 80,
"IpRanges": [
{
"CidrIp": "0.0.0.0/0",
"Description": "Allow HTTP traffic"
}
]
}
For production, never keep SSH open to 0.0.0.0/0. Restrict it to your IP.
What I Checked Step-by-Step
- EC2 instance state → Running
- Public IP assigned → Yes
- Security Group inbound rules → Missing
- NACL rules → Allowed
- Correct username used (ec2-user, ubuntu, etc.)
- Correct key permissions (chmod 400)
After fixing the Security Group, SSH worked instantly.
Key Takeaways
- EC2 running status only confirms compute availability
- Network access depends on Security Groups + NACLs
- Security Groups must explicitly allow required ports
- Public IP is mandatory for internet access
- AWS prioritizes security over convenience
Final Thoughts
This issue taught me how layered AWS security really is.
Instead of assuming something is broken, it’s better to trace the request path:
Client → Internet → Security Group → NACL → EC2
Once I understood this flow, debugging became much easier.
If you’re learning AWS, trust me everyone hits this problem at least once.
Top comments (1)
Nice