ubuntuusers.de

iptables mit prerouting und docker

Status: Gelöst | Ubuntu-Version: Ubuntu 14.04 (Trusty Tahr)
Antworten |

robg336699

Anmeldungsdatum:
4. Mai 2017

Beiträge: Zähle...

Hallo,

ich habe einen Docker Container und einen Applicationserver auf der gleichen Maschine. Der Applicationserver verwendet PREROUTING in iptables.

1
2
-A PREROUTING -p tcp -m tcp --dport 80 -j REDIRECT --to-ports 8080
-A PREROUTING -p tcp -m tcp --dport 443 -j REDIRECT --to-ports 8081

Dies führt jedoch dazu, dass man im Docker-Container keine Webseite mehr aufrufen kann, weil die Pakete ja schon vorher umgeleitet werden.

Kann mir jemand sagen, wie man das beheben kann?

Danke,

Robert

misterunknown Team-Icon

Ehemalige
Avatar von misterunknown

Anmeldungsdatum:
28. Oktober 2009

Beiträge: 4403

Wohnort: Sachsen

robg336699 schrieb:

ich habe einen Docker Container und einen Applicationserver auf der gleichen Maschine. Der Applicationserver verwendet PREROUTING in iptables.

1
2
-A PREROUTING -p tcp -m tcp --dport 80 -j REDIRECT --to-ports 8080
-A PREROUTING -p tcp -m tcp --dport 443 -j REDIRECT --to-ports 8081

Das ist ungünstig, wenn noch andere Sachen auf den Ports 80 und 443 laufen sollen. Besser wäre einen Proxy-VHost für die Ports zu verwenden. Ein weiterer Proxy-VHost könnte die Docker-Applikation nach außen erreichbar machen.

Dies führt jedoch dazu, dass man im Docker-Container keine Webseite mehr aufrufen kann, weil die Pakete ja schon vorher umgeleitet werden.

Kann mir jemand sagen, wie man das beheben kann?

Ja, das ist aber abhängig davon, was du genau machen willst, und wie genau dein Netzwerksetup ist.

robg336699

(Themenstarter)

Anmeldungsdatum:
4. Mai 2017

Beiträge: 4

Also eigentlich läuft nur der App-Server auf Port 80 und 443. Das andere ist ja ein Browser im Docker Container der nur die Antwort auf den eigenen Request erhalten soll. Docker verwendet hierzu masquerading. Bei der Antwort kommt das Prerouting aber vor dem masquerading und deshalb wird eine ankommende Antwort fälschlicher Weise zum AppServer umgeleitet, statt zurück in den Docker Container.

Kann man das nicht in den iptables konfigurieren, dass das Prerouting nur die Requests routet, die nicht masqueraded sind?

Danke!

misterunknown Team-Icon

Ehemalige
Avatar von misterunknown

Anmeldungsdatum:
28. Oktober 2009

Beiträge: 4403

Wohnort: Sachsen

robg336699 schrieb:

Also eigentlich läuft nur der App-Server auf Port 80 und 443.

Ja, aber auf welcher IP? Die PRETOUTING-Regeln spezifizieren keine IP, daher wird alles umgeleitet, was so ja offenbar nicht gewollt ist.

Das andere ist ja ein Browser im Docker Container der nur die Antwort auf den eigenen Request erhalten soll.

Was für einen Netzwerk-Typ hat denn der Docker-Container? Siehe auch.

Bei der Antwort kommt das Prerouting aber vor dem masquerading und deshalb wird eine ankommende Antwort fälschlicher Weise zum AppServer umgeleitet, statt zurück in den Docker Container. Kann man das nicht in den iptables konfigurieren, dass das Prerouting nur die Requests routet, die nicht masqueraded sind?

Deine Aussagen sind irgendwie etwas wirr. Zeige mal bitte:

iptables -t nat -nvL
iptables -nvL
ip l
ip a

robg336699

(Themenstarter)

Anmeldungsdatum:
4. Mai 2017

Beiträge: 4

Der Container läuft im Bridge Netzwerk

Vielleicht reicht das erstmal

1
2
3
4
5
6
7
8

-A PREROUTING -p tcp -m tcp --dport 80 -j REDIRECT --to-ports 8080
-A PREROUTING -p tcp -m tcp --dport 443 -j REDIRECT --to-ports 8081
-A PREROUTING -m addrtype --dst-type LOCAL -j DOCKER
-A OUTPUT ! -d 127.0.0.0/8 -m addrtype --dst-type LOCAL -j DOCKER
-A POSTROUTING -s 172.17.0.0/16 ! -o docker0 -j MASQUERADE

-A DOCKER -i docker0 -j RETURN

iptables -t nat -nvL

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
Chain PREROUTING (policy ACCEPT 70 packets, 4402 bytes)
 pkts bytes target     prot opt in     out     source               destination
   28  1680 REDIRECT   tcp  --  *      *       0.0.0.0/0            0.0.0.0/0            tcp dpt:80 redir ports 8080
    7   420 REDIRECT   tcp  --  *      *       0.0.0.0/0            0.0.0.0/0            tcp dpt:443 redir ports 8081
   22  1012 DOCKER     all  --  *      *       0.0.0.0/0            0.0.0.0/0            ADDRTYPE match dst-type LOCAL

