{ }
menu zespół linki Logowanie
Stabilny hosting
BSDGuru zawdzięcza
firmie Datanet.pl
Hosting BSDGuru.org - DataNet.pl

Statyczny ARP

0. Tytułem wstępu

Tekst ten powstał, aby ułatwić skonfigurowanie sieci "osiedlowej" w taki sposób, aby dostęp do Internetu z odpowiednimi szybkościami (lub priorytetami) mieli tylko użytkownicy, którzy są do tego uprawnieni. Zakładam, że czytający posiada łącze ADSL 128/512Kbit/s oraz system FreeBSD z gałęzi 4.x. Przed zastosowaniem porad zamieszczonych w niniejszym tekście polecam zaznajomić się też z tekstem "Praktyczne IPFW".

Trzeba też pamiętać, że aby nasza konfiguracja działała należy dodać do pliku "/etc/make.conf" wpis "IPFW2=true" oraz do "/etc/sysctl.conf" zmienną "net.link.ether.ipfw=1" i przebudować świat.

1. Trochę teorii

W naszej sieci może się zdażyć, że użytkownik chcąc "podkręcić" sobie szybkość ściągania i wysyłania danych będzie próbował podszyć się pod kogoś, kto ma wyższy od niego abonament i w związku z tym szybciej też może ściągać dane. Przeważnie jest to realizowane przez tzw. ip spoofing, czyli podszywanie się pod czyjś adres IP. Wystarczy, że użytkownik wpisze sobie adres IP kogoś z wyższym abonamentem i nasze regułki dummynetu będą go traktowały jako kogoś, kim nie jest. Jeśli dodatkowo osoba pod którą się podszył wyjechała gdzieś na dłużej działalność taka może zostać niezauważona. W naszej sieci nie będziemy czegoś takiego tolerować. Aby się przed tym chronić należy zastosować połączenie kilku narzędzi: static arp, static dhcp oraz regułek ipfw (oraz dummynet'u).
Statyczny ARP uniemożliwi użytkownikowi zmianę pary IP/MAC, statyczne DHCP uniemożliwi mu przydział adresu IP z dhcp jeśli zmieni sobie adres MAC karty natomiast ipfw z dummynetem pozwoli nam ruch przydzielić według potrzeb (lub abonamentu) dla
każdego z użytkowników.

Może się oczywiście zdarzyć, że nasz niesforny użytkownik przypisze sobie na stałe inne IP oraz zmieni numer MAC karty sieciowej (i ta para IP/MAC będzie istniała w naszej sieci dla innego użytkownika ale np. będzie w danej chwili nieaktywna) ale ponieważ tutaj opisze tylko prostą konfiguracje nie będziemy się tym na razie zajmowali.

Czym jest ARP? Aby pakiet z Internetu został dostarczony do adresata, konieczne jest by nasz router mógł skojarzyć adres IP użytkownika z jego adresem karty sieciowej (nazywanym też adresem fizycznym lub adresem MAC). Mechanizm odpowiedzialny za to (ARP - Address Resolution Protocol) działa zwykle dynamicznie, czyli jeśli router nie ma jeszcze w swojej tablicy adresu MAC skojarzonego z adresem IP, rozsyła broadcastem zapytanie o właściciela danego IP. Jeśli komputer mający przypisane to konkretne IP jest włączony, odpowiada podając swój adres MAC, a router zapisuje te informacje na jakiś czas w swojej tablicy ARP (by w przyszłości nie musieć już ponownie się o ten adres dopytywać).

Tablica ARP jest okresowo odświeżana, gdyż może się zdarzyć, że ten sam numer IP zostanie przypisany innemu komputerowi (np. przez DHCP). Dlatego chcielibyśmy przypisać "raz na zawsze" IP do konkretnego komputera, tak by kto inny nie mógł z niego skorzystać. Można to osiągnąć ręcznie dodając wpisy do tablicy ARP. Oczywiście aby to działało musimy mieć spisane wszystkie adresy MAC kart sieciowych w naszej sieci.

2. Statyczny ARP

Załóżmy, że komputer o adresie IP "192.168.0.1" ma adres fizyczny (MAC) "00:30:cd:00:04:b0".
Teraz chcemy przypisać mu ten adres IP na stałe. Dokonujemy tego komendą:

arp -S 192.168.0.1 00:30:cd:00:04:b0 permanent

Spowoduje to dodanie do tablicy ARP wpisu mówiącego, że karta o adresie fizycznym 00:30:cd:00:04:b0 ma adres IP 192.168.0.1 i że jest to wpis dodany "na stałe" (permanent).

3. Statyczne DHCP

Następnym krokiem jest przypisywanie owego zdefiniowanego powyżej adresu IP do danej karty sieciowej przy każdym włączeniu komputera użytkownika. Realizowane jest to za pomocą DHCP.

Konfiguracje samego serwera DHCP pominę, gdyż jest to opisane dość dobrze przez innych (np. na stronie freebsd.hello.pl) a skupie się na samym pliku konfiguracyjnym. Jak wiadomo jest on umiejscowiony w "/usr/local/etc" i nazywa się "dhcpd.conf". Przykładowy plik dla sieci osiedlowej może wyglądać tak:

# Nazwa domeny (opcjonalna)<br>
  option domain-name "kliny.net.pl";<br>

  # Adresy serwerów DNS<br>
  option domain-name-servers 192.168.2.1;<br>

  # Maska podsieci<br>
  option subnet-mask 255.255.255.0;

# Domyślny czas dzierżawy w sekundach (24 godziny)<br>
  default-lease-time 86400;<br>

  # Maksymalny czas dzierżawy w sekundach (48 godzin)<br>
  max-lease-time 172800;<br>

  <br>
  # Domyślny router <br>
  option routers 192.168.2.2;<br>
  # Adres serwera WINS (opcjonalnie)<br>

  option netbios-name-servers 192.168.2.2;<br>
  # Domyślne wartości TTL dla ip i tcp<br>

  option default-ip-ttl 64;<br>
  option default-tcp-ttl 64;

# No i wreszcie statyczne wpisy dla poszczególnych komputerów w sieci
  LAN

host czardasz {hardware ethernet 00:50:ba:3f:0d:f7; fixed-address 192.168.2.10;}<br>

  host paproszek {hardware ethernet 00:00:b4:5a:96:14; fixed-address 192.168.2.11;}<br>
  host trzynastka {hardware ethernet 00:80:ad:07:9a:30; fixed-address 192.168.2.12;}

Jak widać z konfiguracji każdy komputer dostanie odpowiedni adres IP w zależności
od tego jaki posiada adres MAC karty sieciowej.

4. IPFW i Dummynet

Mamy już skonfigurowany statyczny przydział IP do MAC. Teraz pozostaje kształtowanie ruchu.

Pokaże tu w jaki sposób połączyć wszystkie trzy kluczowe dla naszej konfiguracji rzeczy w jak najwygodniejszy sposób. Najwygodniej jest oczywiście, jeżeli wszystkie dane o użytkowniku (jego adres IP, adres MAC oraz np. wagę w dummynecie) wpiszemy sobie tylko do jednego pliku a resztę wykona za nas skrypt.
Nasz plik z danymi (np. /etc/users.rules) o użytkowniku niech ma składnie: nazwa_komputera;IP;MAC;waga (format ten jest wygodny do obróbki np. w Excellu ;-) ), czyli przykładowo:

gryzor;192.168.0.1;00:30:cd:00:04:b0;5

Teraz skrypt, który przeczyta zawarte w pliku dane i wykorzysta je

#!/bin/sh<br>
  fwcmd="/sbin/ipfw"<br>

  arpcmd="/usr/sbin/arp"<br>
  dhcpdconfig=/usr/local/etc/dhcpd.conf

oif="rl0"

iif="rl1"

nr_regulki="1000"<br>
  nr="100"

# Kopia zapasowa starej konfiguracji dhcpd.conf<br>

  /bin/rm ${dhcpdconfig} ${dhcpdconfig}.bak

# Stałe wpisy do pliku DHCP<br>
  echo 'option domain-name "kliny.net.pl";' >> ${dhcpdconfig}<br>

  echo 'option domain-name-servers 192.168.2.1;' >> ${dhcpdconfig}<br>
  echo 'option subnet-mask 255.255.255.0;' >> ${dhcpdconfig}<br>
  echo 'option routers 192.168.2.2;' >> ${dhcpdconfig}<br>

  echo 'option default-ip-ttl 64;' >> ${dhcpdconfig}<br>
  echo 'option default-tcp-ttl 64;' >> ${dhcpdconfig}

# Czytamy dane z pliku "users.rules"<br>

  for i in $(cat /etc/users.rules); do<br>
  nazwa=`echo $i | cut -f1 -d ";"`<br>
  adres_ip=`echo $i | cut -f2 -d ";"`<br>

  adres_mac=`echo $i | cut -f3 -d ";"`<br>
  waga=`echo $i | cut -f4 -d ";"`

<br>

  # Tablica ARP<br>
  ${arpcmd} -S ${adres_ip} ${adres_mac} permanent

# Konfiguracja DHCP<br>
  echo 'host '${nazwa}' {hardware ethernet '${adres_mac}'; fixed-address '${adres_ip}';}'
  >> ${dhcpdconfig}

# Dummynet<br>
  nr=`let $nr + 1`<br>

  nr_regulki=`let $nr_regulki + 10`<br>
  <br>
  ${fwcmd} add ${nr_regulki} queue ${nr} ip from ${adres_ip} to any out xmit ${oif}<br>
  ${fwcmd} queue ${nr} config weight ${waga} pipe 1 queue 8<br>
  <br>

  nr=`let $nr + 1`<br>

  nr_regulki=`let $nr_regulki + 10`

${fwcmd} add ${nr_regulki} queue ${nr} ip from any to ${adres_ip} in
  recv ${oif}<br>
  ${fwcmd} queue ${nr} config weight ${waga} pipe 1 queue 16

nr_regulki=`let $nr_regulki + 10`

# Firewall (puszczamy tylko zarejestrowanych)<br>
  ${fwcmd} add ${nr_regulki} allow ip from ${adres_ip} to any MAC any ${adres_mac} via ${oif}

nr_regulki=`let $nr_regulki + 10`

${fwcmd} add ${nr_regulki} allow ip from any to ${adres_ip} MAC ${adres_mac} any via ${oif}

# Koniec dummynetu<br>
  done

# Puszczamy połączenia z/do routera

${fwcmd} add allow ip from me to any via ${oif}

${fwcmd} add allow ip from any to me via ${oif}

Powyższą konfiguracje wpisujemy oczywiście do pliku odpowiedzialnego za firewall
(np. /etc/rc.dummynet). Pamiętamy też o ustawieniu w "/etc/sysctl.conf"
zmiennej "net.inet.ip.fw.one_pass=0".

5. Na koniec

Powyższa konfiguracja została napisana "z głowy" a jej część tylko pobierznie przetestowana, więc ma prawo nie działać. Jeśli znajdziesz jakieś błędy lub niedociągnięcia proszę
o kontakt. Proszę też o kontakt osoby na tyle odważne, że spróbują to u siebie
wdrożyć aby podzieliły się wrażeniami ;-)

Autor: 
Tomasz Król [yautja(at)interia.pl]
Porozmawiaj o tym artykule na forum: 

tytus, pt., 18/04/2008 - 22:08