logo elektroda
logo elektroda
X
logo elektroda
REKLAMA
REKLAMA
Adblock/uBlockOrigin/AdGuard mogą powodować znikanie niektórych postów z powodu nowej reguły.

Jak napisać skrypty QOS z HFSC i IMQ dla DSL 1-4 Mb z podziałem na usługi?

wluckyluk 09 Lis 2007 19:51 3012 1
REKLAMA
  • #1 4463343
    wluckyluk
    Poziom 11  
    Posty: 13
    Witam,

    Mam zadanie na studiach, napisać skrypty QOS z podziałem na usługi i userów,
    dla najczęściej spotykanych łącz dla małych ip, czyli coś około DSL 1 - 4 mb,
    czy tez NEO i co tam niepopadnie jest stosowane.

    Jako że nie jestem samolubem postanowiłem zrobić przy okazji HOWTO i udostępnić je w necie dla potomnych, aby nie musieli się już później męczyć tak jak ja.

    Dużo takich skryptów w sieci już lata, ale trudno dogrzebać się czegoś z równoczesnym podziałem na userów i usługi, a zwlaszcza zeby bylo dobrze opisane.
    Usługi chciałbym zmarkować za pomocą layer7 a nie po portach, bo wiadomo jacy userzy są (Ale o tym dalej).

    Znalazlem już coś w sieci, ale jest to zrobione za pomocą filtrów po portach.

    Proszę więc wszystkich którzy posiadają pomocną wiedzę w udziale w powstaniu HOWTO, oraz o sprawdzenie dotychczasowej pracy.
    Wszelkie komentarze są mile widziane, tym bardziej że na HFSC mało się znam wcześniej lizniete mialem cos o htb.

    Poniżej zaprezentuje co już posiadam. (większość w oparciu o skrypt Rafała Rajsa)


    Plik ze zmiennymi (łącza, ip userów itp): rc.zmienne

    Problem, czy ustawiać 90% lacza tak jak sie robilo w htb ?
    #!/bin/sh
    
    # definiujemy interfejsy
    ZEW=eth0 #publiczny do neta
    WEW=eth1 #wewnetrzny LAN do lodkow
    
    LAN="192.168.2.0/24"	# klasa lan
    IP_ZEW="83.13.131.61"	#ip publiczne
    
    # upload i download lacza
    NET_DOWNLOAD=4096
    NET_UPLOAD=512
    
    # wylicz 90% ze wzgledu na opoznienia (czy dobry zapis ??)
    MAX_DOWNLOAD=$[$NET_DOWNLOAD*90/100]
    MAX_UPLOAD=$[$NET_UPLOAD*90/100]
    
    MARK_START=0
    MAX_RESERVE=20
    
    # to moze pozniej wykorzystam do ograniczenia liczby polaczen na wysokich portach
    MAX_CONNS=40
    
    ###
    
    
    L_USERS=3 # liczba userow + serwer
    
    #user 1
    USER_IP[1]="10.1.1.50"
    #user 2
    USER_IP[2]="10.1.1.60"
    #serwer
    USER_IP[3]=$IP_ZEW 
    
    ###
    
    IPTABLES=iptables
    TC=tc



    Plik z skryptem hfsc: rc.hfsc
    #!/bin/sh
    . ???/rc.zmienne # zmienic ??? na lokalizacje pliku
    
    
    ###
    #download do imq0
    TCQ_D="$TC qdisc add dev imq0"
    TCC_D="$TC class add dev imq0"
    TCF_D="$TC filter add dev imq0 parent 1: protocol ip"
    
    #upload do imq1
    TCQ_U="$TC qdisc add dev imq1"
    TCC_U="$TC class add dev imq1"
    TCF_U="$TC filter add dev imq1 parent 1: protocol ip"
    
    
    #czyszczenie kolejki
    #$TC qdisc del root dev imq0 
    #$TC qdisc del root dev imq1
    
    #dodajemy glowne kolejki 
    $TCQ_D root handle 1: hfsc default 500 
    $TCQ_U root handle 1: hfsc default 500 
    

    co oznacza default 500 ?
    
    # download
    $TCC_D parent 1: classid 1:1 hfsc sc rate ${MAX_DOWNLOAD}kbit ul rate ${MAX_DOWNLOAD}kbit 
    
    # upload
    $TCC_U parent 1: classid 1:1 hfsc sc rate ${MAX_UPLOAD}kbit ul rate ${MAX_UPLOAD}kbit 
    
    #default reserve queue
    $TCC_D parent 1:1 classid 1:500 hfsc sc rate ${MAX_RESERVE}kbit ul rate ${MAX_RESERVE}kbit 
    $TCC_U parent 1:1 classid 1:500 hfsc sc rate ${MAX_RESERVE}kbit ul rate ${MAX_RESERVE}kbit 
    
    
    # download dla usera
    USER_UPLOAD=$[$MAX_UPLOAD/($L_USERS+1)]
    
    # upload dla usera
    USER_DOWNLOAD=$[$MAX_DOWNLOAD/($L_USERS+1)]
    
    
    # podklasy z podziałem: 55% ruch wazny, 25% reszta ()
    
    USER_D_PRIOR=$[$USER_DOWNLOAD*55/100]
    USER_D_RESZTA=$[$USER_DOWNLOAD*25/100]
    
    USER_U_PRIOR=$[$USER_UPLOAD*55/100]
    USER_U_RESZTA=$[$USER_UPLOAD*25/100]

    1.moglby byc podzial na trzy klasy wazny/reszta/p2p
    2.czy % nie powinny sie sumowac do 100 ?
    
    #numery podklas
    N_CLASS_D=10
    N_CLASS_U=40
    
    N_CLASS_D_1=70
    N_CLASS_D_2=100
    N_CLASS_U_1=130
    N_CLASS_U_2=160
    
    N_CLASS_D_1_Q=190
    N_CLASS_D_2_Q=220
    N_CLASS_U_1_Q=250
    N_CLASS_U_2_Q=280
    
    i=1
    j=1
    
    
    #dla kazdego usera w petelce
    while [ $i -le $L_USERS ]
    do
    
      #ograniczenie userow na IP
      $TCC_D parent 1:1 classid 1:$[$N_CLASS_D+$i] hfsc sc rate ${USER_DOWNLOAD}kbit ul rate ${MAX_DOWNLOAD}kbit #1 user
      $TCC_U parent 1:1 classid 1:$[$N_CLASS_U+$i] hfsc sc rate ${USER_UPLOAD}kbit ul rate ${MAX_UPLOAD}kbit #1 user
    
      # podzielic to na kolejne dwie klasy. Maksymalne opoznienie w waznej klasie! (prosze sprawdzic czy dobry zapis, komentarze porządane)
      #download
      $TCC_D parent 1:$[$N_CLASS_D+$i] classid 1:$[$N_CLASS_D_1+$i] hfsc sc umax 1500b dmax 20ms rate ${USER_D_PRIOR}kbit ul rate ${MAX_DOWNLOAD}kbit # wazne
      $TCC_D parent 1:$[$N_CLASS_D+$i] classid 1:$[$N_CLASS_D_2+$i] hfsc sc rate ${USER_D_RESZTA}kbit ul rate ${MAX_DOWNLOAD}kbit #reszta
      #upload	
      $TCC_U parent 1:$[$N_CLASS_U+$i] classid 1:$[$N_CLASS_U_1+$i] hfsc sc umax 1500b dmax 20ms rate ${USER_U_PRIOR}kbit ul rate ${MAX_UPLOAD}kbit # wazne
      $TCC_U parent 1:$[$N_CLASS_U+$i] classid 1:$[$N_CLASS_U_2+$i] hfsc sc rate ${USER_U_RESZTA}kbit ul rate ${MAX_UPLOAD}kbit # reszta
      
      # fifo dla waznych, sfq dla reszty (www i fifo nie pasuje stad 3 klasy porzadane, perturb to priorytet ?)
      $TCQ_D parent 1:$[$N_CLASS_D_1+$i] handle $[$N_CLASS_D_1_Q+$i]:0 pfifo
      $TCQ_D parent 1:$[$N_CLASS_D_2+$i] handle $[$N_CLASS_D_2_Q+$i]:0 sfq perturb 10
      $TCQ_U parent 1:$[$N_CLASS_U_1+$i] handle $[$N_CLASS_U_1_Q+$i]:0 pfifo
      $TCQ_U parent 1:$[$N_CLASS_U_2+$i] handle $[$N_CLASS_U_2_Q+$i]:0 sfq perturb 10
    
    
    
    
      #ruch kazdego usera kieruj do odpowiednich kolejek
    
      #upload waznego ruchu dla usera ( mozna dodac SSH, WWW, CS etc)
      $TCF_U prio 3 u32 match ip protocol 1 0xff match ip src ${USER_IP[${i}]} flowid 1:$[$N_CLASS_U_1+$i]
      $TCF_U prio 3 u32 match ip sport 22 0xffff match ip src ${USER_IP[${i}]} flowid 1:$[$N_CLASS_U_1+$i]
      $TCF_U prio 3 u32 match ip dport 22 0xffff match ip src ${USER_IP[${i}]} flowid 1:$[$N_CLASS_U_1+$i]
      $TCF_U prio 3 u32 match ip sport 53 0xffff match ip src ${USER_IP[${i}]} flowid 1:$[$N_CLASS_U_1+$i]
      $TCF_U prio 3 u32 match ip dport 53 0xffff match ip src ${USER_IP[${i}]} flowid 1:$[$N_CLASS_U_1+$i]
    
      #upload ogolny
      $TCF_U prio 20 u32 match ip src ${USER_IP[${i}]} flowid 1:$[$N_CLASS_U_2+$i]
      
    
      #download waznego ruchu dla usera ( mozna dodac SSH, WWW, CS etc)
      $TCF_D prio 2 u32 match ip protocol 1 0xff match ip dst ${USER_IP[${i}]} flowid 1:$[$N_CLASS_D_1+$i]
      $TCF_D prio 2 u32 match ip sport 22 0xffff match ip dst ${USER_IP[${i}]} flowid 1:$[$N_CLASS_D_1+$i]
      $TCF_D prio 2 u32 match ip dport 22 0xffff match ip dst ${USER_IP[${i}]} flowid 1:$[$N_CLASS_D_1+$i]
      $TCF_D prio 2 u32 match ip sport 53 0xffff match ip dst ${USER_IP[${i}]} flowid 1:$[$N_CLASS_D_1+$i]
      $TCF_D prio 2 u32 match ip dport 53 0xffff match ip dst ${USER_IP[${i}]} flowid 1:$[$N_CLASS_D_1+$i]
    
      #download ogolny dla usera
      $TCF_D prio 30 u32 match ip dst ${USER_IP[${i}]} flowid 1:$[$N_CLASS_D_2+$i]
    

    ### zamiast tego co powyzej chcialbym uzyc marka z layer7 czyli moze dla upload:
    # tc filter add dev imq1 parent 1: protocol ip prio 1 handle $[$MARK_START+$j] fw classid 1:$[$N_CLASS_U_1+$i] # ruch wazny
    # tc filter add dev imq1 parent 1: protocol ip prio 5 handle $[$MARK_START+$j+1] fw classid 1:$[$N_CLASS_U_2+$i] # ruch ogolny

    #regolki iptables beda nizej

     # j juz chyba niepotrzebne chyba ze do zakomentowanej propozycji z wartoscia +2
      j=$[$j+4]
    
      i=$[$i+1]
    done
    


    tak moglyby wygladac regolki iptables do markowania (mam nadzieje ze dobrze):
    i=1
    j=1

    while [ $i -le $L_USERS ]
    do
    MARKOWANIE pakietow!
    upload ogolny dla usera
    $IPTABLES -t mangle -A POSTROUTING -o $ZEW --src ${USER_IP[${i}]} -j MARK --set-mark $[$MARK_START+$j+3]
    #przemarkuj upload wazny
    $IPTABLES -t mangle -A POSTROUTING -o $ZEW -m layer7 --l7proto ssh --src ${USER_IP[${i}]} -j MARK --set-mark $[$MARK_START+$j+2]
    $IPTABLES -t mangle -A POSTROUTING -o $ZEW -m layer7 --l7proto dhcp --src ${USER_IP[${i}]} -j MARK --set-mark $[$MARK_START+$j+2]
    $IPTABLES -t mangle -A POSTROUTING -o $ZEW -m layer7 --l7proto dns --src ${USER_IP[${i}]} -j MARK --set-mark $[$MARK_START+$j+2]

    i=$[$i+1]
    j=$[$j+2]
    done;
    
    # przekieruj ruch z lacza zewnetrznego do imq:
    $IPTABLES -t mangle -A POSTROUTING -o $ZEW -j IMQ --todev 1 #upload
    $IPTABLES -t mangle -A PREROUTING -i $ZEW -j IMQ --todev 0 #download
    
    # podnies interfejsy imq
    ip link set imq0 up
    ip link set imq1 up


    narazie tyle mam,
    uprzejmie proszę o przyglądnięcie się kodzikowi i obkomentowanie, zwlaszcza propozycji.

    // Ps. temat dałem też na innych forach
  • REKLAMA
  • #2 4475440
    pilu
    Poziom 12  
    Posty: 77
    Pomógł: 2
    Ocena: 3
    2:procenty powinny sie sumowac do 100 bo inaczej user nigdy nie osiagnie swojego 512Kbit czy ile tam mu dajesz. Osiągnie 80%. Ja robie tak, że podklasa prio (ssh,ping, gry) ma upceil taki jak klasa główna, a klasa p2p ma 50-60% klasy głównej, czyli łącznie niby 160%, ale nie bój się - żaden user mordy poza klasę główną nie wyciągnie :) W Twoim przypadku wejdzie na speedtest.net i bedzie miec 55% swojego łącza -padaka.

    Markujesz wszystkie pakiety na karcie lanowej:
    p2p="100bao applejuice ares bittorrent directconnect edonkey fasttrack gnucleuslan gnutella goboogy hotline kugoo mute napster poco soribada soulseek tesla th
    ecircle xunlei"

    iptables -A PREROUTING -t mangle -i eth0 -j CONNMARK --restore-mark

    $IPTABLES -A PREROUTING -t mangle -i eth0 -m ipp2p --edk --dc --kazaa --gnu --bit --apple --winmx --soul --ares -j MARK --set-mark 200
    for i in `echo $p2p`;do
    $IPTABLES -A PREROUTING -t mangle -i eth0 -m layer7 --l7proto $i -j MARK --set-mark 200
    done
    iptables -A PREROUTING -t mangle -i eth0 -m mark ! --mark 0 -j CONNMARK --save-mark

    iptables -A POSTROUTING -t mangle -o eth0 -j CONNMARK --restore-mark

    $IPTABLES -A POSTROUTING -t mangle -o eth0 -m ipp2p --edk --dc --kazaa --gnu --bit --apple --winmx --soul --ares -j MARK --set-mark 20
    for i in `echo $p2p`;do
    $IPTABLES -A POSTROUTING -t mangle -o eth0 -m layer7 --l7proto $i -j MARK --set-mark 20
    done
    iptables -A POSTROUTING -t mangle -o eth0 -m mark ! --mark 0 -j CONNMARK --save-mark

    mark 200 -upload(od usera) , mark 20 - download (do usera)

    Tak samo możesz zmarkować uslugi prio typu dns itp (np marki 100 i 10)

    Następnie w filtrach per user robisz tak:
    tc filter add dev $LAN parent 1:0 protocol ip u32 match mark 20 0xffff match ip dst $IPEK flowid 1:$klasa
    Co oznacza że pakiety o danym ip i marku 20 kieruje do klasy 1:$klasa (to bedzie jakas tam podklasa klasy głównej usera). Dzięki temu oszczędzisz na filtrach i wpisach iptables, bo teraz masz ich tysiące :)
    Upewnij się tylko czy masz w jądrze łatkę nf_mark_match czy jakos tak (cls_u32_mark?) .

    P.S. Markowanie ruchu prio szybciej się odbywa za pomocą portów niż layer7, albo mam tylko takie złudzenie.
    P.S.2 IMQ rób na interfejsie LAN a nie WAN - wtedy żaden user nie wyskoczy poza widły w przypadku stosowania np. squida.
REKLAMA