Quellbasiertes Richtlinienrouting und NAT (DNAT / SNAT), auch bekannt als Multi-WANs, unter CentOS 5

4

Ursprünglich bei Unix und Linux gepostet, aber niemand konnte darauf antworten, also migriere ich die Frage hier:

Meine Frage bezieht sich auf Source Based Policy Routing unter CentOS 5 mit 2 WANs und einem LAN (NAT) -Port mit Load Balancing. Bevor ich das Problem beschreibe, möchte ich zunächst einige Bemerkungen machen ...

Ich weiß, dass dieses Thema beim Stapelaustausch schon oft hierher gebracht wurde und dass die fünf wichtigsten Antworten lauten (geordnet von den meisten nach den wenigsten):

  1. Deaktiviere rp_filter
  2. Mark / Connmark-basiertes Richtlinienrouting
  3. IP-basiertes Richtlinienrouting (weitere IPs hinzufügen)
  4. Installieren Sie pfSense, Shorewall, Ubuntu ...
  5. Kaufen Sie teure Cisco / 3com / Juniper / Etc ... Router

In den meisten Fällen sind einige dieser Antworten richtig, aber für mich haben die Lösungen 1 und 2 kein Workout (ich verwerfe nicht mindestens Punkt 2, da ich möglicherweise Probleme mit meinem Setup habe). Punkt 3 isoliert im Grunde ein Problem Anstatt es zu lösen (fügt auch Komplexität zu den Routingtabellen hinzu) und die Lösungen 4 und 5 gehören nicht zum Anwendungsbereich, da ich keine Ressourcen habe, um spezielle Hardware zu kaufen, und den Server auch nicht offline schalten kann, da er in Produktion ist, um das Ersetzen zusammenzufassen Der CentOS-Server mit etwas "Besserem" ist vom Tisch.

Ok, jetzt zurück zum Problem, lass uns zuerst das aktuelle Setup beschreiben ...

Schnittstellen :

eth1: IP: 10.0.0.1, GW: 10.0.0.1, NM: 255.255.255.0 (LAN)
eth0: IP: 10.0.1.1, GW: 10.0.1.254, NM: 255.255.255.0 (ISP1 - ADSL Router)
eth2: IP: 10.0.2.1, GW: 10.0.2.254, NM: 255.255.255.0 (ISP2 - ADSL Router)

/etc/sysctl.conf :

# Controls IP packet forwarding
net.ipv4.ip_forward = 1

# Controls source route verification
net.ipv4.conf.default.rp_filter = 0

# Do not accept source routing
net.ipv4.conf.default.accept_source_route = 0

# Controls the use of TCP syncookies
net.ipv4.tcp_syncookies = 1

# Ignoring broadcasts request
net.ipv4.icmp_echo_ignore_broadcasts = 1
net.ipv4.icmp_ignore_bogus_error_messages = 1

/ etc / iproute2 / rt_tables:

#
# reserved values
#
255     local
254     main
253     default
0       unspec
#
# local
#
#1      inr.ruhep
2 ISP1
3 ISP2

/ etc / sysconfig / network-scripts / route-eth0 :

10.0.1.0/24 dev eth0 src 10.0.1.1 table ISP1
default via 10.0.1.254 dev eth0 table ISP1

/ etc / sysconfig / network-scripts / route-eth2 :

10.0.2.0/24 dev eth2 src 10.0.2.1 table ISP2
default via 10.0.2.254 dev eth2 table ISP2

/ etc / sysconfig / network-scripts / rule-eth0 :

fwmark 2 table ISP1
from 10.0.1.1 table ISP1

/ etc / sysconfig / network-scripts / rule-eth2 :

fwmark 3 table ISP2
from 10.0.2.1 table ISP2

/ etc / sysconfig / iptables :

