33
votes

I created a micro ec2 instance. Installed all the necessary web software, mysql and git. Created an AMI out of that instance. Since that instance was using EBS as its root device, it took an EBS snapshot as well when I was creating my AMI.

I terminated that running instance. I then tried creating an instance out that amazon machine image (AMI), the new instance started along with a new EBS volume getting attached to the instance.

Now when I use my key pair to login to that instance via my ssh key to its public DNS address with a command as

ssh -i aws/mykey.pem ubuntu@thepublicdnsname

it says

ssh: connect to host <thepublickdnsname> port 22: Connection refused

Why is this happening. I was able to connect to my first instance with the same keys via ssh. Now the new instance is the exact copy and im not able to login to it. Any help on this ... ? Am I missing something?

I used the same key pairs to create the second new instance from the AMI.

9
did you check the 'console output' ?Ryan Fernandes
no. i have to check it. but whats the difference if i cannot login normally through my terminalAnand
@Anand What was the issue with this? How did you fix it? I'm facing this same issue. The security group attached with my instance does allow inbound SSH connections.Waseem

9 Answers

19
votes

I found that it takes variable amount of time for an EC2 instance to come up and get initialized. One is the time between calling ec2-run-instances till the instance state changes from "pending" to "running". After that there is additional time when ssh server becomes ready. That time can be a couple of minutes.

13
votes

I had the same issue: my problem was that I had a volume attached to my instance, then I detached the volume and deleted it. I followed aws docs to mount my instance and edited /etc/fstab. This was the problem: when the volume is detached and you try to reboot (or stop and start) the instance it goes to this file and tries to attach the nonexistent volume and ssh daemon is not started.

The solution is: I had to create another instance, detach the volume from problematic instance then edit the mounted_point/etc/fstab file to comment the line where its trying to mount the nonexistent instance, the reattach volume to problematic instance and then it worked everything fine.

6
votes

This is probably not the answer to the original question, but as this is at the top of Google for connection issues to EC2, be sure to configure your security group to allow SSH2 from your machine as per:

http://docs.amazonwebservices.com/AWSEC2/latest/UserGuide/AccessingInstances.html#authorizing-access-to-an-instance

4
votes

AWS takes time to bring up an instance from AMI. If you try to connect too quickly, and too frequently, the box can't respond. The full script below launches an AMI, determines IP address, and waits until the system is ready to connect. It would work very well for spot instances close to or below current pricing, as the time required to connect can vary widely.

The following loop caused a connection refused error, when the sleep statement was commented out, and it began too quickly after the instance started. It also consumed alot of CPU on the script server, and made huge error logs.

   `nc -z $ip_address -w 20 22` 1>/dev/null 2>&1; result=$?;
    while [ $result -eq 1 ]
      do
      #echo $ip_address booting
      `nc -z $ip_address -w 30 22` 1>/dev/null 2>&1; result=$?;
      sleep 30
    done

Here is a complete script to start an instance, tag it, wait for it to boot fully, and connect.

 instance_id=$(aws ec2 run-instances --region us-east-1 --count 1 --instance-type $AMItype --image-id $ami --security-group-ids $sg_group --output text --query 'Instances[*].InstanceId' )

 aws ec2 create-tags --resources $instance_id --tags "Key=Name, Value=$AMIname
 #delay until AWS says instance is running
 start_state=0
 while [ $start_state -ne 16 ]
        do
         start_state=$(aws ec2 start-instances --instance-ids $instance_id --query 'StartingInstances[*].PreviousState[*].Code[*]' )
         start_state=$(echo $start_state | tr -d '" []')
         sleep 10
 done
 ip_address=$(aws ec2 describe-instances --instance-ids $instance_id --output text --query 'Reservations[*].Instances[*].PrivateIpAddress')

 `nc -z $ip_address -w 20 22` 1>/dev/null 2>&1; result=$?;
        while [ $result -eq 1 ]
          do
           #waiting for routing updates and connectivity
           `nc -z $ip_address -w 30 22` 1>/dev/null 2>&1; result=$?;
           sleep 30
        done
3
votes

Another potential cause for a connection refused port 22 error is misspelling the public dns name. For example, part of mine contained .compute. and I put .computer. and it gave me a port 22 error instead of something more sensible like the host does not exist.

2
votes

Did you check ip address of the instance? Mine changes every time I run it, unless I chose fixed ip.

0
votes

I had a different (and honestly very silly) issue. Posting this answer here in case it helps someone else.

As part of my debugging I launched a couple of new instances and none of them could connect so I just rebooted my machine!

It works now! :D


0
votes

I encountered similar issue, I noticed the instance was created with virtualization of paravirtual and after recrerating with hvm the issue was resolved.

0
votes

I was having trouble accessing my instance from the internet even though I had all the right security groups, port rules, etc.

The solution was simply to go to the "instances" tab and reboot my instance. A couple minutes later when I retried accessing it from a browser, everything worked as expected.

Somehow, the security changes I made weren't applied until I rebooted the instance.