Michal Koziorowski wrote:


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.


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 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:10

tc 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

Odpowiedź listem elektroniczym