Chain INPUT (policy ACCEPT 44 packets, 2580 bytes)
 pkts bytes target     prot opt in     out     source               destination

Chain OUTPUT (policy ACCEPT 5 packets, 309 bytes)
 pkts bytes target     prot opt in     out     source               destination
    0     0 DOCKER     all  --  *      *       0.0.0.0/0           !127.0.0.0/8          ADDRTYPE match dst-type LOCAL

Chain POSTROUTING (policy ACCEPT 5 packets, 309 bytes)
 pkts bytes target     prot opt in     out     source               destination
   48  3390 MASQUERADE  all  --  *      !docker0  172.17.0.0/16        0.0.0.0/0

Chain DOCKER (2 references)
 pkts bytes target     prot opt in     out     source               destination
    0     0 RETURN     all  --  docker0 *       0.0.0.0/0            0.0.0.0/0

ip l

1
2
3
4
5
6
7
8
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP mode DEFAULT group default qlen 1000
    link/ether 90:1b:0e:a4:9c:d2 brd ff:ff:ff:ff:ff:ff
138: docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP mode DEFAULT group default
    link/ether 02:42:c5:d2:35:f6 brd ff:ff:ff:ff:ff:ff
152: veth0b7f0b1@if151: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UP mode DEFAULT group default
    link/ether 12:58:8d:1b:04:01 brd ff:ff:ff:ff:ff:ff link-netnsid 0

ip a

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25

1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    link/ether 90:1b:0e:a4:9c:d2 brd ff:ff:ff:ff:ff:ff
    inet 138.201.250.222/26 brd 138.201.250.255 scope global eth0
       valid_lft forever preferred_lft forever
    inet6 2a01:4f8:173:21d9::2/64 scope global
       valid_lft forever preferred_lft forever
    inet6 fe80::921b:eff:fea4:9cd2/64 scope link
       valid_lft forever preferred_lft forever
138: docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
    link/ether 02:42:c5:d2:35:f6 brd ff:ff:ff:ff:ff:ff
    inet 172.17.0.1/16 scope global docker0
       valid_lft forever preferred_lft forever
    inet6 fe80::42:c5ff:fed2:35f6/64 scope link
       valid_lft forever preferred_lft forever
152: veth0b7f0b1@if151: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UP group default
    link/ether 12:58:8d:1b:04:01 brd ff:ff:ff:ff:ff:ff link-netnsid 0
    inet6 fe80::1058:8dff:fe1b:401/64 scope link
       valid_lft forever preferred_lft forever

Danke

misterunknown Team-Icon

Ehemalige
Avatar von misterunknown

Anmeldungsdatum:
28. Oktober 2009

Beiträge: 4403

Wohnort: Sachsen

robg336699 schrieb:

Der Container läuft im Bridge Netzwerk

Das ist doch schonmal was. Das heißt dein Docker-Container hat eine eigene private IP.

Vielleicht reicht das erstmal

1
2
3

-A PREROUTING -p tcp -m tcp --dport 80 -j REDIRECT --to-ports 8080
-A PREROUTING -p tcp -m tcp --dport 443 -j REDIRECT --to-ports 8081

Bei diesen Regeln müsstest du einfach noch weiter einschränken. Ich würde vorschlagen du nimmst einfach deine öffentliche IP mit als Kriterium:

-A PREROUTING -p tcp -m tcp -i eth0 -d 138.201.250.222 --dport 80 -j REDIRECT --to-ports 8080
-A PREROUTING -p tcp -m tcp -i eth0 -d 138.201.250.222 --dport 443 -j REDIRECT --to-ports 8081

Damit sind nur Pakete betroffen, die an die öffentliche IP deines Servers gesendet werden.

Ich persönlich würde aber gar keine Portumleitung per iptables machen, sondern einfach auf Port 80 und 443 einen Apache oder Nginx lauschen lassen, der Proxy für die anderen Ports spielt:

<VirtualHost *:80>
   ServerName <hostname-deiner-applikation>
   ProxyPass / http://localhost:8080/
   ProxyPassReverse / http://localhost:8080/
</VirtualHost>

Auf diese Art und Weise kannst du dann auch Sachen, die im Docker-Container laufen, von außen erreichbar machen.

robg336699

(Themenstarter)

Anmeldungsdatum:
4. Mai 2017

Beiträge: 4

Super, ich wusste dass es eigentlich einfach ist. Ich hatte versucht

1
-A PREROUTING -d ! 172.17.0.2 -p tcp -m tcp --dport 80 -j REDIRECT --to-ports 8080

Aber das not(!) ging dort nicht (syntaktisch).

Ja, Reverseproxy wäre wohl die elegantere Lösung, ziehe ich in Erwägung.

Vielen Dank jedenfalls!

Antworten |