*filter
:INPUT DROP [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
# Basic Rules
-A INPUT -i lo -j ACCEPT
-A INPUT -i eth0 -m state --state RELATED,ESTABLISHED -j ACCEPT
-A INPUT -i eth2 -m state --state RELATED,ESTABLISHED -j ACCEPT

# SSH
-A INPUT -i eth0 -m tcp -p tcp --dport 22 -j ACCEPT
-A INPUT -i eth2 -m tcp -p tcp --dport 22 -j ACCEPT

# OpenVPN
-A INPUT -i eth0 -m udp -p udp --dport 1194 -j ACCEPT
-A INPUT -i eth2 -m udp -p udp --dport 1194 -j ACCEPT

# Allow everything from LAN
-A INPUT -i eth1 -j ACCEPT

# Allow everything from the VPN
-A INPUT -i tun0 -j ACCEPT

# Default Drop on everything else
-A INPUT -j DROP

# Allow forwarding from LAN and VPN
-A FORWARD -i eth1 -j ACCEPT
-A FORWARD -i tun0 -j ACCEPT

# Allow all outbound traffic
-A OUTPUT -o lo -j ACCEPT
-A OUTPUT -o eth1 -j ACCEPT
COMMIT

*nat
:PREROUTING ACCEPT [0:0]
:POSTROUTING ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
# DNAT to Developer Box (SSH Server)
-A PREROUTING -i eth0 -p tcp -m tcp --dport 2222 -j DNAT --to-destination 10.0.0.200:2222
-A PREROUTING -i eth2 -p tcp -m tcp --dport 2222 -j DNAT --to-destination 10.0.0.200:2222

# SNAT
-A POSTROUTING -o eth0 -j SNAT --to-source 10.0.1.1
-A POSTROUTING -o eth2 -j SNAT --to-source 10.0.2.1
COMMIT

*mangle
:PREROUTING ACCEPT [0:0]
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
:POSTROUTING ACCEPT [0:0]
# Mark Based Routing? (based on NerdBoys site)
-A PREROUTING -j CONNMARK --restore-mark
-A PREROUTING --match mark --mark 2 -j ACCEPT
-A PREROUTING -i eth0 -j MARK --set-mark 2
-A PREROUTING --match mark --mark 3 -j ACCEPT
-A PREROUTING -i eth2 -j MARK --set-mark 3
-A PREROUTING -j CONNMARK --save-mark
COMMIT

Der Lastausgleich ist mit dem gwping bash-Skript möglich, das im Wesentlichen die 2 Wans (eth0 und eth2) überwacht und die Standardrouten und -gewichte auf dem Server wie folgt einrichtet (während der Lastausgleich oder die 2 Wans aktiv sind):

ip route replace default scope global nexthop via 10.0.1.1 dev eth0 weight 1 nexthop via 10.0.2.1 dev eth1 weight 1

Das Problem, das ich habe, ist, dass selbst mit diesem Setup, dem viele Leute zustimmen, das richtige ist. Ich habe immer noch Probleme mit dem Zugriff auf Dienste innerhalb des Netzwerks von außen (insbesondere die SSH-Entwickler-Box und die OpenVPN-Box), selbst wenn die Pakete werden "markiert" und entsprechend geroutet die antwort von der dev box geht immer auf den falschen pfad. Ich weiß nicht, ob ich irgendetwas in der Mangle oder im Nat-Bereich vermisse oder ob ich quellbasiertes Routing überhaupt missverstehe. Wenn jemand weiß, wie man diese Arbeit dementsprechend macht, wird er sich darüber freuen.

Meine Quellen für dieses Setup sind:

lartc.org/lartc.html#LARTC.RPDB.MULTIPLE-LINKS
fatalsite.net/?p=90
nerdboys.com/2006/05/05/conning-the-mark-multiwan-connections-using-iptables-mark-connmark-and-iproute2/
policyrouting.org/PolicyRoutingBook/ONLINE/CH08.web.html
unix.stackexchange.com/questions/58635/iptables-set-mark-route-diferent-ports-through-different-interfaces
unix.stackexchange.com/questions/22770/two-interfaces-two-addresses-two-gateways
bulma.net/body.phtml?nIdNoticia=2145

Mit freundlichen Grüßen

PS1: Ich habe eine Website gefunden, auf der steht, dass die Markierungen in der Routing-Tabelle + 1 von den iptables-Markierungen abweichen sollten (kim.attr.ee/2010/08/source-based-policy-routing-on-centos.html) Ist das wahr? oder diese Website ist super-falsch.


Update 15.08.2013 22:15 Uhr

Nach mehr Recherche und Debugging habe ich eine Website gefunden, auf der steht, dass ich vergessen habe, den SNAT-Teil in der Post-Routing-Tabelle hinzuzufügen. Deshalb füge ich diese Regeln der iptables-Konfiguration hinzu:

-A POSTROUTING --match mark --mark 2 -j SNAT --to-source 10.0.1.1
-A POSTROUTING --match mark --mark 3 -j SNAT --to-source 10.0.2.1

Ich kann mich aber immer noch nicht von außerhalb des Netzwerks mit der Devbox verbinden. Auf der positiven Seite gibt ein iptables -t nat -nvL POSTROUTING einen Hinweis auf die Funktionsweise von connmark-basiertem Policy-Routing. Vielleicht hängt es also mit dem ISP1- und ISP2-Router-Edge zusammen:

Chain POSTROUTING (policy ACCEPT 520 packets, 56738 bytes)
 pkts bytes target     prot opt in     out     source               destination
    0     0 SNAT       all  --  *      *       0.0.0.0/0            0.0.0.0/0           MARK match 0x2 to:10.0.1.1
    6   312 SNAT       all  --  *      *       0.0.0.0/0            0.0.0.0/0           MARK match 0x3 to:10.0.2.1
  903 70490 SNAT       all  --  *      eth0    0.0.0.0/0            0.0.0.0/0           to:10.0.1.1
  931 78070 SNAT       all  --  *      eth2    0.0.0.0/0            0.0.0.0/0           to:10.0.2.1

Außerdem füge ich weitere Informationen aus meinem Setup hinzu, bitte wirft mir jemand einen Lebensretter zu, da mir die Ideen ausgehen ...>. <

ip route show :

10.8.0.2 dev tun0  proto kernel  scope link  src 10.8.0.1
10.0.2.0/24 dev eth2  proto kernel  scope link  src 10.0.2.1
10.0.0.0/24 dev eth1  proto kernel  scope link  src 10.0.0.1
10.8.0.0/24 via 10.8.0.2 dev tun0
10.0.1.0/24 dev eth0  proto kernel  scope link  src 10.0.1.1
169.254.0.0/16 dev eth2  scope link
default
        nexthop via 10.0.1.254  dev eth0 weight 1
        nexthop via 10.0.2.254  dev eth2 weight 1

IP-Regel zeigen:

0:      from all lookup 255
1024:   from all fwmark 0x2 lookup ISP1
1025:   from all fwmark 0x3 lookup ISP2
2024:   from 10.0.1.1 lookup ISP1
2025:   from 10.0.2.1 lookup ISP2
32766:  from all lookup main
32767:  from all lookup default

Neue Quellen:

sarcasmasaservice.com/2013/04/linux-routing-capabilities-my-abuse-thereof/

Mit freundlichen Grüßen

CentOS_noob
quelle
Könnten Sie vielleicht den Titel ändern und die Centos entfernen, indem Sie ihn durch Linux ersetzen? Ich habe genau das verwendet, um auf Debian / Devuan
Hvisage

Antworten:

5

Gut...

Nach Tausenden von Stunden Debugging, verschiedenen Setups und 72 Stunden intensiver Tests in der Produktion konnte ich die richtige Lösung / das richtige Setup finden. Das Problem lag in den Iptables-Regeln (Abschnitt Mangle). Die Pakete wurden anscheinend direkt beim Eingang markiert Aber als sie herauskamen, gab es keine für dnat'ted-Pakete, jedenfalls ist es hier meine endgültige funktionierende Lösung für mein Problem:

/ etc / sysconfig / iptables :

*filter
:INPUT DROP [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
# Basic Rules
-A INPUT -i lo -j ACCEPT
-A INPUT -i eth0 -m state --state RELATED,ESTABLISHED -j ACCEPT
-A INPUT -i eth2 -m state --state RELATED,ESTABLISHED -j ACCEPT

# SSH
-A INPUT -i eth0 -m tcp -p tcp --dport 22 -j ACCEPT
-A INPUT -i eth2 -m tcp -p tcp --dport 22 -j ACCEPT

# OpenVPN
-A INPUT -i eth0 -m udp -p udp --dport 1194 -j ACCEPT
-A INPUT -i eth2 -m udp -p udp --dport 1194 -j ACCEPT

# Allow everything from LAN
-A INPUT -i eth1 -j ACCEPT

# Allow everything from the VPN
-A INPUT -i tun0 -j ACCEPT

# Default Drop on everything else
-A INPUT -j DROP

# Allow forwarding from LAN and VPN
-A FORWARD -i eth1 -j ACCEPT
-A FORWARD -i tun0 -j ACCEPT

# Allow all outbound traffic
-A OUTPUT -o lo -j ACCEPT
-A OUTPUT -o eth1 -j ACCEPT
COMMIT

*nat
:PREROUTING ACCEPT [0:0]
:POSTROUTING ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
# DNAT to Developer Box (SSH Server)
-A PREROUTING -i eth0 -p tcp -m tcp --dport 2222 -j DNAT --to-destination 10.0.0.200:2222
-A PREROUTING -i eth2 -p tcp -m tcp --dport 2222 -j DNAT --to-destination 10.0.0.200:2222

# SNAT
-A POSTROUTING -o eth0 -j SNAT --to-source 10.0.1.1
-A POSTROUTING -o eth2 -j SNAT --to-source 10.0.2.1
COMMIT

*mangle
:PREROUTING ACCEPT [0:0]
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
:POSTROUTING ACCEPT [0:0]
# CONNMARK Source Based Routing
-A PREROUTING -i eth0 -m state --state NEW,RELATED,ESTABLISHED -d 10.0.1.1 -j CONNMARK --set-mark 0x2
-A PREROUTING -i eth2 -m state --state NEW,RELATED,ESTABLISHED -d 10.0.2.1 -j CONNMARK --set-mark 0x3
-A PREROUTING -i eth1 -m connmark --mark 0x2 -j CONNMARK --restore-mark
-A PREROUTING -i eth1 -m connmark --mark 0x3 -j CONNMARK --restore-mark
-A OUTPUT -m state --state ESTABLISHED,RELATED -j CONNMARK --restore-mark
COMMIT

Zusätzlich zu den vorherigen Einstellungen für iproute und gwping (für Link Load Balancing und Failover) wurden die Lösungen dank der Quellen [1] und [2] ermöglicht, die mich auf einen anderen Teil hinwiesen (Luca Gibelli für Der PREROUTING-Teil und Karl Bowden für den OUTPUT-Teil) der Lösung, auch ich lebe hier einige weitere Quellen für andere Websites, die mich in die richtige Richtung weisen. Hoffe das hilft einem anderen Sysadmin in der Zukunft.

Mit freundlichen Grüßen

Quellen:

[1]www.nervous.it/2010/09/dnat-and-ip-source-routing-woes/
[2]blog.khax.net/2009/12/01/multi-gateway-balancing-with-iptables/
[3]home.regit.org/netfilter-en/links-load-balancing/
[4]mailman.ds9a.nl/pipermail/lartc/2006q2/018964.html
[5]web.archive.org/web/20120320115329/http://versa.net.au/index.php?option=com_content&task=view&id=21&Itemid=34

Update 10.10.2013

OpenVPN erfordert eine zusätzliche Konfigurationsanweisung, um mit einer Mehrfach-WAN-Einrichtung (wie der vorherigen) arbeiten zu können. Fügen Sie daher einfach die Option multihome in Ihrer server.conf hinzu (OpenVPN> = 2.1) bestimmte IP) und Sie sind gut zu gehen.

CentOS_noob
quelle
Danke, die -t mangle -A OUTPUT ... -j CONNMARK --Restore-Marke war etwas, was ich in meinem Setup fehlte :)
Hvisage
0

