Materiały edukacyjne z informatyki
Routing, a zarazem firewall zrealizowane zostaną za pomocą iptables. Ponieważ będziemy korzystać z usługi NAT, w pliku /etc/sysctl.conf trzeba odkomentować opcję: net.ipv4.ip_forward=1
. Zanim uruchomimy pełną konfigurację firewalla, warto utworzyć prosty skrypt testowo-awaryjny. W pliku /etc/mojserwer/testf.sh (nazwy katalogu i pliku można zmienić) wpisujemy:
#!/bin/bash INTIF="eth1" INTNET="192.168.19.0/24" INTIP="192.168.19.254" EXTIF="eth0" EXTIP="`/sbin/ifconfig $EXTIF | grep 'inet addr' | awk '{print $2}' | sed -e 's/.*://'`" UNIVERSE="0.0.0.0/0" iptables -P INPUT ACCEPT iptables -F INPUT iptables -P OUTPUT ACCEPT iptables -F OUTPUT iptables -P FORWARD ACCEPT iptables -F FORWARD iptables -F -t nat if [ "`iptables -L | grep droplog`" ]; then iptables -F droplog fi iptables -X iptables -Z # Włączenie routowania iptables -t nat -A POSTROUTING -o $EXTIF -j MASQUERADE iptables -A FORWARD -i $EXTIF -o $INTIF -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
Nadajemy plikowi prawo do wykonania: sudo chmod a+x /etc/mojserwer/testf.sh
. Teraz możemy uruchomić firewall: sudo sh /etc/mojserwer/testf.sh
– i sprawdzić, czy hosty podpięte do interfejsu LAN mogą połączyć się z internetem. Powyższy skrypt zezwala na każdy ruch sieciowy, należy więc wykorzystywać go tylko do testów lub w sytuacjach awaryjnych (ewentualne problemy z firewallem).
Właściwy firewall zapiszmy w pliku /etc/mojserwer/firewall.sh (nazwę pliku można zmienić):
#!/bin/bash echo -e "Reguły iptables...\n\n" # Nazwa interfejsu LAN, adres sieci LAN i adres IP interfejsu LAN INTIF="eth1" INTNET="192.168.19.0/24" INTIP="192.168.19.1" # Nazwa interfejsu WAN i jego adres IP EXTIF="eth0" EXTIP="`/sbin/ifconfig $EXTIF | grep 'inet addr' | awk '{print $2}' | sed -e 's/.*://'`" UNIVERSE="0.0.0.0/0" # Odkomentowana opcja w /etc/sysctl.conf, więc tu może być zakomentowane #echo 1 > /proc/sys/net/ipv4/ip_forward # Wyczyszczenie wszystkich łańcuchów i reguł, określenie domyślnej polityki odrzucania pakietów (DROP). iptables -P INPUT DROP iptables -F INPUT iptables -P OUTPUT DROP iptables -F OUTPUT iptables -P FORWARD DROP iptables -F FORWARD iptables -F -t nat if [ "`iptables -L | grep drop-and-log-it`" ]; then iptables -F drop-and-log-it fi iptables -X iptables -Z # Utworzenie łańcucha drop-and-log-it. iptables -N drop-and-log-it iptables -A drop-and-log-it -j LOG --log-level info iptables -A drop-and-log-it -j REJECT # Reguły INPUT # Wszystkie połączenia z localhost iptables -A INPUT -i lo -j ACCEPT # Odrzucenie połączeń podszywających się pod lokalne iptables -A INPUT -i $EXTIF -s $INTNET -d $UNIVERSE -j drop-and-log-it # Protokół ICMP iptables -A INPUT -i $INTIF -p icmp -s $INTNET -d $UNIVERSE -j ACCEPT iptables -A INPUT -i $EXTIF -p icmp -s $UNIVERSE -d $EXTIP -j ACCEPT # Połączenia zwrotne do serwera maskarady na interfejsie LAN iptables -A INPUT -i $INTIF -s $INTNET -d $INTIP -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT # Komunikaty ICMP: ping i echo iptables -A INPUT -i $INTIF -p tcp -s $INTNET -d $UNIVERSE --dport 7 -j ACCEPT iptables -A INPUT -i $INTIF -p udp -s $INTNET -d $UNIVERSE --dport 7 -j ACCEPT # Zapytania DNS iptables -A INPUT -i $INTIF -p tcp -s $INTNET -d $UNIVERSE --dport 53 -j ACCEPT iptables -A INPUT -i $INTIF -p udp -s $INTNET -d $UNIVERSE --dport 53 -j ACCEPT # Zapytania DHCP iptables -A INPUT -i $INTIF -p udp --dport 67 -j ACCEPT # Usługi Samby (jeżeli korzystamy, odkomentować) # iptables -A INPUT -i $INTIF -p tcp -s $INTNET -d $UNIVERSE --dport 135 -j ACCEPT # iptables -A INPUT -i $INTIF -p tcp -s $INTNET -d $UNIVERSE --dport 139 -j ACCEPT # iptables -A INPUT -i $INTIF -p tcp -s $INTNET -d $UNIVERSE --dport 445 -j ACCEPT # iptables -A INPUT -i $INTIF -p udp -s $INTNET -d $UNIVERSE --dport 137 -j ACCEPT # iptables -A INPUT -i $INTIF -p udp -s $INTNET -d $UNIVERSE --dport 138 -j ACCEPT # Protokół SSH iptables -A INPUT -i $INTIF -p tcp -s $INTNET -d $UNIVERSE --dport 22 -j ACCEPT # Serwer proxy Squid na interfejsie LAN, port 3128 # iptables -A INPUT -i $INTIF -p tcp --dport 3128 -j ACCEPT # Squid3 transparent bez Dansguardiana # iptables -t nat -A PREROUTING -i $INTIF -p tcp --dport 80 -j REDIRECT --to-ports 3128 # Dansguardian + Squid3 transparent proxy iptables -A INPUT -i $INTIF -p tcp --dport 8080 -j ACCEPT iptables -t nat -A PREROUTING -i $INTIF -p tcp --dport 80 -j REDIRECT --to-ports 8080 # Połączenia przychodzące na interfejs WAN # Połączenia zwrotne do serwera maskarady na interfejsie WAN iptables -A INPUT -i $EXTIF -s $UNIVERSE -d $EXTIP -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT # Komunikaty ICMP: ping i echo. iptables -A INPUT -i $EXTIF -p tcp -s $UNIVERSE -d $EXTIP --dport 7 -j ACCEPT iptables -A INPUT -i $EXTIF -p udp -s $UNIVERSE -d $EXTIP --dport 7 -j ACCEPT # Odrzucanie i logowanie wszystkich innych połączeń przychodzących iptables -A INPUT -s $UNIVERSE -d $UNIVERSE -j drop-and-log-it # Reguły OUTPUT # Odrzucanie połączeń do sieci LAN z WAN iptables -A OUTPUT -o $EXTIF -s $UNIVERSE -d $INTNET -j drop-and-log-it # Wszystkie połączenia localhost iptables -A OUTPUT -o lo -j ACCEPT # Zezwolenie dla LAN iptables -A OUTPUT -o $INTIF -d $INTNET -j ACCEPT # Zezwolenie na DHCP reply typu broadcast - dla MS Visty iptables -A OUTPUT -o $INTIF -p udp -s $INTIP --sport 67 -d $UNIVERSE --dport 68 -j ACCEPT # Zezwolenie dla WAN iptables -A OUTPUT -o $EXTIF -j ACCEPT # Odrzucanie i logowanie wszystkie innych połączeń wychodzących iptables -A OUTPUT -s $UNIVERSE -d $UNIVERSE -j drop-and-log-it # FORWARD: Włączenie routowania, tj. usługi NAT, zwanej maskaradą, czyli IMPASQ. # Routing na interfejsie WAN iptables -t nat -A POSTROUTING -o $EXTIF -j MASQUERADE # Routowanie ustanowionych połączeń iptables -A FORWARD -i $EXTIF -o $INTIF -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT # Odblokowanie poszczególnych usług # Protokół ICMP iptables -A FORWARD -i $INTIF -p icmp -j ACCEPT # Porty wysokie iptables -A FORWARD -i $INTIF -p tcp --dport 1024:65535 -j ACCEPT iptables -A FORWARD -i $INTIF -p udp --dport 1024:65535 -j ACCEPT # Komunikaty ICMP: ping, echo iptables -A FORWARD -i $INTIF -p tcp --dport 7 -j ACCEPT iptables -A FORWARD -i $INTIF -p udp --dport 7 -j ACCEPT # Usługa DNS iptables -A FORWARD -i $INTIF -p tcp --dport 53 -j ACCEPT iptables -A FORWARD -i $INTIF -p udp --dport 53 -j ACCEPT # Protokół SSH iptables -A FORWARD -i $INTIF -p tcp --dport 22 -j ACCEPT iptables -A FORWARD -i $INTIF -p udp --dport 22 -j ACCEPT # HTTP-FORWARD-OK # HTTP -- jeżeli nie korzystamy ze squida i dansguardiana, trzeba odkomentować: # iptables -A FORWARD -i $INTIF -p tcp --dport 80 -j ACCEPT # iptables -A FORWARD -i $INTIF -p udp --dport 80 -j ACCEPT # HTTPS iptables -A FORWARD -i $INTIF -p tcp --dport 443 -j ACCEPT iptables -A FORWARD -i $INTIF -p udp --dport 443 -j ACCEPT # FTP iptables -A FORWARD -i $INTIF -p tcp --dport 20:21 -j ACCEPT iptables -A FORWARD -i $INTIF -p udp --dport 21 -j ACCEPT # Poczta: smtp, pop3, imap, legacy secure SMTP, smtp Submission, imap ssl, pop3s iptables -A FORWARD -i $INTIF -p tcp --dport 25 -j ACCEPT iptables -A FORWARD -i $INTIF -p tcp --dport 110 -j ACCEPT iptables -A FORWARD -i $INTIF -p tcp --dport 143 -j ACCEPT iptables -A FORWARD -i $INTIF -p tcp --dport 465 -j ACCEPT iptables -A FORWARD -i $INTIF -p tcp --dport 587 -j ACCEPT iptables -A FORWARD -i $INTIF -p tcp --dport 993 -j ACCEPT iptables -A FORWARD -i $INTIF -p tcp --dport 995 -j ACCEPT # Odrzucanie i logowanie wszystkich pozostałych połączeń. iptables -A FORWARD -j drop-and-log-it echo -e "Zakończono!\n\n"
Plikowi należy nadać prawa do wykonywania: chmod a+x /etc/mojserwer/firewall.sh
. Aby reguły były wczytywane podczas startu systemu w pliku /etc/rc.local dopisujemy:
cd /etc/mojserwer/ ./init_firewall.sh
Nie jest to metoda optymalna, ale skuteczna. Firewall można też zrestartować np. po zmianach) czy uruchomić ręcznie: sh /etc/rc.local
.
W przedstawionej koniguracji zdefiniowany został dodatkowy łańcuch "drop-and-log-it", do którego trafiają pakiety niepasujące do reguł połączenia. Domyślnie wszystkie te wpisy trafiają do logu systemowego /var/log/syslog poprzedzone przedrostkiem "droplog:". Lepiej jednak zapisywać je w osobnym pliku, co ułatwia ewentualną póxniejszą analizę. Torzymy więc plik /etc/rsyslog.d/20-iptables.conf i wpisujemy:
:msg, contains, "droplog: " -/var/log/iptables.log & ~
– dzięki czemu usługa rsyslog odpowiedzialna za logowanie przekieruje wpisy do pliku /var/log/iptables.log. Pozostaje jeszcze utworzenie pliku /etc/logrotate.d/iptables z zawartością:
/var/log/iptables.log { daily rotate 4 compress delaycompress missingok }
– co zabezpieczy nas przed niekontrolowanym rozrastaniem się logu firewalla. Raz na dzień log zostanie zachowany w spakowanej kopii, po czym utworzony zostanie nowy pusty plik.