
Mein Titel ist vielleicht ungünstig formuliert, aber ich versuche, die Hintergrundgeschichte klarzustellen:
Ich habe Ubuntu-Instanzen mit Clustern von Docker-Containern, die alle Webserver hosten
Um Firewalls zu umgehen, möchten wir Port 443 statt Port 8000 verwenden (wo ein Dienst auf Datenverkehr wartet und die für die entsprechenden Container geöffneten Sockets verfolgt).
Zu diesem Zweck haben wir eine Regel hinzugefügt:
sudo iptables -t nat -D PREROUTING -p tcp --dport 443 -j REDIRECT --to-port 8000
Die Container verwenden jedoch Boto, um Inhalte an S3 zu senden, z. B. etwas wie:
from boto.s3.connection import S3Connection
s3_connection = S3Connection(
'AWS_KEY_ID',
'AWS_SECRET_KEY'
)
s3_bucket = s3_connection.get_bucket(
'AWS_BUCKET'
)
Mit der Vorrouting-Regel kann Boto Port 443 nicht mehr verwenden und gibt Folgendes zurück:
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
Ohne die Regel funktioniert Boto einwandfrei, aber wir können Port 8000 nicht für einen Produktions-SSL-Dienst verwenden.
Wie sollten wir unsere PREROUTING-Tabelle und unseren Dienst konfigurieren, um beides zu tun?
Ich bin kein Experte für Boto, Iptables oder Docker und es ist interessant, dass dies anscheinend ein Problem der Container und nicht des Hosts ist.
Antwort1
Ihre DNAT-Regel ist nicht spezifisch genug. Sie gilt füralleDatenverkehr, der über den Host an Port 443 weitergeleitet wird, unabhängig von Ursprung oder Ziel.
Um das Problem zu lösen, formulieren Sie die Regel spezifischer, indem Sie beispielsweise angeben, dass sie nur für eingehenden Datenverkehr von außen gilt. Wenn dieser über die eth0
Schnittstelle eintrifft, fügen Sie -i eth0
der Regel Folgendes hinzu:
sudo iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 443 -j REDIRECT --to-port 8000
Dies gilt nicht für den Datenverkehr in die andere Richtung, bei dem die „eingehende“ Schnittstelle zB docker0
und die „ausgehende“ Schnittstelle ist eth0
.