nur ein tipp für dich ich mache genau das gleiche nur ohne den lastausgleich und 3 wan links und ich benutze nicht mal iptables für alles. Ich finde es viel effektiver, einfaches richtlinienbasiertes Routing und Socat zu verwenden

meine rt_tables:

100     lan
102     wireless
103     wan1
104     wan2
105     wan3

in den Schnittstellen für jede WAN-Verbindung:

/bin/ip route add <wan network id> dev eth0 src <wan host ip> table wan1
/bin/ip route add default via <wan gateway address> table wan1
/bin/ip rule add from <wan host ip> table wan1

In den Schnittstellen unten für jede WAN-Verbindung:

/bin/ip route del default via <wan gateway address> table wan1
/bin/ip rule del from <wan host ip> table wan1

Um einen LAN-Client zu zwingen, einen bestimmten Link zu entfernen, schreiben Sie folgendes in Ihr Interface-Up-Skript:

/bin/ip rule add from <lan client ip> table <wan table number of link to force it through>

und das im down script:

/bin/ip rule del from <lan client ip> table <wan table number of link to force it through>

Um eine eingehende Verbindung zu einem bestimmten Computer (z. B. einem Webserver) zu senden, fügen Sie dem rc.local so etwas hinzu (dies kann ausgeführt werden, ob der Link aktiv ist oder nicht).

