|
Strona 3 z 4
4. Dwa w jednym
Poznaliśmy zasady tworzenia firewalla w oparciu o ipfw oraz
zasady tworzenia regułek dummynetu. A jeśli będziemy chcieli stworzyć jeden
zestaw regułek, który będzie pełnił jednocześnie role firewalla i kontrolował
ruch sieciowy? Możemy to zrobić łącząc ze sobą firewalla opartego na ipfw i
regułki dummynetu w jednym pliku (skrypcie). Zanim przystąpimy do budowy takiej
hybrydy musimy zdać sobie sprawę z pewnej niedogodności. Otóż ipfw przetwarza
pakiet aż do trafienia na taką regułkę, do której ów pasuje. Ta sama
funkcjonalność tyczy się dummynetu. Jeśli mamy dwie następujące po sobie kolejki
to zadziała tylko pierwsza pasująca. Następna już nie będzie przetwarzana. Jakie
ma to konsekwencje? Otóż jeśli w jednym skrypcie połączymy funkcjonalność ipfw
jako firewalla oraz dummynetu to może się okazać (w zależności od kolejności
regułek), że po przejściu przez odpowiednią regułkę dummynetu pakiet nie będzie
już przetwarzany przez regułki firewalla lub odwrotnie - po trafieniu na
pasującą regułkę firewalla nie będzie już brany pod uwagę przez dummynet. Aby
zmienić to zachowanie należy w pliku "/etc/sysctl.conf" ustawić zmienną "net.inet.ip.fw.one_pass=0"
(domyślnie ma ona wartość 1). Spowoduje to to, że pakiet po przejściu przez
regułki dummynetu (który powinien być przetwarzany pierwszy) powróci do ipfw (z
już przydzieloną dla ruchu rurką lub kolejką) i będzie mógł być dodatkowo
przetwarzany przez regułki firewalla. Czyli uzyskujemy firewall z kontrolą
przepustowości!
Przykładowa konfiguracja dla stacji roboczej (w oparciu o poprzednio stworzony
dla niej firewall) może wyglądać tak (zakładamy, że sieć LAN ma przepustowość
100Mbit/s a interfejs do tej sieci to xl0):
ipfw pipe 1 config bw 100Mbit/s
queue 50Kbytes
ipfw add 100 queue 1 tcp from me to
any out xmit xl0 iplen 0-80 tcpflags ack
ipfw queue 1 config pipe 1 weight 7 queue 4
ipfw add 200 skipto 1000 tcp from me to any out xmit xl0
iplen 0-80 tcpflags ack
ipfw add 300 queue 2 tcp from any to
me in recv xl0 iplen 0-80 tcpflags ack
ipfw queue 2 config pipe 1 weight 7 queue 4
ipfw add 400 skipto 1000 tcp from any to me in recv xl0 iplen
0-80 tcpflags ack
ipfw add 500 queue 3 ip from
192.168.0.0/24 to me out xmit xl0
ipfw queue 3 config pipe 1 weight 1 queue 16Kbytes
ipfw add 600 queue 4 ip from any to 192.168.0.0/24 in recv
xl0
ipfw queue 4 config pipe 1 weight 1 queue 16Kbytes
ipfw add 1000 allow tcp from
192.168.0.0/24 137,138,139 to me setup keep-state
ipfw add 1100 allow udp from 192.168.0.0/24 137,138,139 to me
setup keep-state
ipfw add 1200 allow tcp from me to any setup keep-state
ipfw add 13000 allow ucp from me to any setup keep-state
ipfw add 1400 allow icmp from any to any
ipfw add 65000 deny ip from any to any
Teraz przeanalizujmy co robi powyższa konfiguracja. Pakiet
wpada do ipfw. Najpierw przetwarzany jest przez dummynet i może być pakietem o
wielkości 0-40 bajtów z ustawioną flagą ACK, wtedy trafia do kolejki 1 lub 2 (w
zależności od kierunku jego przepływu) a następnie wędruje z powrotem do kodu
firewalla. Następna w kolejności regułka to "skipto" (pozwalająca na "przeskok"
do regułki o podanym po "skipto" numerze), która przerzuca pakiet do regułki
1000, czyli już do kodu właściwego firewalla (jak ów działa zostało opisane w
sekcji dotyczącej ipfw). Jeśli nasz pakiet nie jest pakietem o wielkości 0-40
bajtów i ustawionej fladze ACK to zostaje przechwycony przez kolejkę 3 lub 4
(znów w zależności od kierunku przepływu) a później trafia do kodu firewalla
(kolejki 3 i 4 znajdują się bezpośrednio nad regułkami firewalla, więc tutaj "skipto"
nie jest już potrzebne).
Zapewne zastanawiać się możesz, po co wprowadzać kolejkowanie pakietów na stacji
roboczej? Otóż taka konfiguracja, która nadaje małym pakietom potwierdzającym (z
flagą ACK) wyższy "priorytet" niż reszcie transmisji pozwala na dobrą
interaktywność przy bardzo obciążonej karcie sieciowej (transmisja na granicy
maksymalnej przepustowości medium). Jeśli często np. ściągamy coś od kolegów z
sieci LAN a w tym samym czasie przeglądamy strony WWW może to mieć bardzo
pozytywny wpływ na komfort naszego korzystania z sieci.
Teraz spróbujmy skonfigurować firewall na naszej bramie z
podziałem za pomocą dynamicznych kolejek opisanej w sekcji dummynetu:
ipfw pipe 1 config bw 128Kbit/s
queue 8Kbytes
ipfw pipe 2 config bw 512Kbit/s queue 24Kbytes
ipfw queue 1 config pipe 1 weight 5
queue 4Kbytes mask src-ip 0xffffffff
ipfw queue 2 config pipe 2 weight 5 queue 8Kbytes mask dst-ip
0xffffffff
ipfw queue 3 config pipe 1 weight 3 queue 8Kbytes mask src-ip
0xffffffff
ipfw queue 4 config pipe 2 weight 3 queue 12Kbytes mask
dst-ip 0xfffffff
ipfw queue 5 config pipe 1 weight 1 queue 4Kbytes mask src-ip
0xffffffff
ipfw queue 6 config pipe 2 weight 1 queue 8Kbytes mask dst-ip
0xffffffff
ipfw add 100 queue 1 udp from
192.168.0.0/24 to any out xmit xl0
ipfw add 150 skipto 1500 udp from 192.168.0.0/24 to any out
xmit xl0
ipfw add 200 queue 2 udp from any to 192.168.0.0/24 in recv
xl0
ipfw add 250 skipto 1500 udp from any to 192.168.0.0/24 in
recv xl0
ipfw add 300 queue 3 tcp from 192.168.0.0/24 to any 80,25,110
out xmit xl0
ipfw add 350 skipto 1500 tcp from 192.168.0.0/24 to any
80,25,110 out xmit xl0
ipfw add 400 queue 4 tcp from any 80,25,110 to 192.168.0.0/24
in recv xl0
ipfw add 450 skipto 1500 tcp from any 80,25,110 to
192.168.0.0/24 in recv xl0
ipfw add 500 queue 5 ip from 192.168.0.0/24 to any out xmit
xl0
ipfw add 600 queue 6 ip from any to 192.168.0.0/24 in recv
xl0
ipfw add 1500 check-state
ipfw add 1600 allow ip from any to any via xl1
ipfw add 1700 reset tcp from any to
192.168.0.0/24,81.21.31.41 113 in recv xl0
ipfw add 1800 deny tcp from any to any 137,138,139,445
ipfw add 1900 deny udp from any to any 137,138,139
ipfw add 2000 allow tcp from any to
192.168.0.0/24,81.21.31.41 via xl0 established
ipfw add 2100 allow udp from any to
192.168.0.0/24,81.21.31.41 via xl0 established
ipfw add 2200 allow tcp from 192.168.0.0/24 to any via xl0
setup
ipfw add 2300 allow udp from 192.168.0.0/24 to any via xl0
setup
ipfw add 2400 allow icmp from any to any
ipfw add 2500 allow tcp from any to 81.21.31.41 22 via xl0
setup
ipfw add 65000 deny ip from any to any
Powyższa konfiguracja pozwala kolejkować ruch a jednocześnie
chroni sieć.
Na zakończenie przedstawiam przykładowy skrypt dla bramy sieci LAN pozwalający
kolejkować ruch dynamicznie według usług. Nie opisuje go, gdyż po przeczytaniu
powyższego teksu powinieneś(aś) już sam(a) dojść do tego, za co odpowiadają
odpowiednie wpisy. Skrypt jest przewidziany dla łącza ADSL 128/512Kbit/s. W
razie niejasności co do składni polecam manual systemowy do ipfw ("man ipfw").
#!/bin/sh
fwcmd="/sbin/ipfw"
# Firewall quiet or normal?
############################
if [ -n "${1}" ]; then
firewall_type="${1}"
fi
case ${firewall_quiet} in
[Yy][Ee][Ss])
fwcmd="/sbin/ipfw -q"
;;
*)
fwcmd="/sbin/ipfw"
;;
esac
# Flush rules
##############
${fwcmd} -f flush
${fwcmd} -f pipe flush
${fwcmd} -f queue flush
${fwcmd} zero
myip="81.21.31.41"
siec="192.168.2.0/24"
serwery_dns="81.21.31.42,81.21.31.132"
iif="rl1"
oif="rl0"
poczta="25,110,119"
dns="53"
www="80,443,8080"
ftp="20,21"
ssh="22"
### Flow
# - Wychodzace pakiety ACK maja najwyzszy priorytet
# - Zapytania i odpowiedzi DNS oraz ICMP maja wyzszy
priorytet
# - SSH i poczta maja wysoki priorytet
# - ruch UDP (np. radio internetowe) ma normany priorytet
# - WWW i FTP maja normalny priorytet
# - Pozostale sesje TCP (np. GG) maja niski priorytet
###
# interfejs "loopback"
${fwcmd} add 100 set 1 allow ip
from any to any via lo0
${fwcmd} add 110 set 1 deny ip from any to 127.0.0.0/8
${fwcmd} add 120 set 1 deny ip from 127.0.0.0/8 to any
# Rurka ruchu wychodzacego - 128Kbit/s
${fwcmd} pipe 1 config bw 128Kbit/s
queue 8Kbytes
# Rurka ruchu wchodzacego - 512Kbit/s
${fwcmd} pipe 2 config bw 512Kbit/s
queue 24Kbytes
# Ruch wychodzacy
##############
# --- ACK ---
${fwcmd} queue 1 config weight 7
pipe 1 queue 3 buckets 64 mask src-ip 0x000000ff
# --- DNS, ICMP ---
${fwcmd} queue 2 config weight 5
pipe 1 queue 3 buckets 64 mask src-ip 0x000000ff
# --- SSH, Poczta ---
${fwcmd} queue 3 config weight 4
pipe 1 queue 4 buckets 64 mask src-ip 0x000000ff
# --- WWW, FTP ---
${fwcmd} queue 4 config weight 3
pipe 1 queue 4 buckets 64 mask src-ip 0x000000ff
# --- Inne UDP ---
${fwcmd} queue 5 config weight 1
pipe 1 queue 4 buckets 64 mask src-ip 0x000000ff
# --- Inne TCP ---
${fwcmd} queue 6 config weight 1
pipe 1 queue 4 buckets 64 mask src-ip 0x000000ff
# --- Router lokalnie ---
${fwcmd} queue 10 config weight 7
pipe 1 queue 4Kbytes
# Ruch wchodzacy
##############
# --- ACK ---
${fwcmd} queue 11 config weight 7
pipe 2 queue 3 buckets 64 mask dst-ip 0x000000ff
# --- DNS, ICMP ---
${fwcmd} queue 12 config weight 5
pipe 2 queue 3 buckets 64 mask dst-ip 0x000000ff
# --- SSH, Poczta ---
${fwcmd} queue 13 config weight 4
pipe 2 queue 4 buckets 64 mask dst-ip 0x000000ff
# --- WWW, FTP ---
${fwcmd} queue 14 config weight 3
pipe 2 queue 8 buckets 64 mask dst-ip 0x000000ff
# --- Inne UDP --
${fwcmd} queue 15 config weight 1
pipe 2 queue 6 buckets 64 mask dst-ip 0x000000ff
# --- Inne TCP ---
${fwcmd} queue 16 config weight 1
pipe 2 queue 6 buckets 64 mask dst-ip 0x000000ff
# --- Router lokalnie ---
${fwcmd} queue 20 config weight 7
pipe 2 queue 20Kbytes
# Kolejki wychodzace
###############
# --- Ruch wychodzacy z routera ---
${fwcmd} add 500 queue 2 icmp from
${myip} to any out xmit ${oif}
${fwcmd} add 600 skipto 10000 icmp from ${myip} to any out
xmit ${oif}
${fwcmd} add 700 queue 2 udp from ${myip} to any out xmit ${oif}
${fwcmd} add 800 skipto 10000 udp from ${myip} to any out
xmit ${oif}
${fwcmd} add 900 queue 10 tcp from ${myip} to any out xmit ${oif}
${fwcmd} add 1000 skipto 10000 tcp from ${myip} to any not
${ftp},${www} out xmit ${oif}
# --- DNS ---
${fwcmd} add 1010 queue 2 udp from
${siec} to not ${siec} ${dns} out xmit ${oif}
${fwcmd} add 1020 skipto 10000 udp from ${siec} to not
${siec} ${dns} out xmit ${oif}
${fwcmd} add 1030 queue 2 tcp from ${siec} to not ${siec} ${dns}
out xmit ${oif}
${fwcmd} add 1040 skipto 10000 tcp from ${siec} to not
${siec} ${dns} out xmit ${oif}
# --- ICMP ---
${fwcmd} add 1050 queue 2 icmp from
${siec} to not ${siec} out xmit ${oif}
${fwcmd} add 1060 skipto 10000 icmp from ${siec} to not
${siec} out xmit ${oif}
# --- ACK ---
${fwcmd} add 1070 queue 1 tcp from
${siec} to not ${siec} out xmit ${oif} iplen 1-80 tcpflags ack
${fwcmd} add 1080 skipto 10000 tcp from ${siec} to not
${siec} out xmit ${oif} iplen 1-80 tcpflags ack
# --- SSH, Poczta ---
${fwcmd} add 1090 queue 3 tcp from
${siec} to not ${siec} ${ssh},${poczta} out xmit ${oif}
${fwcmd} add 1100 skipto 10000 tcp from ${siec} to not
${siec} ${ssh},${poczta} out xmit ${oif}
# --- WWW, FTP ---
${fwcmd} add 1110 queue 4 tcp from
${siec},${myip} to not ${siec} ${www} out xmit ${oif}
${fwcmd} add 1120 skipto 10000 tcp from ${siec},${myip} to
not ${siec} ${www} out xmit ${oif}
${fwcmd} add 1130 queue 4 tcp from ${siec},${myip} to not
${siec} ${ftp} out xmit ${oif}
${fwcmd} add 1140 skipto 10000 tcp from ${siec},${myip} to
not ${siec} ${ftp} out xmit ${oif}
# --- Reszta UDP ---
${fwcmd} add 1150 queue 5 udp from
${siec} to not ${siec} not ${dns} out xmit ${oif}
${fwcmd} add 1160 skipto 10000 tcp from ${siec} to not
${siec} not ${dns} out xmit ${oif}
# --- Reszta TCP ---
${fwcmd} add 1170 queue 5 tcp from
${siec} to not ${siec} not ${dns},${ssh},${poczta},${ftp},${www} out xmit ${oif}
${fwcmd} add 1180 skipto 10000 tcp from ${siec} to not
${siec} not ${dns},${ssh},${poczta},${ftp},${www} out xmit ${oif}
# Kolejki przychodzace
#################
# --- Ruch przychodzacy do routera ---
${fwcmd} add 1500 queue 12 icmp
from any to ${myip} in recv ${oif}
${fwcmd} add 1600 skipto 10000 icmp from any to ${myip} in
recv ${oif}
${fwcmd} add 1700 queue 12 udp from any to ${myip} in recv ${oif}
${fwcmd} add 1800 skipto 10000 udp from any to ${myip} in
recv ${oif}
${fwcmd} add 1900 queue 20 tcp from any not ${ftp},${www} to
${myip} in recv ${oif}
${fwcmd} add 2000 skipto 10000 tcp from any not ${ftp},${www}
to ${myip} in recv ${oif}
# --- DNS ---
${fwcmd} add 2010 queue 2 udp from
not ${siec} ${dns} to ${siec} in recv ${oif}
${fwcmd} add 2020 skipto 10000 udp from not ${siec} ${dns} to
${siec} in recv ${oif}
${fwcmd} add 2030 queue 2 tcp from not ${siec} ${dns} to
${siec} in recv ${oif}
${fwcmd} add 2040 skipto 10000 tcp from not ${siec} ${dns} to
${siec} in recv ${oif}
# --- ICMP ---
${fwcmd} add 2050 queue 2 icmp from
not ${siec} to ${siec} in recv ${oif}
${fwcmd} add 2060 skipto 10000 icmp from not ${siec} to
${siec} in recv ${oif}
# --- ACK ---
${fwcmd} add 2070 queue 1 tcp from
not ${siec} to ${siec} in recv ${oif} iplen 1-80 tcpflags ack
${fwcmd} add 2080 skipto 10000 tcp from not ${siec} to
${siec} in recv ${oif} iplen 1-80 tcpflags ack
# --- SSH, Poczta ---
${fwcmd} add 2090 queue 3 tcp from
not ${siec} ${ssh},${poczta} to ${siec} in recv ${oif}
${fwcmd} add 2100 skipto 10000 tcp from not ${siec} ${ssh},${poczta}
to ${siec} in recv ${oif}
# --- WWW, FTP ---
${fwcmd} add 2110 queue 4 tcp from
not ${siec} ${www} to ${siec},${myip} in recv ${oif}
${fwcmd} add 2120 skipto 10000 tcp from not ${siec} ${www} to
${siec},${myip} in recv ${oif}
${fwcmd} add 2130 queue 4 tcp from not ${siec} ${ftp} to
${siec},${myip} in recv ${oif}
${fwcmd} add 2140 skipto 10000 tcp from not ${siec} ${ftp} to
${siec},${myip} in recv ${oif}
# --- Reszta UDP ---
${fwcmd} add 2150 queue 5 udp from
not ${siec} not ${dns} to ${siec} in recv ${oif}
${fwcmd} add 2160 skipto 10000 tcp from not ${siec} not ${dns}
to ${siec} in recv ${oif}
# --- Reszta TCP ---
${fwcmd} add 2170 queue 5 tcp from
not ${siec} not ${dns},${ssh},${poczta},${ftp},${www} to ${siec} in recv ${oif}
${fwcmd} add 2180 skipto 10000 tcp from not ${siec} not ${dns},${ssh},${poczta},${ftp},${www}
to ${siec} in recv ${oif}
${fwcmd} add 10000 set 3 check-state
# SQUID
#==============
${fwcmd} add 10100 fwd
192.168.2.2,8080 tcp from ${siec} to not ${siec} dst-port 80,8080
# SSH i FTP
#==============
${fwcmd} add 11100 set 2 allow log
tcp from any to ${myip} 22 via ${oif} setup keep-state
${fwcmd} add 11200 set 2 allow tcp from any to ${myip} 80 via
${oif} setup keep-state
${fwcmd} add 11300 set 2 allow tcp from any ${ftp} to ${myip},${siec}
in recv ${oif}
${fwcmd} add 11400 set 2 allow udp from ${serwery_dns} ${dns}
to ${myip},${siec} via ${oif}
# Statefull Firewall
#==============
${fwcmd} add 12100 set 3 allow ip
from any to any via ${iif}
${fwcmd} add 12200 set 4 allow tcp from any to ${siec},${myip}
via ${oif} established
${fwcmd} add 12300 set 4 allow tcp from ${siec},${myip} to
any out xmit ${oif}
${fwcmd} add 12400 set 4 allow udp from ${siec},${myip} to
any out xmit ${oif}
# Reset IDENTa
#==============
${fwcmd} add 12500 set 5 reset log
tcp from any to ${myip},${siec} 113 in recv ${oif}
# Wyblokuj wychodzacy NetBIOS
#==============
${fwcmd} add 13100 set 5 deny tcp
from any to any 137,138,139,445
${fwcmd} add 13200 set 5 deny udp from any to any 137,138,139
# ICMP
#==============
${fwcmd} add 13300 set 2 allow icmp
from any to any
# Loguj co wyblokowane
#==============
${fwcmd} add 65000 set 6 deny log
ip from any to any
|