Michal Koziorowski wrote:
Przepraszam że dopiero teraz ale miałem trochę mało czasu - poza tym w rzeczywistości wszystko u mnie jest generowane przez taki fikuśny programik w C ściągający dane klientów z postgresa i musiałem jakoś to przystosować...
A czy moglbys jeszcze wyslac konfiguracje nata iptables do obslugi takiego ruchu?. Nie mam takich lacz ale temat wydaje mi sie ciekawy i chcialem sobie zachowac cala dyskusje na przyszlosc.
A więc:
Sieć: ok 300 klientów, podłączeni radyjkiem. Aktualnie: 5 x 2 MBit DSL (4x dialog, 1x tpsa), docelowo jeszcze dwie tepsy.
Router to P4 2.4 GHz, 512 MB RAM, dysk jakiś szybszy SCSI, kontroler Adaptec Ultra320. Dwie czteroportowe sieciówki D-Link (nie pamiętam typu, zgłaszają się jako D-Link DL10050 Sundance Ethernet). Dla przypomnienia: PLD Ra, 2.4.26 + patch
Zainstalowane dodatkowo: squid, dnsmasq. Programik na QUEUE ogranicza ilość jednoczesnych połączeń danego klienta (nie tak jak connlimit, bo traktuje jako połączenie każdy pakiet wysłany gdziekolwiek - niezależnie od tego czy połączenie zostało w rzeczywistości nawiązane - i pamięta taki fakt przez ileś tam sekund) do 8 różnych hostów (dobrane empirycznie). Bardzo wspaniale sobie radzi z wszelakim robactwem, panoszącymi się wirusami oraz genialnymi klientami próbującymi swoich sił w skanowaniu sieci. Źródełka w razie potrzeby mogę udostępnić.
A więc zaczynamy...
1) iptables
Dla każdej podsieci klienckiej mam:
#magiczny program ogranicznika połączeń iptables -A PREROUTING -t mangle -s $siec -j QUEUE
#transparent squid iptables -t nat -A PREROUTING -p tcp -s $siec \ -d '!' $moje_serwery \ --dport 80 -j REDIRECT --to-port 3128
#dnsmasq - jako że nieprzewidywalnym jest co klient wpisze # w konfiguracji DNS-ów iptables -t nat -A PREROUTING -p udp -s $siec \ --dport 53 -j REDIRECT --to-port 53
# i kolejno dla wszystkich interfejsów wyjściowych: iptables -A POSTROUTING -t nat -o $interface -s $siec \ -d '!' $moje_serwery -j SNAT --to-source $ifaddr
#teraz dla każdego "swobodnego" adresu z sieci klienckich #coby się obce elementy nie podłączały:
iptables -I PREROUTING -t mangle -s $adres -d 0/0 -j DROP
#a dla każdego klienta (jako że nie mogę stosować IMQ) iptables -A POSTROUTING -t mangle -s $adres -j MARK \ --set-mark $numer_klienta
2) routing
Dla kazdego interfejsu jest oczywiscie oddzielna tabela.
Jako że maszyna ma oddzielny interfejs na futuro (dla klientów z zewnętrznymi IP i takich tam podobnych) mamy tu dodatkową tabelę futuro. Czyli:
#dla każdego interfejsu wyjściowego: ip rule add from $ifaddr table $tabela ip route add 0/0 via $gateway table $tabela
#serwery na lokalnym ethernecie - podłączone przez inny router (10.0.0.1 - mój adres to 10.0.0.2)
ip route add to $moje_serwery via 10.0.0.2
#wyjście na świat przez futuro ip route add 0/0 via 10.0.0.1 table futuro
#klienci zewwnętrzni ip rule add from $siec_klientow table futuro
#dns-y futuro ip rule add to 62.233.128.18 table futuro ip rule add to 62.233.128.17 table futuro ip rule add to 213.77.129.149 table futuro
#z dziwnych przyczyn router nie widzi klientów - tak jakby nie uwzględniał local. W związku z tym mam lokalną tablicę i na chama dla każdej sieci mu wpisuję co gdzie ma routować
ip route add $siec via $interfejs table lokalna ip rule add to $siec table lokalna
#no i najważniejsze - wyjście na świat: ip route add 0/0 proto static \ nexthop via $gateway1 dev $if1 \ nexthop via $gateway2 dev $if2 \ nexthop via $gateway3 dev $if3 \ nexthop via $gateway4 dev $if4 \ nexthop via $gateway5 dev $if5
3) limity na interfejsach:
tc qdisc add dev $interface root handle 1: htb default 20 tc class add dev $interface parent 1: classid 1:1 htb \ rate 440kbit burst 12k
tc class add dev $interface parent 1:1 classid 1:10 htb \ rate 440kbit burst 12k prio 1
tc class add dev $interface parent 1:1 classid 1:20 htb \ rate 396kbit burst 12k prio 2
tc qdisc add dev $interface parent 1:10 handle 10: sfq tc qdisc add dev $interface parent 1:20 handle 20: sfq
tc filter add dev $interface parent 1: protocol ip prio 10 u32 \
match ip protocol 6 0xff match u8 0x05 0x0f at 0 \
match u16 0x0000 0xffc0 at 2 \
match u8 0x10 0xff at 33 \
flowid 1:10tc qdisc add dev $interface handle ffff: ingress
tc filter add dev $interface parent ffff: protocol ip prio 50 u32 \ match ip src 0.0.0.0/0 police rate 1638kbit burst 10k drop \ flowid :1
#teraz dla każdego klienta mam trzy cyferki: # $numer - numer klienta (taki jak w MARK) # $klasa - unikalna klasa # $uchwyt - unikalny uchwyt # u mnie jest to tak, że kolejne numerki różnią się o 2, # klasa jest równa numerkowi, a uchwyt to klasa+1 # parametry rate i ceil zależą od "gatunku" klienta # (konkretniej od tego ile płaci)
tc class add dev $interface parent 1:20 classid 1:$klasa htb \ rate $rate ceil $ceil prio 4
tc qdisc add dev $interface parent 1:$klasa handle $uchwyt: tbf \ rate $ceil latency 200ms burst 1540
tc filter add dev $interface parent 1:0 protocol ip prio 12 \ handle $numer fw classid 1:$klasa
#konfiguracja ograniczenia koozy na ssanie #ponieważ mam tu trochę nietypowo, więc piszę "mniej więcej" #coś podobnego - czyli może nie działać... #CEIL zależy od ilości wyjść na świat - czyli ok. 1600 * n #rate i ceil oczywiście dla każdego klienta różne #muszę tu dać tbf - nie mogę pozwolić klientowi na zbytnie #rozpędzenie się bo inny klient o niższym SNR może w ogóle #nie wbić się w przekaźnik
tc qdisc add dev eth1 root handle 1: htb default 2 tc class add dev eth1 parent 1: classid 1:1 htb \ rate ${CEIL}kbit ceil ${CEIL}kbit
#a to dla nie-klientów - ze względu na charakter sieci (radio) #muszę i tu dać ograniczenia. Defaultowo wędruje tu wszystko #co nie jest klientem
tc class add dev eth1 parent 1: classid 1:2 htb rate 2000kbit ceil 2000kbit tc qdisc add dev eth1 parent 1:2 handle 20 sfq
#no i dla każdego klienta:
tc class add dev eth1 parent 1:1 classid 1:$klasa htb \ rate $rate ceil $ceil prio 2
tc qdisc add dev eth1 parent 1:$klasa handle $uchwyt: tbf \ rate $ceil latency 200ms burst 1540
tc filter add dev eth1 parent 1:0 prio 10 protocol ip u32 \ match ip dst $klient_ip classid 1:$klasa
4) I na koniec - żeby żadna menda mi się nie wbiła w sieć (jest to bezpieczne, bo kliencki AP podaje zawsze swojego MAC-a i zmiana sieciówki u klienta nie powoduje konieczności przestawiania czegokolwiek):
# dla każdego klienta: arp -s $ip_klienta $mac_klienta
5) Dodatkowo: wszystkie przekażniki ustawione są tak, że klient może połączyć się wyłącznie z MAC-em bramy. Co prawda na początku wywoływało to wielkie pretensje klientów (bo nie mogą sobie nawzajem filmów przegrywać po LANie - problem ze zrozumieniem różnicy między radiem a ethernetem mieli jakoś wszyscy) - po pewnym czasie (i po demonstracji, jak dwa AP-ki z dobrym SNR-em skutecznie blokują całą transmisję) chyba zrozumieli bo przestali się czepiać... A przy okazji dość dobrze rozwiązuje to problem snifferów (owszem, podsłuchanie transmisji radiowej też jest możliwe, ale wymaga trochę więcej niż ściągnięcie sobie windzianego execa)
To tak mniej więcej tyle...
ethanak
_______________________________________________ pld-users-pl mailing list [email protected] http://lists.pld-linux.org/mailman/listinfo/pld-users-pl
