Frage iptables - Target, um Pakete an bestimmte Schnittstellen zu leiten?


Mein Home-Server hat zwei Hauptschnittstellen, eth1 (eine Standard-Internetverbindung) und tun0 (ein OpenVPN-Tunnel). Ich würde gerne verwenden iptables Erzwingen, dass alle von einem lokalen Prozess, der der UID 1002 gehört, generierten Pakete durchgehen tun0und alle anderen Pakete, durch die es hinausgeht eth1.

Ich kann leicht übereinstimmende Pakete markieren:

iptables -A OUTPUT -m owner --uid-owner 1002 -j MARK --set-mark 11

Nun möchte ich eine Regel in die POSTROUTING-Kette (wahrscheinlich der Mangle-Tabelle) setzen, um mit 11 markierte Pakete zu vergleichen und an sie zu senden tun0, gefolgt von einer Regel, die alle Pakete abgleicht und an sie sendet eth1.

Ich habe das ROUTE-Ziel gefunden, aber das scheint nur die Quellschnittstelle neu zu schreiben (es sei denn, ich lese es falsch).

Ist iptables dazu in der Lage? Muss ich mich mit der Routing - Tabelle (via ip route oder nur das Vermächtnis route Befehle) stattdessen?

Edit: Ich dachte, dass ich vielleicht mehr Informationen liefern sollte. Ich habe derzeit keine anderen iptables-Regeln (obwohl ich einige Regeln erstellen kann, um in Zukunft nicht damit zusammenhängende Aufgaben auszuführen). Auch die Ausgabe von ip route ist:

default via 192.168.1.254 dev eth1  metric 203
10.32.0.49 dev tun0  proto kernel  scope link  src 10.32.0.50
85.17.27.71 via 192.168.1.254 dev eth1
192.168.1.0/24 dev eth1  proto kernel  scope link  src 192.168.1.73  metric 203

Ich habe die Routing-Tabelle nicht berührt - so ist es zur Zeit (obwohl es ziemlich schmutzig aussieht). Es tut mir leid, aber ich habe kein Vermächtnis route Befehl auf diesem Computer installiert.

Und die Ausgabe von ip addr (Natürlich können eth0 und eth2 ignoriert werden - sie sind NICs, die derzeit nicht verwendet werden):

1: lo: <LOOPBACK,UP,LOWER_UP> mtu 16436 qdisc noqueue state UNKNOWN
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN qlen 1000
    link/ether 1c:6f:65:2a:73:3f brd ff:ff:ff:ff:ff:ff
3: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast     state UP qlen 1000
    link/ether 00:1b:21:9d:4e:bb brd ff:ff:ff:ff:ff:ff
    inet 192.168.1.73/24 brd 192.168.1.255 scope global eth1
    inet6 fe80::21b:21ff:fe9d:4ebb/64 scope link
       valid_lft forever preferred_lft forever
4: eth2: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN qlen 1000
    link/ether 00:1b:21:6a:c0:4b brd ff:ff:ff:ff:ff:ff
5: tun0: <POINTOPOINT,MULTICAST,NOARP,UP,LOWER_UP> mtu 1500 qdisc     pfifo_fast state UNKNOWN qlen 100
    link/none
    inet 10.32.0.50 peer 10.32.0.49/32 scope global tun0

Edit: Ich habe etwas funktioniert, funktioniert aber nicht, markierte Pakete zu tun0 weiterleiten. Grundsätzlich habe ich eine Tabelle (11) hinzugefügt und verwendet:

ip route add table 11 via 10.32.0.49 dev tun0
ip rule add priority 10000 fwmark 11 table 11

Wenn ich nur sudo -u user1000 wget -qO- whatismyip.org, Bekomme ich die externe IP-Adresse meines Hauses, aber wenn ich es tue sudo -u user1002 wget -qO- whatismyip.org, Bekomme ich auch die IP-Adresse meines Hauses (aber ich sollte die IP am anderen Ende des OpenVPN-Tunnels bekommen).

Laufen iptables -vL bestätigt, dass die Pakete mit der Markierungsregel übereinstimmen, aber sie scheinen der Routing-Regel nicht zu folgen.

EDIT: Ich habe eine lange Zeit damit verbracht, und obwohl es immer noch nicht funktioniert, denke ich, dass ich ein bisschen näher bin.

Die iptables Regel muss in der sein mangle OUTPUT-Kette der Tabelle. Ich denke ich brauche auch eine MASKERADE Regel in der nat die POSTROUTING-Kette der Tabelle, um die Quelladresse festzulegen. Die Umleitung, die nach dem Mangel von OUTPUT auftritt, funktioniert jedoch nicht ordnungsgemäß.

Ich habe jetzt 5 Stunden damit verbracht, also mache ich eine Pause und werde wahrscheinlich später heute Abend oder irgendwann morgen zu ihr zurückkehren.


