iptables --set-mark - Leiten Sie verschiedene Ports über verschiedene Schnittstellen

13

Kurzgeschichte,
3 Schnittstellen, eth0 (LAN), eth1 (ADSL), eth2 (4G).
eth0 -> eth1: Funktioniert
(Ports 80, 443, 4070) eth0 -> eth2: Passiert nicht


Dies ist eine grafische Darstellung der Idee:

Port 80 & 443 über eth2 und
der Rest über eth1
Bildbeschreibung hier eingeben

Netzschema:

eth0: -ip 10.0.0.1 -net 10.0.0.0/8 -gw 10.0.0.1 (the servers own intf) 
eth1: -ip 192.168.1.74 -net 192.168.1.0/24 -gw 192.168.1.254 
eth2: -ip 192.168.1.91 -net 192.168.0.0/24 -gw 192.168.0.1 






Dieses neue Skript leitet 22 und 4070 an die richtige Tabelle weiter, denke ich.
Nachdem es an diesen Tisch gelangt ist, wird es jedoch nicht zu eth2 umgeleitet.




Dieses Skript funktioniert mit Ausnahme von 22 und 4070!

(Port 80 ist unkommentiert und funktioniert, aber über eth1, was falsch ist.)

modprobe iptable_nat
modprobe ip_conntrack

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

iptables -P INPUT ACCEPT
iptables -F INPUT
iptables -P OUTPUT ACCEPT
iptables -F OUTPUT
iptables -P FORWARD DROP
iptables -F FORWARD
iptables -F PREROUTING
iptables -t nat -F
iptables -t mangle -F
iptables -F
# This next line restores any issues trying to connect to something
# if you get weird ACK packets when trying to connect (at least i did)!
iptables -t mangle -A PREROUTING -p tcp -j CONNMARK --restore-mark
ip route flush table main

iptables -A PREROUTING -i eth0 -t mangle -p tcp --dport 22 -j MARK --set-mark 1
###  iptables -A PREROUTING -i eth0 -t mangle -p tcp --dport 80 -j MARK --set-mark 1
iptables -A PREROUTING -i eth0 -t mangle -p tcp --dport 4070 -j MARK --set-mark 1

## Setup routes
# LAN
route add -net 10.0.0.0 netmask 255.0.0.0 dev eth0
# ADSL
route add -net 192.168.1.0 netmask 255.255.255.0 dev eth1
# 4G (Only accessible if marking packages with \x01
route add -net 192.168.0.0 netmask 255.255.255.0 dev eth2
# Default via ADSL
## -- Does the same as ip route below? route add default gw 192.168.1.254


echo "201 eth2.out" >> /etc/iproute2/rt_tables

ip rule add fwmark 1 table eth2.out
ip route add default via 192.168.0.1 dev eth2 table eth2.out
ip route add default via 192.168.1.254 dev eth1



## Setup forwards
# From 4G to LAN
iptables -A FORWARD -i eth2 -o eth0 -m state --state ESTABLISHED,RELATED,NEW -j ACCEPT
# From ADSL to LAN
iptables -A FORWARD -i eth1 -o eth0 -m state --state ESTABLISHED,RELATED,NEW -j ACCEPT
# From LAN to ADSL (Default route out)
# - Note: If marked packages is sent to ADSL they will be mangled and rerouted to 4G
iptables -A FORWARD -i eth0 -o eth1 -j ACCEPT
iptables -t nat -A POSTROUTING -o eth1 -j MASQUERADE
iptables -t nat -A POSTROUTING -o eth2 -j MASQUERADE









Altes Drehbuch:


  Ignore everything below unless you're interested in retracing my steps!!




Ich habe ein router.sh-Skript erstellt, um meine Umgebung für den Fall einzurichten, dass ich etwas Schlechtes tue. Ich habe 3 Ports, die ich über eine Festnetz-ADSL-Verbindung an eine 4G-Verbindung und den Rest senden möchte. Dazu habe ich iptables angewiesen, Pakete auf der Standardroute zu entpacken und sie über meine 4G-Schnittstelle zu senden, wenn --dport == 443 | 80 | 4070

