我的标题可能措辞不当,但我会尽力把背景故事讲清楚:
我有 Ubuntu 实例,其中包含托管 Web 服务器的 Docker 容器集群
为了安抚防火墙,我们希望使用端口 443 而不是端口 8000(服务正在监听流量并跟踪向相应容器打开的套接字)
为此,我们添加了一条规则:
sudo iptables -t nat -D PREROUTING -p tcp --dport 443 -j REDIRECT --to-port 8000
然而容器使用 boto 将内容推送到 s3,例如:
from boto.s3.connection import S3Connection
s3_connection = S3Connection(
'AWS_KEY_ID',
'AWS_SECRET_KEY'
)
s3_bucket = s3_connection.get_bucket(
'AWS_BUCKET'
)
实施预路由规则后,boto 不再能够使用端口 443 并返回:
Traceback (most recent call last):
File "<stdin>", line 2, in <module>
File "/usr/local/lib/python2.7/dist-packages/boto/s3/connection.py", line 496, in get_bucket
return self.head_bucket(bucket_name, headers=headers)
File "/usr/local/lib/python2.7/dist-packages/boto/s3/connection.py", line 543, in head_bucket
response.status, response.reason, body)
boto.exception.S3ResponseError: S3ResponseError: 405 Method Not Allowed
如果没有该规则,boto 也可以正常工作,但我们不能使用端口 8000 来进行生产 ssl 服务。
我们应该如何配置我们的 PREROUTING 表和服务来完成这两件事?
我不是 boto、iptables 或 docker 方面的专家,有趣的是,这似乎是容器而不是主机的问题。
答案1
您的 DNAT 规则不够具体。它适用于全部流量通过主机转发到端口 443,无论来源和目的地是什么。
要解决该问题,请使规则更加具体,例如指定它仅适用于来自外部世界的入站流量。如果该流量到达接口eth0
,则您需要-i eth0
在规则中添加:
sudo iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 443 -j REDIRECT --to-port 8000
这不适用于去往另一个方向的流量,其中“入站”接口例如为docker0
,“出站”接口为eth0
。