exec socat -T15 tcp4-listen:80,reuseaddr,fork tcp:<lan host ip to send it to>:80 >> /var/log/socat-web.log 2>&1

Aktivieren Sie dann die IP-Weiterleitung und -Maskerade sowie alle anderen Firewall-Regeln, die Sie benötigen, und legen Sie los

Auf Ubuntu können Sie sogar einen Startjob für das Socat erstellen. Dies ist meine /etc/init/socat-web.conf:

description "socat web port tunnel"
author      "jacqueline"

start on started mountall
stop on shutdown
respawn
respawn limit 99 5

script
    export HOME="/root"
    exec socat -T15 tcp4-listen:80,reuseaddr,fork tcp:192.168.0.97:80 >> /var/log/socat-web.log 2>&1
end script

post-start script
   # Optionally put a script here that will notifiy you socat has (re)started
end script
Jacqueline Loriault
quelle
0

@CentOS_noob

Erstens, tolle Arbeit und vielen Dank für das Teilen, vielen Dank! Ich hatte jahrelang damit zu kämpfen. :)

Wenn Sie bestimmte Dienste über einen ausgewählten Link weiterleiten möchten, können Sie dies vor dem Hintergrund Ihrer aktuellen MARKING-Regeln tun.

iptables -t mangle -A PREROUTING -i br1 -s 10.1.1.2 -p tcp --dport 80 -m state --state NEW,RELATED,ESTABLISHED -j CONNMARK --set-mark 0x3
iptables -t mangle -A PREROUTING -i br1 -s 10.1.1.2 -p icmp  -j CONNMARK --set-mark 0x4

Wo:

br1 - is LAN interface
10.1.1.2 - is LAN's IP of some host.
Michal Sokolowski
quelle