22
2017-12-29 18:56


Ursprung




Antworten:


Ich habe vor kurzem ein ähnliches Problem, wenn auch ein bisschen anders. Ich wollte routen nur TCP-Port 25 (SMTP) über eine OpenVPN-Schnittstelle tap0, während der gesamte übrige Datenverkehr (auch für denselben Host) über die Standardschnittstelle geleitet wird.

Um dies zu tun, musste ich Pakete markieren und Regeln für den Umgang damit festlegen. Fügen Sie zuerst eine Regel hinzu, mit der der Kernel Pakete routen lässt, die mit markiert sind 2 durch Tabelle 3 (später erklärt):

ip rule add fwmark 2 table 3

Sie hätten einen symbolischen Namen hinzufügen können /etc/iproute2/rt_tables, aber ich habe mich nicht darum gekümmert. Die Nummer 2 und 3sind zufällig ausgewählt. In der Tat können diese die gleichen sein, aber zur Klarheit habe ich es in diesem Beispiel nicht gemacht (obwohl ich es in meinem eigenen Setup mache).

Fügen Sie eine Route hinzu, um Datenverkehr über eine andere Schnittstelle umzuleiten, unter der Annahme, dass das Gateway ist 10.0.0.1:

ip route add default via 10.0.0.1 table 3

Sehr wichtig! Leeren Sie Ihren Routing-Cache, sonst erhalten Sie keine Antwort und sitzen einige Stunden mit Ihren Händen im Haar:

ip route flush cache

Stellen Sie nun eine Firewall-Regel zum Markieren von designierten Paketen ein:

iptables -t mangle -A OUTPUT -p tcp --dport 465 -j MARK --set-mark 2

Die obige Regel gilt nur, wenn die Pakete von der lokalen Maschine kommen. Sehen http://inai.de/images/nf-packet-flow.png. Passen Sie es Ihren Anforderungen an. Wenn Sie beispielsweise ausgehenden HTTP - Datenverkehr nur über die tap0 Schnittstelle, ändern Sie 465 zu 80.

Um zu verhindern, dass die Pakete gesendet werden tap0 Wenn Sie Ihre LAN-Adresse als Quell-IP verwenden, verwenden Sie die folgende Regel, um sie in Ihre Schnittstellenadresse zu ändern (angenommen 10.0.0.2 als IP-Adresse für die Schnittstelle tap0):

iptables -t nat -A POSTROUTING -o tap0 -j SNAT --to-source 10.0.0.2

Entspannen Sie abschließend die Validierung der umgekehrten Pfadquelle. Einige schlagen vor, dass Sie es einstellen 0, aber 2 scheint eine bessere Wahl zu sein https://www.kernel.org/doc/Documentation/networking/ip-sysctl.txt. Wenn Sie dies überspringen, erhalten Sie Pakete (dies kann mit bestätigt werden tcpdump -i tap0 -n), aber Pakete werden nicht akzeptiert. Der Befehl zum Ändern der Einstellung, so dass Pakete akzeptiert werden:

sysctl -w net.ipv4.conf.tap0.rp_filter=2

22
2018-05-14 19:52



Warum verwenden Sie SNAT anstelle von MASQUERADE? MACHT MASQUERADE das gleiche, außer dass die IP-Adresse von der Schnittstelle zu "runtime" gesammelt und nicht in der Konfigurationsdatei fest codiert ist? - Ethan
@Ethan Von man iptables: Es sollte nur mit dynamisch zugewiesenen IP-Verbindungen verwendet werden: Wenn Sie eine statische IP-Adresse haben, sollten Sie das SNAT-Ziel verwenden. Masquerading ist äquivalent zur Angabe einer Zuordnung zu der IP-Adresse der Schnittstelle, an der das Paket ausgeht, hat aber auch den Effekt, dass Verbindungen vergessen werden, wenn die Schnittstelle ausfällt. Du hast Recht, aber da sich meine IP niemals ändern würde, entschied ich mich, SNAT per Empfehlung auf der Manpage zu verwenden. - Lekensteyn
Ich denke (obwohl nicht getestet) ist der letzte Schritt (Reverse Path Source Validierung) nicht notwendig. Sie könnten einfach eine weitere Regel hinzufügen PREROUTING Kette zu DNAT an die richtige Quelladresse (entsprechend Ihrem Standard-Gateway). - Christian Wolf


Ich habe das gelöst. Das Problem war mit den Routing-Regeln in Tabelle 11. Tabelle 11 war getroffen werden, aber die Routing-Regeln machen es funktionsunfähig. Dieses Skript verwende ich jetzt und es scheint gut zu funktionieren (obwohl es offensichtlich spezifisch für mein Setup ist). Außerdem habe ich eine neue Tabelle 21 erstellt, die dem Haupt-Uplink (eth1) gewidmet ist.

