Routing i firewall

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.

Na skróty
Kontakt