Dies funktioniert jedoch nicht. Ich werde immer noch durch mein Festnetz geroutet, egal was passiert.

So sieht mein Skript aus:

#!/bin/bash

## routing tables
# wireless = 4G via eth2
# adsl = adsl via eth1

modprobe iptable_nat
modprobe ip_conntrack

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

iptables -P INPUT ACCEPT
iptables -F INPUT
iptables -P OUTPUT ACCEPT
iptables -F OUTPUT
iptables -P FORWARD DROP
iptables -F FORWARD
iptables -t nat -F
ip route flush table main
ip route flush table wireless
ip route flush table adsl

## Setup routing tables
# ADSL
ip route add table adsl to 192.168.1.0/24 dev eth1
# 4G
ip route add table wireless to 192.168.0.0 dev eth2
ip rule add fwmark 0x1 table wireless

## Setup routes
# LAN
route add -net 10.0.0.0 netmask 255.0.0.0 dev eth0
# ADSL
route add -net 192.168.1.0 netmask 255.255.255.0 dev eth1
# 4G (Only accessible if marking packages with \x01
route add -net 192.168.0.0 netmask 255.255.255.0 dev eth2
# Default via ADSL
route add default gw 192.168.1.254


## Forward ports into the LAN
iptables -t nat -A PREROUTING -i eth1 -p tcp --dport 80 -j DNAT --to 10.0.0.3:80


## Lets mark all packets we want for 4G forward
# HTTPS
iptables -A OUTPUT -t mangle -o eth1 -p tcp --dport 443 -j MARK --set-mark 1
# HTTP
iptables -A OUTPUT -t mangle -o eth1 -p tcp --dport 80 -j MARK --set-mark 1
# Spotify
iptables -A OUTPUT -t mangle -o eth1 -p tcp --dport 4070 -j MARK --set-mark 1

## Setup forwards
# From 4G to LAN
iptables -A FORWARD -i eth2 -o eth0 -m state --state ESTABLISHED,RELATED,NEW -j ACCEPT
# From ADSL to LAN
iptables -A FORWARD -i eth1 -o eth0 -m state --state ESTABLISHED,RELATED -j ACCEPT
# From LAN to ADSL (Default route out)
# - Note: If marked packages is sent to ADSL they will be mangled and rerouted to 4G
iptables -A FORWARD -i eth0 -o eth1 -j ACCEPT
iptables -A FORWARD -j LOG
#iptables --table nat --append POSTROUTING --out-interface eth2 --jump SNAT --to-source "192.168.1.74"
iptables -t nat -A POSTROUTING -o eth1 -j MASQUERADE

Ich habe auch versucht, diese 3 am Ende des Skripts einzufügen:

iptables -t nat -A POSTROUTING -o eth2 -p tcp --dport 80 -j SNAT --to "192.168.0.91"
iptables -t nat -A POSTROUTING -o eth2 -p tcp --dport 443 -j SNAT --to "192.168.0.91"
iptables -t nat -A POSTROUTING -o eth2 -p tcp --dport 4070 -j SNAT --to "192.168.0.91"

Auch ohne Erfolg versucht:

iptables -A PREROUTING -t mangle -i eth0 -p tcp --dport 80 -j MARK --set-mark 1

Zu guter Letzt versucht:

## Lets mark all packets we want for 4G forward
# HTTPS
iptables -A POSTROUTING -t mangle -o eth1 -p tcp --dport 443 -j MARK --set-mark 1
# HTTP
iptables -A POSTROUTING -t mangle -o eth1 -p tcp --dport 80 -j MARK --set-mark 1
# Spotify
iptables -A POSTROUTING -t mangle -o eth1 -p tcp --dport 4070 -j MARK --set-mark 1

