UWAGA
Dzielenie łącza to uproszczona nazwa określająca różne metody regulowania szybkości pobierania danych z internetu przez użytkowików. Dzielenie łącza nie ma nic wspólnego z udostępnianiem łącza czyli z umożliwieniem użytkownikom wewnątrz sieci łączenia się z internetem za pośrednictwem serwera. Udostępnianie jest osobnym zagadnieniem i nie jest omówione na tej stronie (szukaj na wyszukiwarkach hasła: maskarada, masquerade, nat, firewall)
historia:
Na wstępie chciałbym zaznaczyć, że program ten jest w wersji beta a to znaczy, że jest niedostatecznie przetestowany i może sprawiać nijakie problemy. Należy się spodziewać, że będzie jeszcze nie raz uaktualniany.
Po włączeniu się w sieć nowego użytkownika i rozpoczęciu transmisji z internetem (lokalne połączenia nie rezerwują łącza), daemon testuje czy użytkownik nie łączy się przypadkiem z jednym z adresów ip lub portów wpisanych w liście wyjątków (plik /etc/shaper/ignore). Jeśli nie znajdzie takiego wyjątku to przydziela część łącza wynikającą z prostego podziału szybkości maksymalnej łącza przez ilość aktualnie przez nie pracujących komputerów.
Po określonym czasie (zależnie od konfiguracji) - np. po 10 sekundach - shaperd sprawdza, czy użytkownik wykorzystał co najmniej 50% z przydzielonego łącza. Jeśli nie wykorzystał to zostaje mu przydział zmniejszony o 25%. Jeśli użytkownik wykorzystuje przydział w granicach 50%-75% to program niczego nie zmienia a jeśli wykorzystuje więcej od 75% to shaperd zwiększa mu transfer o minimalny transfer (np o 8000 czyli 1KBajt) - pod warunkiem, że coś jeszcze zostało do przydzielenia. Zasada jest taka, że w pierwszej części daemon sprawdza, komu można obciąć a dopiero na samym końcu z tego co zostanie z przydzielania szybkości dodaje tym co dużo ciągną.
Dzięki temu program zapobiega przejęciu całkowitej kontroli nad łączem przez jednego nawiedzonego maniaka programów P2P lub idioty otwierającego kilkadziesiąt sesji WWW.
Program ten reguluje transfer przychodzący z internetu do użytkowników, transfer wychodzący od użytkowników do internetu oraz transfer wychodzący z serwera do internetu.
Przy włączonej opcji extended_queue shaperd dodatkowo dla każdego użytkownika tworzy 4 podklasy z różnymi priorytetami.
Shaperd jest programem napisanym w języku C funkcjonalnie odpowiadającym skryptowi shaper_cbq.
Istnieje, jak na razie nie rozwiązany, bład w kernelach 2.4.x polegający na tym iż niektóre połącznia wiszą ma maskaradzie przez 5 dni pomimo tego, że komputer, dla którego je utworzono nie był od kilku dni włączony w sieć. W przypadku shaperd problem wiszących połączeń obszedłem ignorując połączenia z czasem wygaśnięcia większym niż 600 sekund).
Autor tego oprogramowania nie bierze odpowiedzialności za jakiekolwiek błedy, awarie i uszkodzenia wywołane przez działanie tego programu. Wszystko co robisz - robisz na własną odpowiedzialność.
Program ten testowany jest na systemach opartych na jądrzach: 2.4.8, 2.4.12 i 2.4.18-grsec, firewall'ach na ipchains i iptables oraz na dystrybucji Mandrake 8.1 (Vitamin) i łączach: SDI, DSL 768Kbit, asynchroniczne 1Mbit.
Warunki działania
Aby wogóle dzielenie łącza pod Linuxem zaczęło działać to musi być spełnione wiele warunków:tc -d qdiscJeśli w wyniku jej działania pojawi się jakiś komunikat typu RTNETLINK error to jądro nie obsługuje CBQ (lub nie ma załadowanego modułu).
Konfiguracja
high_start_speed=yes even_division=no continuous_control=no check_always=yes squid_support=no divide_upload=yes extended_queue=no nomasq=no class_type=cbq upload_class_type=cbq jump_type=5 speed_ext=bit debug=0 delay=10 write_delay=0 inter_int=ppp0;8000;92000;1000;60000;auto;1 local_int=eth0;10485760;192.168.0.0/16;192.168.1.0/24;2Gdzie:
high_start_speed=yes even_division=no continuous_control=no check_always=yes squid_support=no divide_upload=yes extended_queue=no nomasq=no class_type=cbq upload_class_type=cbq jump_type=5 speed_ext=Kbit debug=0 delay=10 write_delay=0 inter_int=ppp0;16;900;1;300;auto;1 local_int=eth0;10240;192.168.0.0/16;192.168.1.0/24;2 local_int=eth1;102400;192.168.0.0/16;192.168.2.0/24;3
high_start_speed=yes even_division=no continuous_control=no check_always=yes squid_support=no divide_upload=yes extended_queue=no nomasq=no class_type=cbq upload_class_type=cbq jump_type=5 speed_ext=Kbit debug=0 delay=10 write_delay=0 inter_int=eth0;8;440;1;100;auto;1 inter_int=ppp0;8;92;1;60;auto;2 local_int=eth1;10240;192.168.0.0/16;192.168.1.0/24;3 local_int=eth2;102400;192.168.0.0/16;192.168.2.0/24;4 local_int=ppp2;768;192.168.3.0/24;192.168.3.0/24;5
gcc /usr/src/shaperd/shaperd.c -o /sbin/shaperd
192.168.1.2=eth0 ppp0 192.168.1.3=eth0 ppp0 192.168.1.4=eth0 ppp0 8000 16000 1000 16000 192.168.1.5=eth0 ppp0 192.168.2.2=eth1 ppp0 192.168.2.3=eth1 ppp0 192.168.2.4=eth1 ppp1 192.168.2.5=eth1 ppp1Wprowadziłem dodatkowo możliwość ustawiania indywidualnych limitów dla poszczególnych numerów IP. W powyższym przykładzie dla numeru IP 192.168.1.4 ustawiłem następujące widełki dla ściągania (download): 8000 (1KB - minimum gwarantowane) i 16000 (2KB - maksymalna możliwa przydzielona szybkość) oraz dla wysyłania (upload): 8000 (1KB - minimum gwarantowane) i 16000 (2KB - maksymalna możliwa do osiągnięcia prędkość wysyłania). Pamiętaj, że wartości te są podawane w jednostce szybkości takiej samej jak ustawiona jednostka w pliku shaper.cfg w parametrze speed_ext. W przypadku braku wpisów shaperd przyjmuje dla każdego numeru IP wartości ustawione globalnie w pliku shaper.X.cfg.
192.168.1.2=eth0 ppp0 192.168.1.3=eth0 ppp0 # numery 192.168.1.4 i 192.168.1.5 mają jeden wspólny przydział łącza 192.168.1.4/31=eth0 ppp0 192.168.2.2=eth1 ppp0 192.168.2.3=eth1 ppp0 192.168.2.4=eth1 ppp1 192.168.2.5=eth1 ppp1Co spowoduje, że numery IP od 192.168.1.4-192.168.1.5 będą traktowane jako jeden i otrzymają wspólnie widełki.
192.168.1.0/24=eth0 ppp0 192.168.2.0/24=eth1 ppp0Jest to podział między dwoma interfejsami. Przy włączonej opcji even_division=1 możemy zaczynać działalność providerską :)
lospeed = hispeed / liczba_IPgdzie:
00 00 * * * root killall shaperd;/sbin/shaperd -config=0 00 15 * * * root killall shaperd;/sbin/shaperd -config=1Co spowoduje, że shaperd będzie używał konfiguracji 0 w godzinach od 00:00-15:00 a od 15:00-00:00 konfiguracji 1.
tc -s class show dev eth0możemy zobaczyć miedzy innymi klasę dla tego numeru IP (w przykładzie używana klasa HTB):
class htb 2:5 parent 2:1 prio 3 rate 214Kbit ceil 214Kbit burst 27391b cburst 1872b Sent 27025335 bytes 34960 pkts (dropped 0, overlimits 0) rate 21702bps 28pps lended: 0 borrowed: 0 giants: 0 injects: 0 tokens: 778767 ctokens: 15581A dla upload:
tc -s class show dev eth0zobaczymy coś takiego (w przykładzie używana klasa CBQ):
class cbq 1:5 parent 1:1 rate 14Kbit (bounded) prio 5 Sent 554775 bytes 4674 pkts (dropped 0, overlimits 0) borrowed 30 overactions 0 avgidle 379301 undertime 0Dodatkowe 4 podklasy do kolejkowania mają numery tworzone zgodnie z zasadą X:Y gdzie X to identyfikator klasy, Y = (4*(A+4))+PRIO
iptables -t mangle -A FORWARD -p tcp -s 0/0 --sport 22:23 -d 192.168.1.2/32 -j MARK --set-mark 2120 iptables -t mangle -A FORWARD -p udp -s 0/0 --sport 22:23 -d 192.168.1.2/32 -j MARK --set-mark 2120Znacznik (MARK) wyliczamy ze wzoru:
M = (1000 * X) + PRIO + (4 * (A + 4))gdzie: M - znacznik, X - identyfikator klasy (w tym przypadku 2 - dla local_int), A - pozycja numery IP w pliku iplist.X
tc -s filter show dev eth1 | grep 848i dostajemy w wyniku:
filter parent 2: protocol ip pref 10 fw handle 0x848 classid 2:120Czyli ruch zaznaczony przez tą regułkę trafi do klasy 2:120. Teraz możemy sobie obserwować ruch wpadający do tej klasy:
watch tc -s class show dev eth1i jeśli tylko połączymy się pod ssh lub telnetem z jakimś zewnętrznym serwerem to zobaczymy:
class htb 2:120 parent 2:5 leaf a688: prio 0 rate 273Kbit ceil 273Kbit burst 15Kb cburst 1948b Sent 10644 bytes 133 pkts (dropped 0, overlimits 0) rate 11bps lended: 133 borrowed: 0 giants: 0 injects: 0 tokens: 315623 ctokens: 39721I jak widać 10644 bajty przeszły przez klasę 2:120
iptables -t mangle -A FORWARD -p tcp -s 192.168.1.2/32 -d 0/0 --dport 22:23 -j MARK --set-mark 1120 iptables -t mangle -A FORWARD -p udp -s 192.168.1.2/32 -d 0/0 --dport 22:23 -j MARK --set-mark 1120Wzór do obliczenia znacznika jest identyczny jak powyżej - zwracam uwagę, że upload ograniczany jest na interfejsie internetowym a nie jak download na lokalnym więc w tym przypadku identyfikator klasy mamy taki jak dla inter_int czyli w tym przypadku 1. Teraz sprawdzamy:
tc -s filter show dev eth0 | grep 460i dostajemy w wyniku:
filter parent 1: protocol ip pref 10 fw handle 0x460 classid 1:120Czyli wszystko jest prawidłowo. Możemy teraz obserwować klasę 1:120 aby zobaczyć czy coś przez nią przechodzi. I widzimy:
class cbq 1:120 parent 1:5 leaf a69c: rate 18Kbit prio 3 Sent 12122 bytes 208 pkts (dropped 0, overlimits 0) borrowed 0 overactions 0 avgidle 8.07342e+06 undertime 0Czyli jak widać, przez klasę przeszły 12122 bajty.
iptables -t mangle -A POSTROUTING -p tcp -s 213.97.124.129/32 --sport 22:23 -d 0/0 -j MARK --set-mark 1164 iptables -t mangle -A POSTROUTING -p udp -s 213.97.124.129/32 --sport 22:23 -d 0/0 -j MARK --set-mark 1164numer IP serwera znajduje się w pliku iplist.X na pozycji 12 (wpis w iplist.X: 213.97.124.129=eth0 eth0).
tc -s filter show dev eth0 | grep 48ci wynik:
filter parent 1: protocol ip pref 10 fw handle 0x48c classid 1:164I cały ruch wychodzący z serwera z portu 22 lub 23 będzie miał najwyższy priorytet.
/etc/shaper/queue_download_high.X /etc/shaper/queue_download_med.X /etc/shaper/queue_download_low.X /etc/shaper/queue_upload_high.X /etc/shaper/queue_upload_med.X /etc/shaper/queue_upload_low.X /etc/shaper/queue_upload_server_high.X /etc/shaper/queue_upload_server_med.X /etc/shaper/queue_upload_server_low.XPliki te zawierają przykładową konfigurację.
iptables -t mangle -vxL OUTPUT -n | grep 8192
modprobe sch_cbq modprobe sch_tbf modprobe cls_u32Dla HTB trzeba załadować następujące moduły:
modprobe sch_htb modprobe sch_sfq modprobe cls_u32
/sbin/shaperd shownatW dostarczonym przykładowym pliku są zrobione wpisy dla popularnych komunikatorów np. GaduGady, Tlen oraz dla kilku czatów i MUD'ów.
192.168.1.2/32 40000 192.168.1.9/32 58000lub gdy speed_ext jest ustawiony inny niż bit (w tym przypadku Kbit):
192.168.1.2/32 40 Kbit 192.168.1.9/32 58 Kbit
tc -s qdisc show dev eth1gdzie: eth1 to nazwa interfejsu lokalnego jeśli sprawdzamy dzielenie download
tc -s class show dev eth1Wyniki jej działania mogą wyglądać tak:
qdisc tbf d09f: dev eth0 rate 5430bps burst 10Kb lat 1.2s Sent 108930 bytes 73 pkts (dropped 0, overlimits 0) qdisc tbf d09e: dev eth0 rate 5430bps burst 10Kb lat 1.2s Sent 126618 bytes 89 pkts (dropped 0, overlimits 0) qdisc tbf d09d: dev eth0 rate 1638bps burst 10Kb lat 3.8s Sent 54699 bytes 65 pkts (dropped 0, overlimits 321) backlog 6110b 5p qdisc tbf d09c: dev eth0 rate 10Mbit burst 10Kb lat 4.8ms Sent 0 bytes 0 pkts (dropped 0, overlimits 0) qdisc tbf d09b: dev eth0 rate 10Mbit burst 10Kb lat 4.8ms Sent 5690 bytes 53 pkts (dropped 0, overlimits 0) qdisc cbq 10: dev eth0 rate 10Mbit (bounded,isolated) prio no-transmit Sent 310829 bytes 302 pkts (dropped 0, overlimits 1555) backlog 5p borrowed 0 overactions 0 avgidle 624 undertime 0Nalezy zwrócić szczególną uwagę na linie z rate innym niż 10Mbit (lub innym w przypadku posiadania łącza lokalnego o innej szybkości maksymalnej). W tym przypadku trzy pierwsze klasy obrazują transfery trzech różnych komputerów w sieci lokalnej. Należy zwrócić uwagę, czy rejestrowane są wielkości wysłanych danych Sent. Jeśli tak to znaczy, że CBQ działa i obcina transfer przekraczający widełki.
/usr/local/lstat/bin/show_filters | grep shaper | awk '{print $1,$11}'a dla wychodzących (upload):
/usr/local/lstat/bin/show_filters | grep shaout | awk '{print $1,$10}'Dostaniemy listę z nazwami filtrów po lewej stronie i numerami ip im odpowiadającymi Kolejność jest taka sama jak wpisy w pliku iplist dlatego lepiej potem nie przestawiać linijek w iplist.
<p><a href="http://sp9wun.republika.pl/"> <img src="http://sp9wun.republika.pl/linux/pics/shaper.png" border="0" width="89" height="32" alt="Powered by Shaper CBQ"></a></p>
Problemy
Aby ustrzec się pewnych problemów, które mogą wyniknąć w trakcie normalnej eksploatacji daemona należy przestrzegać kilku zasad (zasady te będą ulegać zmianom w trakcie wprowadzania zmian w kolejnych wersjach programu - na razie jednak mysząbyć ponieważ nie jestem wszechwiedzący i nie z każdym problemem potrafię sobie poradzić)
ipchains -L output -ntablica shaperX powinna być na najwyższej pozycji
Chain output (policy ACCEPT): target prot opt source destination ports shaout0 all ------ 0.0.0.0/0 0.0.0.0/0 n/a shaper0 all ------ 0.0.0.0/0 0.0.0.0/0 n/a ppp-out all ------ 0.0.0.0/0 0.0.0.0/0 n/a eth-out all ------ 0.0.0.0/0 0.0.0.0/0 n/a
ipchains -L shaper0 -nw tej tablicy powinny znajdować się reguły dla wszystkich numerów IP z pliku /etc/shaper/iplist.0. Przykład:
Chain shaper0 (1 references): target prot opt source destination ports RETURN tcp ------ !192.168.1.1 192.168.1.2 * -> * RETURN tcp ------ !192.168.1.1 192.168.1.3 * -> * RETURN tcp ------ !192.168.1.1 192.168.1.4 * -> * RETURN tcp ------ !192.168.1.1 192.168.1.5 * -> * RETURN tcp ------ !192.168.1.1 192.168.1.6 * -> * RETURN tcp ------ !192.168.1.1 192.168.1.7 * -> * RETURN tcp ------ !192.168.1.1 192.168.1.8 * -> *Analogicznie jest dla tablicy upload shaout, z tym, że w kolumnie source będą numery IP userów.
watch ipchains -vxL shaper0 -n watch ipchains -vxL shaout0 -npozwoli na obserwowanie, czy regułki liczą ilość pobranych danych przezd poszczególne numery IP. Generalnie - jeśli jakiś numer aktualnie coś ciągnie z internetu to jego regułka musi liczyć. Jeśli tego nie robi to należy próbować zrestartować shapera
iptables -L FORWARD -n --line-numbers | grep shatablica shaoutX powinna mieć pozycję 1 a shaperX pozycję numer 2:
1 shaout0 all -- 0.0.0.0/0 0.0.0.0/0 2 shaper0 all -- 0.0.0.0/0 0.0.0.0/0
iptables -L shaper0 -nw tej tablicy powinny znajdować się reguły dla wszystkich numerów IP z pliku /etc/shaper/iplist.0. Przykład:
Chain shaper0 (1 references) target prot opt source destination RETURN all -- !192.168.0.0/16 192.168.1.2 RETURN all -- !192.168.0.0/16 192.168.1.3 RETURN all -- !192.168.0.0/16 192.168.1.4 RETURN all -- !192.168.0.0/16 192.168.1.5 RETURN all -- !192.168.0.0/16 192.168.1.6 RETURN all -- !192.168.0.0/16 192.168.1.7 RETURN all -- !192.168.0.0/16 192.168.1.8 RETURN all -- !192.168.0.0/16 192.168.1.9 RETURN all -- !192.168.0.0/16 192.168.1.10Analogicznie jest dla tablicy upload shaout, z tym, że w kolumnie source są numery IP userów.
watch iptables -vxL shaper0 -n watch iptables -vxL shaout0 -npozwoli na obserwowanie, czy regułki liczą ilość pobranych danych przezd poszczególne numery IP. Generalnie - jeśli jakiś numer aktualnie coś ciągnie z internetu to jego regułka musi liczyć. Jeśli tego nie robi to należy próbować zrestartować shapera
FAQ
![]() |
![]() |
Powrót | Linux |