PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Forwarding



Thomassen
15.03.08, 16:58
Hi,

im Moment migriere ich ein paar Dienste auf einen neuen Server.

Beispiel HTTP: Damit es nicht zu Ausfällen kommt, möchte ich den alten Server so konfigurieren, dass er Anfragen an die neue IP weiterleitet. Dazu habe ich auf der neuen Maschine einen Testwebserver auf Port 8080 aufgesetzt und das auf der alten Maschine ausgeführt:


iptables -t nat -A PREROUTING -p tcp --dport 8080 -j DNAT --to [neue IP]:8080

Ich dachte, nun werden Anfragen entsprechend weitergeleitet. Rufe ich allerdings http://[alte IP]:8080/ auf, bekomme ich einen Timeout.

Es liegt wohl daran, dass der Browser die Antwort nicht von dem Server erhält, bei dem er angefragt hat. Ich bräuchte quasi einen transparenten Proxy. Wie biege ich das hin?


Ich habe vor, dasselbe mit MySQL und SMTP zu tun.

Merci,
Peter

asi_dkn
15.03.08, 17:40
du kannst das ganz einfach mit apache machen (hast du noch installiert nehme ich an?) wenn du VHosts verwendest:



....
NameVirtualHost *:80
....

<VirtualHost *:80>
ServerAdmin admin@domain.com
ServerName www.domain.com
....
ProxyPass / http://neue_IP:8080/
</VirtualHost>

Für den Client ist das absolut transparent da dein "alter" Server die Anfrage weiterleitet und die Antwort wieder an den Client schickt.

Alternativ kannst du auch einfach einen Rewrite machen. Dem Client wird dann quasi mitgeteilt das er eine andere URL aufrufen muss (was dieser dann auch tut):

<VirtualHost *:80>
ServerAdmin admin@domain.com
ServerName www.domain.com
....
RewriteEngine On
RewriteRule ^/.*$ http://www1.domain.com/
</VirtualHost>

Letzteres Beispiel würde ich aber nur mit Domainnamen und nicht mit einer IP machen, da es für die Besucher eventuell etwas "hässlich" ist wenn sie eine IP Adresse in der Adressliste finden. Zudem arbeiten name based VHosts so nicht.

Ich denke mal das erste Beispiel ist 1) praktischer und 2) für die Besucher angenehmer das es 100% transparent ist.

Thomassen
15.03.08, 17:48
Hi,

danke, darüber hatte ich bereits nachgedachte, allerdings möchte ich nicht hunderte virtueller Hosts anpassen.

Außerdem habe ich ja vor, auch ein Forwarding für MySQL und Mail einzurichten, wo natürlich die Apache-Möglichkeit nicht möglich ist.

Leider war das nicht die Lösung ...
Peter

asi_dkn
15.03.08, 17:53
okay, in dem fall braucht es noch eine Regel mehr:


iptables -t nat -A PREROUTING -p tcp --dport 8080 -j DNAT --to neue_IP:8080
iptables -A FORWARD -p tcp --dport 8080 -j ACCEPT

Zusätzlich musst du sicherstellen dass das forwarding vom kernel auch erlaubt wird:


# cat /proc/sys/net/ipv4/ip_forward
0


um es zu aktivieren:


echo 1 > /proc/sys/net/ipv4/ip_forward

Und damit's auch nach einem Reboot noch passt muss noch ein eintrag in die /etc/sysctl.conf:


net.ipv4.ip_forward = 1

Hoffe das passt.

Thomassen
15.03.08, 18:07
Hi,

leider passt es nicht (IP-Forwarding war bereits aktiviert). Wenn ich eine Anfrage Client->alt mache, müsste die ja alt->neu weitergereicht werden. Ich hatte gehofft, dass die Antwort von "neu" direkt an den Client geht; das ist aber nicht der Fall: Laut wireshark geht der Request raus, es kommt aber nichts an.

Laut Apache-Log des neuen Servers kommt der Request gar nicht an. Es liegt also bereits am Weiterreichen, des Requests, nicht an der Antwort.

Merci,
Peter

Thomassen
15.03.08, 18:14
[Update] Unsinn

Peter

asi_dkn
15.03.08, 18:15
es ist nicht möglich das der Client C an Server A schickt, Server A die Anfrage an Server B weiterleitet, und B dann dem Client antwort gibt. Das ist so für das TCP Protokoll auch gar nicht vorgesehen, also kannst du dir den gleich abschminken. Das wird so aussehen:

C -> A -> B -> A -> C

Kannst du dann von Server A den Server B auf den benötigen Ports erreichen? Hat B eventuell eine Firewall (iptables) welcher eingehenden Verkehr blockiert? Hat es auf A eventuell iptables Regeln welche den ausgehenden Verkehrt blockieren?

Thomassen
15.03.08, 18:18
Das wird so aussehen:

C -> A -> B -> A -> C

So hatte ich das auch geplant. :-)


Kannst du dann von Server A den Server B auf den benötigen Ports erreichen?

Sei A der alte Server. Ja, beispielsweise mit lynx ist B:8080 aufrufbar.


Hat B eventuell eine Firewall (iptables) welcher eingehenden Verkehr blockiert?

Nein.


Hat es auf A eventuell iptables Regeln welche den ausgehenden Verkehrt blockieren?

Nein.

Peter

asi_dkn
15.03.08, 18:29
Ich habs gerade nicht so 100% im Kopf, aber füge VOR der FORWARD Regel die deine Anfragen weiterleiten sollte doch mal ne Regel ein welche die Pakete mit dem Destination Port 8080 Loggt. So kannst du sehen ob die Pakete überhaupt bis dahin kommen. Dasselbe machst du dann auch noch auf dem neuen Server in der INPUT Tabelle VOR der Regel die den Port 8080 erlaubt.

Ich glaube dass das etwa so aussehen müsste:

iptables -A FORWARD -p tcp --dport 8080 -j LOG --log-prefix 'ipt. Forward :'
respektive
iptables -A INPUT -p tcp --dport 8080 ....

Und wie gesagt, es ist wichtig das diese Reglen vor den Regeln stehen welche die Pakete auf 8080 akzeptieren (die Pakete werden dann nicht weiter behandelt und die Log Regel würde nie zutreffen).

Sieht du in den Access Logfiles vom NEUEN Server auch keine Einträge? Also kein Indiz das die Anfrage überhaupt soweit kommt?

Thomassen
15.03.08, 18:38
Auf dem alten Server habe ich die Log-Regel eingeführt; im Syslog tauchen mehrere Zeilen im Abstand von einigen Sekunden auf, die das Forwarding bestätigen (offenbar versucht es der Client-Browser häufiger).

Auf dem neuen Server passiert Folgendes:


# iptables -A INPUT -p tcp --dport 8080 -j LOG --log-prefix 'ipt. Forward :'
iptables: No chain/target/match by that name

Man muss dazusagen, dass es sich um eine virtuelle OpenVZ-Maschine handelt, die sonst aber netzwerkmäßig einwanfrei funktioniert.

Nein, im access.log von Apache auf dem neuen Server taucht nichts auf.

asi_dkn
15.03.08, 19:03
Es sieht aus als wäre auf dem neuen Server die iptables Module nicht geladen... Wie dem auch sei, wenn das Forwarding klappt, auf dem Server aber nichts ankommt, liegt das Problem nicht beim Forwarding. Hast du deine iptables Regeln kontrolliert? IP, Port etc. stimmt alles und keine Tippfehler?

Was evtl. noch gut möglich wäre, ist, das der spätere Verbdindungsaufbau nicht klappt. Initial wird zwar der Port 8080 angesteuert, später einigen sich aber u.U. auf andere Ports für den weiteren Verkehr.

Füge doch mal auf deinem alten Server folgende Regel hinzu:


iptables -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT

Damit werden alle Pakete die zu einer bereits aufgebauten Verbindung oder einer anderen, bestehenden Verbindung gehören durchgelassen.

Thomassen
15.03.08, 19:31
Ja, ich habe alle Regeln überprüft. Müssen auf dem neuen Server überhaupt iptables-Module geladen sein?

Das Einfügen der zuletzt genannten Regel führt auch nicht weiter. Soll ich verzweifeln? ;-)

asi_dkn
15.03.08, 21:51
Verzweifeln nicht umbedingt... aber wie's scheint ist das Problem nicht sooo einfach zu lösen... oder ich übersehe etwas ganz einfaches, gut möglich. Aber so aus der Ferne ohne Näheres zu wissen ist das auch nicht ganz einfach.

Vielleicht liegt der Hund auch irgendwo bei der OpenVZ-Config begraben.

Mir ist dazu noch eingefallen das die letzte iptables Regel die ich dir genannt habe eigentlich nicht nötig sein sollte und zumindest für HTTP nicht nötig ist.

NACHTRAG:
Wegen den iptables modulen. Wenn der Server nicht direkt am WAN hängt und hinter einem Router resp. Firewall steckt ist das nicht umbedingt nötig. Andernfalls würde ich dir wärmstens empfehlen den paketfilter zu benutzen, generell dicht zu machen und nur die nötigen ports zu öffnen (SSH, HTTP/S, MySQL und was du sonst noch benötigst).

der Befehl 'lsmod' zeigt die alle geladenen module an. Mit 'modprobe iptables' sollte er dann das modul auch laden. ausser du hast das alles direkt im kernel.

Thomassen
08.04.08, 18:30
Das Programm pen kann dieses Forwarding exzellent selbst handhaben.

Peter