# Add relevant iptables entries.
iptables -t mangle -A OUTPUT -m owner --uid-owner 1002 -j MARK --set-mark 11
iptables -t nat -A POSTROUTING -o tun0 -j MASQUERADE

# Flush ALL THE THINGS.
ip route flush table main
ip route flush table 11
ip route flush table 21
ip rule flush

# Restore the basic rules and add our own.
ip rule add lookup default priority 32767
ip rule add lookup main priority 32766
ip rule add fwmark 11 priority 1000 table 11
# This next rule basically sends all other traffic down eth1.
ip rule add priority 2000 table 21

# Restore the main table.  I flushed it because OpenVPN does weird things to it.
ip route add 127.0.0.0/8 via 127.0.0.1 dev lo
ip route add 192.168.1.0/24 dev eth1 src 192.168.1.73
ip route add default via 192.168.1.254

# Set up table 21.  This sends all traffic to eth1.
ip route add 192.168.1.0/24 dev eth1 table 21
ip route add default via 192.168.1.254 dev eth1 table 21

# Set up table 11.  I honestly don't know why 'default' won't work, or
# why the second line here is needed.  But it works this way.
ip route add 10.32.0.49/32 dev tun0 table 11
ip route add 10.32.0.1 via 10.32.0.50 dev tun0 table 11
ip route add 0.0.0.0/1 via 10.32.0.50 dev tun0 table 11

ip route flush cache

## MeanderingCode bearbeiten (weil ich noch nicht kommentieren kann) 

Danke für diese Antwort! Es scheint, als könnte dies unordentlich werden, da Sie die Routeninformationen hier beibehalten müssen (möglicherweise Duplikate oder andere Dinge, die Routen festlegen möchten.

Sie können "komische Dinge" in Ihrer Routingtabelle von OpenVPN erfahren, da der Server so konfiguriert ist, dass er Routen "pusht", wodurch der gesamte Datenverkehr durch die VPN-Netzwerkschnittstelle statt durch das "nackte" Internet geleitet wird. Oder Ihre OpenVPN-Konfiguration oder was auch immer Skript / Anwendung einrichtet, legt Routen fest.

Im ersten Fall können Sie Ihre OpenVPN-Konfiguration bearbeiten und eine Zeile einfügen, die "route-nopull" enthält.
   Im letzteren Fall überprüfen Sie die Konfiguration für OpenVPN oder einen Wrapper (Netzwerk-Manager-openvpn, zum Beispiel auf vielen aktuellen Linux-Desktop-Distributionen)
   In jedem Fall ist das Löschen der Routingkonfiguration, in der sie eingerichtet wird, sauberer und sicherer als das Löschen der Tabelle, je nachdem, wann Sie dieses Skript ausführen und was Ihr System sonst noch tut.

Prost!


5
2017-12-30 04:02





Ich denke du willst:

/sbin/ip route add default via 10.32.0.49 dev tun0 table 11
/sbin/ip rule add priority 10000 fwmark 11 table 11

http://lartc.org/howto/lartc.netfilter.html

Aber ich habe das oben nicht getestet.


2
2017-12-29 21:02



Der erste Befehl gibt "Error: entweder" zu "ist doppelt, oder" 10.32.0.49 "ist ein Müll." - Ethan
Sorry hat das Via zwischen Standard und IP vergessen. - mfarver
Ich versuchte es. Es scheint den gleichen Effekt zu haben wie das Verlassen des default Schlüsselwort aus. - Ethan
Um Optionen zu eliminieren, können Sie versuchen, eine Paketaufzeichnung auf tun0 durchzuführen und sehen, ob Pakete auf dieser Schnittstelle landen. tcpdump -i tun0 .. alternativ, müssen Sie es auf Benutzer-ID basieren? Könnten Sie es einfach basierend auf der Ziel-IP-Adresse (einfacher) tun? Route hinzufügen <remote Host> über 10.32.0.49 - mfarver
Ich kann nicht von der Ziel-IP-Adresse basieren - es würde viele davon geben. Ich könnte theoretisch auch von pid ausgehen, aber das ist noch schwieriger, weil ich das pid erst kennen werde, wenn die Daemon (s) starten. - Ethan


Dies kann ohne iptables-Befehl ausgeführt werden. Führen Sie einen einfachen ip-Befehl aus

Für die UID 1002:

ip rule add uidrange 1002-1002 table 502

Fügen Sie die Standardroute für die Tabelle 502 über die Schnittstelle hinzu, die Sie sagen möchten

eth0 ip rule add default via a.b.c.d dev eth0

0
2017-12-30 14:14



Ich habe diesen Befehl getestet und es hat nicht funktioniert: Error: argument "uidrange" is wrong: Failed to parse rule type - kasperd