如何配置直接访问EC2实例的HTTP访问?

24

这是一个非常基础的Amazon EC2问题,但我却被卡住了。

我想启动一个Amazon EC2实例,并允许从任何地方通过80和8888端口访问HTTP。到目前为止,我甚至不能允许该实例使用其自己的IP地址连接到这些端口(但它可以连接到localhost)。

我使用管理控制台上的标准HTTP选项(以及SSH)配置了HTTP的“默认”安全组。

我在默认安全组中启动了我的实例。

我通过SSH端口22两次连接到实例,在一个窗口中在端口80上启动HTTP服务器。在另一个窗口中,我验证了我可以使用“localhost”连接到HTTP。

但是当我尝试使用公共DNS或私有IP地址从实例(或任何其他地方)访问HTTP时,我得到“connection refused”的错误。

请问我做错了什么?

以下是控制台片段,显示从实例本身运行的成功和失败的wget。

--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个回答

22
标准的TCP套接字接口要求你在发送或监听时绑定到一个特定的IP地址。有一些比较特殊的地址:localhost(可能是你熟悉的)是127.0.0.1。还有一个特殊的地址,0.0.0.0或INADDR_ANY(互联网协议,代表任何地址的特殊简写)。它是监听主机上的所有地址或更常见的情况下,所有地址的一种方式。这是告诉内核/堆栈,你对特定的IP地址不感兴趣的一种方式。
因此,当你设置一个服务器来监听"localhost"时,你正在告诉服务你想要使用特殊保留的地址,该地址只能被此主机的用户访问,并且虽然它存在于每个主机上,但连接到localhost将只会到达你发出请求的主机。
当你希望某个服务在任何地方都可以访问(在本地主机、所有接口上等)时,可以指定0.0.0.0。

补充彼得的答案,您可能需要编辑 /etc/jetty/jetty.xml 上的以下行:<Set name="host"><SystemProperty name="jetty.host" />0.0.0.0</Set> - douglaslps

22

(0) 首要的事情是确保你的网络服务器正在运行。

(1) 你需要编辑你的安全组,允许传入的HTTP数据包访问你的网站。如果你的网站监听的是80端口,那么就要像上面提到的一样编辑安全组,开放对80端口的访问。如果你的网站监听的是其他端口,那么就要编辑安全组以访问该端口。

(2) 如果你正在运行Linux实例,则iptables防火墙可能会默认运行。你可以通过在命令行中运行sudo service iptables status来检查此防火墙是否处于活动状态。如果输出结果,则表示iptables防火墙正在运行。如果出现消息“防火墙未运行”,那么这就很清楚了。总的来说,iptables防火墙通常是默认运行的。

你有两个选择:绕过防火墙或编辑防火墙的配置以允许HTTP流量通过。我选择了绕过防火墙作为更简单的选项(对我而言)。

sudo service iptables stop

关闭iptables并不会造成真正的安全风险,因为iptables(如果处于活动状态)只是复制Amazon的防火墙功能,而后者是使用安全组生成其配置文件的。我们在这里假定Amazon AWS不会误配置其防火墙——这是一个非常安全的假设。

(3) 现在,你可以从浏览器中访问URL了。

(4) Microsoft Windows服务器也默认运行其个人防火墙,你需要修复Windows服务器的个人防火墙。

更正:根据AWS的默认设置,在订购新的EC2实例时,AWS不会启动服务器防火墙,例如CentOS中的iptables或Ubuntu中的UAF。这就是为什么在同一VPC中的EC2实例可以ssh到彼此,并且你可以从同一VPC中的另一个EC2实例中“看到”你启动的Web服务器。

确保你的RESTful API正在所有接口上监听,即0.0.0.0:portID


我忘记检查我的iptables配置...在阅读了您的答案后,我检查了我的规则,发现有一条规则将80端口的数据包重定向到3000端口,这就是它无法正常工作的原因。 - Chittolina

6
由于您遇到了连接被拒绝(数据包被拒绝),我猜测是iptables引起的问题。请尝试运行以下命令并测试连接:

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

您还需要将这些规则永久添加,如果您正在运行Red Hat,则可以通过将上述命令添加到例如/etc/sysconfig/iptables中来实现。


4

显然我绑定了“本地主机”,而我需要绑定到0.0.0.0以响应所有传入的TCP接口(?)的80端口。这是TCP/IP的一个微妙之处,我尚未完全理解,但它解决了问题。


1
默认情况下,这是AWS的默认设置,绑定仅限于本地主机接口,即内核内部。因此,如果您尝试从外部IP访问该端口,则无法获取任何内容,因为服务器未侦听任何外部接口。 - Vietnhi Phuvan
如何将端口绑定到0.0.0.0? - mrid

0

需要执行以下操作:

1)在实例配置中启用HTTP访问,因为默认情况下只有SSH 2)尝试使用nodejs服务器,因此端口绑定到80 -> 3000,执行以下命令以解决问题

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

0

亚马逊支持回答并立即解决了问题:

我在测试Ubuntu实例上复制了该问题,并成功解决了它。问题是,在Ubuntu / Unix上运行Tomcat在低于1024的端口上,服务需要root权限,但通常不建议使用root权限在端口80上运行进程,这是一种不必要的安全风险。

我们建议使用iptables进行端口重定向:

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

希望以上信息有所帮助。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接