Das Routing funktioniert, ich kann im Internet surfen, Musik hören und was nicht, aber ich mache es über die falsche Schnittstelle. Ich habe schon lange gegoogelt und Kleinigkeiten gefunden, um zu verstehen, was ich tue und warum ich es tue. Ich könnte Traffic Shaping über tc machen, aber wenn es möglich ist, Pakete in iptables zu markieren, würde es mir sehr helfen.

Meine Vermutung ist, dass ich die Reihenfolge in Bezug auf die verschiedenen Regeln falsch mache, hauptsächlich den MASQUERADE- Teil? oder sollte das überhaupt da sein?

Kann jemand erklären, wie man den DNAT- Port tcp: 80 von einer externen Schnittstelle (entweder einem oder BEIDEN Protokollen) zu einem internen 10.0.0.0-Adressraum sagt?



Ausgänge:

root@Netbridge:~# route -n Kernel IP routing table Destination    

Gateway         Genmask         Flags Metric Ref    Use Iface<br>
0.0.0.0         192.168.1.254   0.0.0.0         UG    0      0        0 eth1<br>
10.0.0.0        0.0.0.0         255.0.0.0       U     0      0        0 eth0<br>
192.168.0.0     0.0.0.0         255.255.255.0   U     0      0        0 eth2<br>
192.168.1.0     0.0.0.0         255.255.255.0   U     0      0        0 eth1


root@Netbridge:~# ifconfig

eth0      Link encap:Ethernet  HWaddr 00:0c:29:7e:9e:4e  
          inet addr:10.0.0.1  Bcast:10.255.255.255  Mask:255.0.0.0

eth1      Link encap:Ethernet  HWaddr 00:0c:29:7e:9e:58  
          inet addr:192.168.1.74  Bcast:192.168.1.255  Mask:255.255.255.0

eth2      Link encap:Ethernet  HWaddr 00:0c:29:7e:9e:62  
          inet addr:192.168.0.91  Bcast:192.168.0.255  Mask:255.255.255.0

Befolgen Sie diese Anweisungen:
Ausgabe-Verkehr-auf-verschiedenen-Schnittstellen-basierend-auf-Ziel-por
iptables-Forward-spezifisch-Port-zu-spezifisch-nic
Neben einigen anderen verwandten Threads.

Torxed
quelle
Es tut mir leid, aber gibt es einen Grund, Apache nicht nur an die localhostund die Adresse der eth2Schnittstelle zu binden ?
Jan Marek,
@ JanMarek: Apache wird hier nicht erwähnt. Und zu Ihrer Information: Wenn Sie einen Socket an ethXdie IP-Adresse eines Benutzers binden, wird verhindert, dass Hosts im ethXLAN über die IP-Adresse des Benutzers auf den lokalen Server zugreifen ethY, und Hosts werden nicht daran gehindert, über die IP-Adresse des Benutzers auf den Server ethYzuzugreifen ethX. Denken Sie daran, dass Linux ein schwaches Hostmodell verwendet.
BatchyX
OK, es gibt mehr Webserver, nicht nur einen Apache-Server ... Ich denke, der Bindungs-Webserver auf der Schnittstelle eth2 kann eine einfache Lösung sein. Aber ich kann mich irren, ich weiß.
Jan Marek

Antworten:

4

BatchyX gibt bereits einige sehr gute Erklärungen zu Iptables und Routing, so dass ich meine Faulheit ausüben und direkt zum Skript gehen werde.

Es sollte den gesamten Datenverkehr auf Port 80.443.22.4070 bis 192.168.0.91 NAT. Der ganze Rest wird NAT durch 192.168.1.254.

Ich mache meine Tests erneut und folge am Ende dieser Anleitung . Was in dieser Anleitung fehlt, sind die letzten 3 Zeilen in meinem Skript. Was ich von einem anderen Hafen herausgefunden habe, aber ich habe den Überblick über diesen Link verloren.

