
Возможно, мой заголовок сформулирован неудачно, но я постараюсь рассказать предысторию прямо:
У меня есть экземпляры Ubuntu с кластерами контейнеров 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
Это не будет применяться к трафику, идущему в другом направлении, где «входящий» интерфейс — eg docker0
, а «исходящий» интерфейс — eth0
.