Rozhodování o směrování probíhá výhradně podle cílové IP adresy.
To není úplně pravda, i bez pravidel lze zohlednit ToS.
jsou i směrovací tabulky pojmenovány pomocí unikátního číselného identifikátoru. Ten je na jádrech 2.6 a novějších dvaatřicetibitový
Přesněji "až" od jádra 2.6.19.
protocol
... podle směrovacího protokolu
Klíčové slovo protocol
není součást selektoru (tj. podmínky, která definuje, na které pakety se pravidlo aplikuje), ale "action". Podobně jako u routy je to jen informativní položka, která říká, jaký je původ pravidla (viz tabulka rtnl_rtprot_tab[]
v iproute2).
například volba from nebude fungovat pro originující provoz, protože v době prohledávání směrovací tabulky ještě není místní IP adresa známa – ta je určena až po rozhodnutí, kterým směrem datagram odejde
Tady by bylo vhodné upřesnit, že výraz originující provoz v této větě znamená jen první paket daného flow (např. TCP spojení), protože všechny další pakety už mají zdrojovou adresu určenou ještě před směrováním. Toho se v praxi využívá třeba u klasického příkladu na load balancing mezi dvěma ISP: pakety, které mají zdrojovou adresu danou předem, se routují přes odpovídající gateway (musejí, druhý ISP by je pravděpodobně zahodil), jen ty, kde bude určená podle směrování, "propadnou" do tabulky, kde se dělá load balancing.
Zkusil jsem "klasiký příklad na load balancing", ale ten řeší pouze výstupní spojení. Já to mám na hraničním routeru s firewalem a NATem, který příchozí provoz směřuje na DMZ. Ale tento "klasický příklad" mi odpovědi na příchozí spojení rozhazuje "náhodně" na oba ISP. Je mi jasné, že příchozí spojení musím přiřazovat do odpovídajících tabulek, ale jak?
Mám tam:
### https://lartc.org/howto/lartc.rpdb.multiple-links.html ip route add ${ISP1_NET}/${ISP1_NETMASK} dev ${ISP1_IFACE} src ${ISP1_IP} table 110 ip route add ${ISP2_NET}/${ISP2_NETMASK} dev ${ISP2_IFACE} src ${ISP2_IP} table 120 # tohle tam uz je zrejme od "ip addr add" #ip route add ${ISP1_NET}/${ISP1_NETMASK} dev ${ISP1_IFACE} src ${ISP1_IP} #ip route add ${ISP2_NET}/${ISP2_NETMASK} dev ${ISP2_IFACE} src ${ISP2_IP} ip route add default via ${ISP1_ROUTER_IP} table 110 ip route add default via ${ISP2_ROUTER_IP} table 120 # a tohle tam nechceme, viz Load balancing ##ip route add default via ${ISP1_ROUTER_IP} ip rule add from ${ISP1_IP} table 110 ip rule add from ${ISP2_IP} table 120 ip rule add to ${ISP1_IP} table 110 ip rule add to ${ISP2_IP} table 120 ip rule add iif ${ISP1_IFACE} table 110 ip rule add iif ${ISP2_IFACE} table 120 # mistni pakety vystupujici danym iface pouziji odpovidajici routovaci tabulku (napr. ping -I iface) ip rule add oif ${ISP1_IFACE} table 110 ip rule add oif ${ISP2_IFACE} table 120 # Load balancing ip route add default scope global \ nexthop via ${ISP1_ROUTER_IP} dev ${ISP1_IFACE} weight 1 \ nexthop via ${ISP2_ROUTER_IP} dev ${ISP2_IFACE} weight 1
Může mi někdo poradit?
O to by se měla postarat právě ta dvě pravidla
ip rule add from ${ISP1_IP} table 110 ip rule add from ${ISP2_IP} table 120
která ty pakety pošlou do tabulek, kde je default route přes příslušného ISP.
Jeden možný problém, který mne napadá, je problém s maškarádou, ale to by se odpovědi na příchozí spojení stát nemělo. Nebo by to nefungovalo, pokud by tahle dvě pravidla nebyla před tím standardním, které všechno pošle do main
.
Jsme zcela stejného názoru, jen to nefunguje. Připojuji nastavení NATU, snad to něco napoví (je zjednodušené jen na http, ale to by nemělo vadit):
### POSTROUTING ### iptables -t nat -A POSTROUTING -m state --state ESTABLISHED,RELATED -j ACCEPT iptables -t nat -A POSTROUTING -o $ISP1_IFACE -j SNAT --to-source $ISP1_IP iptables -t nat -A POSTROUTING -o $ISP2_IFACE -j SNAT --to-source $ISP2_IP ### PREROUTING ### iptables -t nat -A PREROUTING -m state --state ESTABLISHED,RELATED -j ACCEPT ## uplatni se pro ISP1, ISP2 iptables -t nat -N PREROUTING_PUBLIC # HTTP server iptables -t nat -A PREROUTING_PUBLIC -p TCP --dport $PORT_HTTP -j DNAT --to-destination $DMZ_HTTP_IP iptables -t nat -A PREROUTING -d $ISP1_IP -j PREROUTING_PUBLIC iptables -t nat -A PREROUTING -d $ISP2_IP -j PREROUTING_PUBLIC ### FORWARD chain ### iptables -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT iptables -N INET_DMZ_packets iptables -A FORWARD -i $ISP1_IFACE -o $DMZ_IFACE -j INET_DMZ_packets iptables -A FORWARD -i $ISP2_IFACE -o $DMZ_IFACE -j INET_DMZ_packets # HTTP server iptables -A INET_DMZ_packets -p TCP -d $DMZ_HTTP_IP --dport $PORT_HTTP -j ACCEPT iptables -A INET_DMZ_packets -j DROP
Na tenhle use case jsem musel rozchodit jeste connection marking. WAN tabulky maji u me cislo 4 a 5, WAN rozhrani jsou sfp0.3
a ppp999
.
# 2020-11-19 @rzajic, adapted from https://www.system-rescue.org/networking/Load-balancing-using-iptables-with-connmark/ iptables -t mangle -N CONNMARK4 iptables -t mangle -F CONNMARK4 iptables -t mangle -A CONNMARK4 -j MARK --set-mark 4 iptables -t mangle -A CONNMARK4 -j CONNMARK --save-mark #iptables -t mangle -A CONNMARK4 -j LOG --log-prefix 'iptables-mark4: ' --log-level info iptables -t mangle -N CONNMARK5 iptables -t mangle -F CONNMARK5 iptables -t mangle -A CONNMARK5 -j MARK --set-mark 5 iptables -t mangle -A CONNMARK5 -j CONNMARK --save-mark #iptables -t mangle -A CONNMARK5 -j LOG --log-prefix 'iptables-mark5: ' --log-level info iptables -t mangle -N RESTOREMARK iptables -t mangle -F RESTOREMARK iptables -t mangle -A RESTOREMARK -j CONNMARK --restore-mark #iptables -t mangle -A RESTOREMARK -j LOG --log-prefix 'restore-mark: ' --log-level info iptables -t mangle -D PREROUTING ! -i ppp999,sfp0.3 -m state --state ESTABLISHED,RELATED -j RESTOREMARK iptables -t mangle -D PREROUTING -i ppp999 -m state --state NEW -j CONNMARK4 iptables -t mangle -D PREROUTING -i sfp0.3 -m state --state NEW -j CONNMARK5 iptables -t mangle -A PREROUTING ! -i ppp999,sfp0.3 -m state --state ESTABLISHED,RELATED -j RESTOREMARK iptables -t mangle -A PREROUTING -i ppp999 -m state --state NEW -j CONNMARK4 iptables -t mangle -A PREROUTING -i sfp0.3 -m state --state NEW -j CONNMARK5 # routing mark X via table X ip rule add from all fwmark 0x4 lookup 4 ip rule add from all fwmark 0x5 lookup 5
Co mi nefunguje: mtr
skrze "sekundarni" rozhrani, pokud specifikuji jeho IP.
Tohle funguje a routuje se sekundarnim pripojenim skrze sfp0.3
:
traceroute -I -i sfp0.3 nix.cz
Tohle je routovane primarnim interfacem, i kdyz by melo byt sekundarnim.
mtr -4 -a SECON.DARY.PUBLIC.IP nix.cz
ip rule
vypada takto:
0: from all lookup local 32724: from all to PRI.MARY.PUBLIC.IP lookup wan_primary 32725: from all to SECON.DARY.PUBLIC.IP lookup wan_secondary 32726: from 192.168.245.0/24 lookup wan_secondary 32727: from 192.168.247.0/24 lookup wan_secondary 32728: from all fwmark 0x5 lookup wan_secondary 32729: from SECON.DARY.PUBLIC.IP lookup wan_secondary 32730: from all ipproto udp sport 9201 lookup wan_secondary 32761: from PRI.MARY.PUBLIC.IP lookup wan_primary 32762: from all fwmark 0x4 lookup wan_primary 32763: from 192.168.246.0/24 lookup wan_primary 32764: from 192.168.248.0/24 lookup wan_primary 32766: from all lookup main 32767: from all lookup default
Děkuji, tohle vypadá nadějně a zřejmě jste mi ušetřil cca měsíc bádání.
Chtěl jsem se podívat na https://www.system-rescue.org/networking/Load-balancing-using-iptables-with-connmark/ z nějž jste vycházel, ale už zřejmě neexistuje.
Naštěstí existuje web archive. :)
https://web.archive.org/web/20200920043606/https://www.system-rescue.org/networking/Load-balancing-using-iptables-with-connmark/
Je nějaký vysvětlující článek o klíčových slovech via a nexthop pro route?
Nějak nerozumím xyzvia 192.168.1.1 dev enp0s3 i když jsem četl man.
Když se k tomu přidá nexthop a src už je to celkem guláš. Src chápu.
u toho via nerozumím jestli to posílá na rozhraní 192.168.1.1 nebo na enp0s3 nebo daná adresa je na enp0s3 a proč se tam tedy uvádí obojít.
Směrovací tabulka slouží k rozhodnutí, kam se daný provoz (paket) pošle. Obvykle se rozhoduje podle cílové sítě, tedy podle jejího prefixu. Pokud není cílová síť přímo dostupná (nejsme její součástí), musí být zvoleno odchozí rozhraní (dev) a také sousední směrovač (via, což je nexthop), kterému ten paket pošleme.
Čili odpověď zní: posílá se ven místním rozhraním enp0s3 na stroj s IP adresou 192.168.1.1. Samozřejmě to znamená, že se pro tu IP adresu musí nejdřív pomocí ARP (nebo ND v IPv6) zjistit odpovídající MAC adresa a pak se sestaví rámec se správnou cílovou MAC a do něj se zabalí ten paket, který chceme odeslat do světa. Pak se to celé vyšle na enp0s3. Je to takhle jasné?
Dobré vysvětlení, pochopel jsem to i z následujícího stackoverflow threadu. Zapomněl jsem na to, že pro odeslání paketu je potřeba znát MAC adresu.
přesto by mě zajímalo
použití nexthop... podle násedujícího předpisu
ROUTE := NODE_SPEC [ INFO_SPEC ]
INFO_SPEC := NH OPTIONS FLAGS [ nexthop NH ] ...
NH := [ encap ENCAP ] [ via [ FAMILY ] ADDRESS ] [ dev STRING ] [ weight NUMBER ] NHFLAGS
Příklad je i dokonce i v této diskuzi o balancování ISP
## https://lartc.org/howto/lartc.rpdb.multiple-links.html
##ip route add default via ${ISP1_ROUTER_IP}
ip route add default scope global \
nexthop via ${ISP1_ROUTER_IP} dev ${ISP1_IFACE} weight 1 \
nexthop via ${ISP2_ROUTER_IP} dev ${ISP2_IFACE} weight 1
(První nemá nexthop, druhý ano)
vlákno stack overflowa příslušný obrázek
13. 2. 2022, 17:26 editováno autorem komentáře