Es ist ein getestetes Arbeitsskript.

Benötige Standardroute

Eine Sache, die ich nicht in das Skript eingefügt habe, ist das Einrichten der Standardroute. Es sollte sein

route add default gw 192.168.1.254

Wenn Sie dies tun route -n, sollte dies die einzige Standardroute sein (Ziel: 0.0.0.0).

0.0.0.0    192.168.1.254    0.0.0.0    UG    0    0    0    eth1

fw-router.sh

# Iptables zurücksetzen / spülen
iptables -F
Iptables -X
iptables -t nat -F
iptables -t nat -X
iptables -t mangle -F
iptables -t mangle -X
iptables -P EINGABE AKZEPTIEREN
iptables -P FORWARD ACCEPT
iptables -P OUTPUT ACCEPT

# IP-Route zurücksetzen / spülen / einrichten (Tabelle 4)
ip route flush table 4
ip route show table main | grep -Ev ^ default | während ROUTE lesen; ip route add table 4 $ ROUTE; erledigt
ip route add table 4 default via 192.168.0.1

#Mark Packet mit passendem D.Port
iptables -t mangle -A PREROUTING -p tcp --dport 22 -s 10.0.0.0/24 -j MARK --set-mark 4
iptables -t mangle -A PREROUTING -p tcp --dport 80 -s 10.0.0.0/24 -j MARK --set-mark 4
iptables -t mangle -A PREROUTING -p tcp --dport 443 -s 10.0.0.0/24 -j MARK --set-mark 4
iptables -t mangle -A PREROUTING -p tcp --dport 4070 -s 10.0.0.0/24 -j MARK --set-mark 4

#SNAT-Regeln
iptables -t nat -A POSTROUTING -o eth1 -j SNAT --zur Quelle 192.168.1.74
iptables -t nat -A POSTROUTING -o eth2 -j SNAT --zur Quelle 192.168.0.91

#IP Route
IP-Regel füge fwmark 4 hinzu. Tabelle 4
ip route flush cache

#IP Stack
#Dies ist der fehlende Teil in der Anleitung
echo 1> / proc / sys / net / ipv4 / ip_forward
für f in / proc / sys / net / ipv4 / conf / * / rp_filter; Echo 0> $ f; erledigt
echo 0> / proc / sys / net / ipv4 / route / flush

PS1: Kurz gesagt, MASQUERADEfunktioniert nicht (in den meisten Fällen und definitiv in Ihrem Fall) für NAT mit mehreren externen IP-Adressen, die einen Lastenausgleich benötigen oder DNAT für die Verarbeitung des eingehenden Datenverkehrs benötigen. Sie benötigen SNATfür die Richtungssteuerung.

PS2: Reine Iptables sind nicht ausreichend.

John Siu
quelle
Zuallererst ein Hoch auf den direkten Drehbucheinstieg :) Ich werde es heute Abend versuchen, wenn ich wieder in die Umgebung komme, in der dies ablaufen wird!
Torxed
hmm, muss möglicherweise gründlich überarbeitet werden. Lass es mich wissen.
John Siu
Überarbeitet, sollte jetzt funktionieren.
John Siu
Sweet, wir werden uns in Kürze bei Ihnen
melden
Ich liebe dich, so viele Kopfschmerzen und du hast es gelöst! Vielen Dank!
Torxed
5

