Connecting to an Instance via SSH
Once you launch a Linux EC2 (Elastic Compute Cloud, Amazon’s virtual server service) instance, the next thing you almost always want to do is log into it. The classic way is SSH (Secure Shell, an encrypted protocol for remote command-line access). To connect successfully you need three things lined up at the same time: the right private key, the right username, and a network path that actually reaches the machine on port 22. This page walks through each piece, then shows you how to quickly tell apart the two most common failures so you stop guessing.
What you need before connecting
SSH to an EC2 instance depends on four things working together:
| Ingredient | What it is | Where it comes from |
|---|---|---|
| Private key file | The .pem (or .ppk) file half of your key pair | Downloaded once when you created the key pair |
| Username | The default login user baked into the AMI | Depends on the OS image you launched |
| Reachable address | A public IP or DNS name the client can route to | The instance’s public IPv4 or an Elastic IP |
| Open port 22 | An inbound rule allowing TCP 22 from your IP | The instance’s security group |
If any one of these is wrong, the connection fails. The trick to debugging is knowing which one.
The basic SSH command
The command always follows the same shape: point at your key, give the username, then @ the address.
ssh -i ~/.ssh/my-key.pem [email protected]
-i ~/.ssh/my-key.pem— the identity file (your private key).ec2-user— the default username for Amazon Linux (more on this below).203.0.113.42— the instance’s public IPv4 address. You can also use the public DNS name likeec2-203-0-113-42.compute-1.amazonaws.com.
Output:
The authenticity of host '203.0.113.42 (203.0.113.42)' can't be established.
ED25519 key fingerprint is SHA256:V8mZ3...rT9k.
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
, #_
~\_ ####_ Amazon Linux 2023
~~ \_#####\
[ec2-user@ip-10-0-1-25 ~]$
Saying yes to the fingerprint prompt is normal the first time. SSH then remembers the host in ~/.ssh/known_hosts.
Key file permissions matter. SSH refuses to use a private key that other users on your machine can read. If you see
WARNING: UNPROTECTED PRIVATE KEY FILE, runchmod 400 ~/.ssh/my-key.pemto lock it down to read-only for you, then try again.
The right default username per AMI
EC2 does not let you log in as root directly. Each AMI (Amazon Machine Image, the OS template you boot from) ships with a specific default user that has sudo access. Using the wrong one is the single most common cause of “permission denied.”
| AMI / distribution | Default username |
|---|---|
| Amazon Linux 2 / 2023 | ec2-user |
| Ubuntu | ubuntu |
| RHEL (Red Hat Enterprise Linux) | ec2-user (older: root) |
| Debian | admin |
| CentOS | centos (or ec2-user) |
| SUSE | ec2-user |
| Fedora | fedora |
When in doubt, check the AMI’s documentation, or just try ec2-user first since it is the most common.
Allowing SSH in the security group
A security group is a virtual firewall attached to your instance. By default it blocks all inbound traffic, so you must add a rule that allows TCP port 22 from your IP address.
Using the AWS Management Console
- Open the EC2 console and go to Instances.
- Select your instance, then open the Security tab and click its security group (for example
sg-0a1b2c3d). - Choose Edit inbound rules, then Add rule.
- Set Type to
SSH(this auto-fills Protocol TCP and Port range 22). - For Source, choose My IP so AWS fills in your current public IP as a
/32range. Avoid0.0.0.0/0(the whole internet). - Click Save rules.
Using the AWS CLI
aws ec2 authorize-security-group-ingress \
--group-id sg-0a1b2c3d \
--protocol tcp \
--port 22 \
--cidr 198.51.100.10/32
Output:
{
"Return": true,
"SecurityGroupRules": [
{
"SecurityGroupRuleId": "sgr-0a1b2c3d4e5f",
"GroupId": "sg-0a1b2c3d",
"IsEgress": false,
"IpProtocol": "tcp",
"FromPort": 22,
"ToPort": 22,
"CidrIpv4": "198.51.100.10/32"
}
]
}
When NOT to open port 22 to the world. Restricting the source to your
/32IP dramatically shrinks your attack surface. If your IP changes often, prefer Session Manager instead, which needs no open SSH port at all. There is no extra cost for using Session Manager on standard instances.
Telling “timeout” apart from “permission denied”
These two errors look similar but have completely different causes. Reading the error message correctly saves you a lot of time.
Connection timeout — it’s a network problem
ssh: connect to host 203.0.113.42 port 22: Operation timed out
A timeout means your SSH client never even reached the instance. The conversation never started. This is almost always a network reachability issue, not a key or username issue. Check these, roughly in order:
- Security group — is there an inbound rule for TCP 22 from your current IP? Your home/office IP may have changed since you set it.
- Network ACL (NACL) — the subnet-level firewall. Unlike security groups, NACLs are stateless, so they need to allow both inbound 22 and outbound on the high ephemeral ports (1024-65535).
- Route table — the subnet must have a route to an internet gateway (
igw-...) for a public instance to be reachable from the internet. - Public IP — does the instance actually have a public IPv4 address? Instances in private subnets do not.
- Instance state — is it
runningand finished booting?
A quick way to confirm whether the port is open at all:
nc -vz 203.0.113.42 22
Output:
nc: connect to 203.0.113.42 port 22 (tcp) failed: Operation timed out
If nc times out, stop looking at your key. The problem is in the network layers above.
Permission denied — it’s a credentials problem
[email protected]: Permission denied (publickey).
This message means the network worked fine: you reached the SSH server and it talked back, but it rejected your login. The cause is one of:
- Wrong username — you used
ubuntuon an Amazon Linux box, or vice versa. - Wrong key — the
.pemyou passed with-iis not the key pair attached to this instance. - Bad key permissions — the file is too open, so SSH silently ignores it. Run
chmod 400.
A great diagnostic is verbose mode, which shows exactly which keys SSH offered:
ssh -v -i ~/.ssh/my-key.pem [email protected]
Output:
debug1: Offering public key: ~/.ssh/my-key.pem ED25519 SHA256:V8mZ3...
debug1: Authentications that can continue: publickey
debug1: No more authentication methods to try.
[email protected]: Permission denied (publickey).
Seeing the server respond at all confirms the network is fine and you should focus on key and username.
Best Practices
- Lock private keys with
chmod 400and never commit.pemfiles to version control. - Scope SSH inbound rules to your
/32IP, not0.0.0.0/0. - Prefer Session Manager over open SSH ports for production access; it needs no inbound rule and logs every session.
- Attach an Elastic IP if you need a stable address, since a default public IP changes every time you stop and start the instance.
- Read the error first: timeouts mean fix the network, “permission denied” means fix the username, key, or permissions.
- Use
ssh -vandnc -vzas your two go-to diagnostics before changing anything.