Názory k článku Policy-based routing v Linuxu: směrování provozu pod kontrolou

  • Článek je starý, nové názory již nelze přidávat.
  • 11. 1. 2022 8:36

    Michal Kubeček

    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.

  • 12. 1. 2022 15:09

    pet I.

    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?

  • 12. 1. 2022 20:15

    Michal Kubeček

    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.

  • 13. 1. 2022 10:50

    pet I.

    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
  • 13. 1. 2022 20:50

    Radek Zajíc

    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
  • 1. 2. 2022 16:43

    `

    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.

  • 2. 2. 2022 9:15

    Petr Krčmář

    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é?

  • 13. 2. 2022 17:23

    `

    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