Hinweis: Ich habe nur das erste Skript betrachtet und das alte ignoriert.

  • Sie müssen netfilter-Module nicht manuell mit aktuellen iptables testen. Dies ist nur für benutzerdefinierte Verbindungstracker erforderlich.
  • Verwechseln Sie nicht routeund ip route. Das ist das pure Böse. Verwenden Sie einfach ipüberall und vergessen ifconfigundroute
  • /etc/iproute2/rt_tableswird bei Neustarts nicht zurückgesetzt. Das wiederholte Anhängen desselben Eintrags ist keine gute Idee, Sie müssen es nur einmal tun. Denken Sie daran, dass rt_tablesnur Namen-Aliase zu numerischen Werten definiert werden und keine Konfiguration geändert wird.

  • Jetzt für iptables: In Ihrer FORWARDKette verwerfen Sie Pakete, die von LAN zu 4G kommen. Das ist schlecht. Der FORWARDHook wird nach dem Routing verwendet. Zu diesem Zeitpunkt ist das gesamte Richtlinienrouting abgeschlossen, und es ist bereits bekannt, ob das Paket an 4G oder ADSL gesendet werden soll. In FORWARDoder nach dem Umleiten wird nicht ausgeführt FORWARD(technisch gesehen kann das Umleiten POSTROUTINGin schweren Fällen nach dem Umleiten ausgeführt werden, aber zurück zum eigentlichen Punkt).

Nun zu Ihrem Routing: Denken Sie daran, dass Ubuntu standardmäßig die umgekehrte Pfadfilterung aktiviert. Die umgekehrte Pfadfilterung funktioniert folgendermaßen: Wenn der Kernel ein Paket von einer Schnittstelle A empfängt (ob es weitergeleitet wird oder nicht), invertiert er die Quelladresse und die Zieladresse und prüft, ob das resultierende Paket über die Schnittstelle A geleitet werden soll. Ist dies nicht der Fall, wird das Paket als Adress-Spoofing-Versuch verworfen.

Für Pakete, die von empfangen wurden eth0, ist dies kein Problem. Für Pakete, die von empfangen werden eth1, ist dies ebenfalls kein Problem, da der Kernel beim Umkehren der Quell-IP-Adresse und der Ziel-IP-Adresse die Standardroute in der Tabelle verwendet main. Für Pakete, von eth2denen Sie nicht markieren, ist dies ein Problem, da der Kernel die Standardroute in der Tabelle mainerreicht und berücksichtigt, dass diese Pakete von empfangen wurden eth1. Die einfachste Lösung besteht darin, die Umkehrpfadfilterung für eth1 zu deaktivieren:

sysctl -w net.ipv4.conf.eth1.rp_filter=0
BatchyX
quelle
Alle tollen Kommentare und ja, es gibt einige fehlerhafte Logik von meiner Seite, zum Beispiel jedes Mal an rt_tables anzuhängen und vor allem bestimmte Tabellen nicht so zu löschen, wie ich sollte, aber ich werde es schaffen :) Ich werde alles versuchen und sehen Wenn es funktioniert, dann +50 für Sie und vor allem haben Sie einen Mann hinter sich vor dem Zerhacken gerettet! :)
Torxed
Das folgende Skript funktioniert, aber Sie, mein Herr, haben mir ein oder zwei Denkanstöße gegeben und rp_filter = 0 hat mir sehr geholfen! : D
Torxed
@ BatchyX sehr informativ, stimmen Sie auch zu.
John Siu
@Torxed Der Beitrag, den ich als Erwähnung von rp_filter für ALLE gesehen habe, muss deaktiviert werden. Ich bin mir nicht sicher, ob es anders funktioniert.
John Siu
@ JohnSiu: Sie müssen nur den RP-Filter an Schnittstellen deaktivieren, an denen dies problematisch ist. In diesem Fall ist es eth1, da keine Route zu dieser Schnittstelle führt, wenn keine Markierungen gesetzt sind. eth2 hat kein solches Problem, da die Standardroute in diese Schnittstelle eingeht. Für eth0 ist es tatsächlich nützlich, den RP-Filter aktiviert zu lassen, da andernfalls jemand im LAN ein IP-Paket fälschen könnte, dessen Quelladresse im Internet und dessen Zieladresse im LAN liegt, und der Router dies gerne annimmt und weiterleitet es zurück zu ... eth0.
BatchyX