23
votes

This is a very basic Amazon EC2 question, but I'm stumped so here goes.

I want to launch an Amazon EC2 instance and allow access to HTTP on ports 80 and 8888 from anywhere. So far I can't even allow the instance to connect to on those ports using its own IP address (but it will connect to localhost).

I configured the "default" security group for HTTP using the standard HTTP option on the management console (and also SSH).

I launched my instance in the default security group.

I connected to the instance on SSH port 22 twice and in one window launch an HTTP server on port 80. In the other window I verify that I can connect to HTTP using the "localhost".

However when I try to access HTTP from the instance (or anywhere else) using either the public DNS or the Private IP address I het "connection refused".

What am I doing wrong, please?

Below is a console fragment showing the wget that succeeds and the two that fail run from the instance itself.

--2012-03-07 15:43:31--  http://localhost/
Resolving localhost... 127.0.0.1
Connecting to localhost|127.0.0.1|:80... connected.
HTTP request sent, awaiting response... 302 Moved Temporarily
Location: /__whiff_directory_listing__ [following]
--2012-03-07 15:43:31--  http://localhost/__whiff_directory_listing__
Connecting to localhost|127.0.0.1|:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: unspecified [text/html]
Saving to: “__whiff_directory_listing__”

[ <=>
                                                                                                               ] 7,512       --.-K/s   in 0.03s   

2012-03-07 15:43:31 (263 KB/s) - “__whiff_directory_listing__” saved [7512]

[ec2-user@ip-10-195-205-30 tmp]$ wget http://ec2-50-17-2-174.compute-1.amazonaws.com/
--2012-03-07 15:44:17--  http://ec2-50-17-2-174.compute-1.amazonaws.com/
Resolving ec2-50-17-2-174.compute-1.amazonaws.com... 10.195.205.30
Connecting to ec2-50-17-2-174.compute-1.amazonaws.com|10.195.205.30|:80... failed:          
Connection refused.
[ec2-user@ip-10-195-205-30 tmp]$ wget http://10.195.205.30/
--2012-03-07 15:46:08--  http://10.195.205.30/
Connecting to 10.195.205.30:80... failed: Connection refused.
[ec2-user@ip-10-195-205-30 tmp]$ 
6

6 Answers

22
votes

(0) It's silly but the first thing you need to do is to make sure that your web server is running.

(1) You need to edit your Security Group to let incoming HTTP packets access your website. If your website is listening on port 80, you need to edit the Security Group to open access to port 80 as mentioned above. If your website is listening on some other port, then you need to edit the Security Group to access that other port.

(2) If you are running a Linux instance, the iptables firewall may be running by default. You can check that this firewall is active by running

sudo service iptables status

on the command line. If you get output, then the iptables firewall is running. If you get a message "Firewall not running", that's pretty self-explanatory. In general, the iptables firewall is running by default.

You have two options: knock out the firewall or edit the firewall's configuration to let HTTP traffic through. I opted to knock out the firewall as the simpler option (for me).

sudo service iptables stop

There is no real security risk in shutting down iptables because iptables, if active, merely duplicates the functionality of Amazon's firewall, which is using the Security Group to generate its configuration file. We are assuming here that Amazon AWS doesn't misconfigure its firewalls - a very safe assumption.

(3) Now, you can access the URL from your browser.

(4) The Microsoft Windows Servers also run their personal firewalls by default and you'll need to fix the Windows Server's personal firewall, too.

Correction: by AWS default, AWS does not fire up server firewalls such iptables (Centos) or UAF (Ubuntu) when you are ordering the creation of new EC2 instances - That's why EC2 instances that are in the same VPC can ssh into each other and you can "see" the web server that you fired up from another EC2 instance in the same VPC.

Just make sure that your RESTful API is listening on all interfaces i.e. 0.0.0.0:portID

21
votes

The standard tcp sockets interface requires that you bind to a particular IP address when you send or listen. There are a couple of somewhat special addresses: localhost (which you're probably familiar with) which is 127.0.0.1. There's also a special address, 0.0.0.0 or INADDR_ANY (internet protocol, special shorthand for ANY ADDRESS). It's a way to listen on ANY or more commonly, ALL addresses on the host. This is a way to tell the kernel/stack that you're not interested in a particular IP address.

So, when you're setting up a server that listens to "localhost" you're telling the service that you want to use the special reserved address that can only be reached by users of this host, and while it exists on every host, making a connection to localhost will only ever reach the host you're making the request from.

When you want a service to be reachable everywhere (on a local host, on all interfaces, etc.) you can specify 0.0.0.0.

5
votes

As you are getting connection refused (packets are being rejected) I bet it is iptables causing the problem. Try to run

iptables -I INPUT -p tcp --dport 80 -j ACCEPT
iptables -I INPUT -p tcp --dport 8888 -j ACCEPT

and test the connection.

You will also need to add those rules permanently which you can do by adding the above lines into ie. /etc/sysconfig/iptables if you are running Red Hat.

4
votes

Apparently I was "binding to localhost" whereas I needed to bind to 0.0.0.0 to respond to port 80 for the all incoming TCP interfaces (?). This is a subtlety of TCP/IP that I don't fully understand yet, but it fixed the problem.

0
votes

Had to do the following:

1) Enable HTTP access on the instance config, it wasn't on by default only SSH 2) Tried to do nodejs server, so port was bound to 80 -> 3000 did the following commands to fix that

iptables -F
iptables -I INPUT -p tcp --dport 80 -j ACCEPT
sudo service iptables-persistent flush
0
votes

Amazon support answered it and it worked instantly:

I replicated the issue on my end on a test Ubuntu instance and was able to solve it. The issue was that in order to run Tomcat on a port below 1024 in Ubuntu/Unix, the service needs root privileges which is generally not recommended as running a process on port 80 with root privileges is an unnecessary security risk.

What we recommend is to use a port redirection via iptables :-

iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 80 -j REDIRECT --to-port 8080

I hope the above information helps.