[OT] Dwa łącza i routing
Bohdan R. Rau
ethanak w polip.com
Nie, 16 Sty 2005, 10:39:38 CET
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
Więcej informacji o liście dyskusyjnej pld-users-pl