Sunday, July 11, 2010

Zapora ogniowa w Linuksie na komputerze domowym

Wiele osób pyta jak skonfigurować zaporę na komputerze domowym, często jest to podobna konfiguracja więc dlaczego nie stworzyć pewnego wzorca?

Przygotowałem taki wzorzec, nie sprawdzałem go pod każdym kątem więc może coś nie działać, zwłaszcza na desktopie, dlaczego? Ponieważ to właśnie na nim więcej jest oprogramowania, lub jak kto woli bajerów np. komunikatory itp. itd.. Tak więc postawiłem za cel sobie napisanie takiej zapory, aby tworzyła najlepszy kompromis między bezproblemowym użytkowaniem komputera (wygoda), bezpieczeństwem i prędkością.

Najpierw należy wspomnieć o założeniach zapory (polityce):
  • zapora korzysta z architektury klient-serwer, desktop jest klientem, jego użytkownik może inicjować połączenia (porty źródłowe aplikacji klienckich to zakres 1024-65535), serwery nie mogą inicjować połączeń z naszym komputerem - na tej samej zasadzie działa przekazywanie ruchu z mechanizmem NAT
  • odpowiedz serwera jest akceptowana poprzez mechanizm filtrowania stateful
  • zapora zezwala na przyjmowanie, wysyłanie i przekazywanie komunikatów protokołu ICMP (np. polecenie ping)
  • zapora zezwala na przyjmowanie pakietów kierowanych do interfejsu local loopback, czyli lo
  • zapora udostępnia dwie usługi, pierwsza to zasoby sieciowe jakie oferuje pakiet Samba (często użytkownicy instalują taki serwer na potrzeby wymiany plików wewnątrz sieci prywatnej - domu) oraz SSH, czyli szyfrowany terminal, jest on dostępny również z zewnątrz a nie tylko z wewnątrz jak SMB
Ponieważ zapora wykorzystuje mechanizm NAT należy uruchomić tą funkcję usuwając znak komentarza '#' przed linią '# net.ipv4.ip_forward=1' w pliku /etc/sysctl.conf

root@home:/home/grzesiek# cat /etc/sysctl.conf | grep forward
# Uncomment the next line to enable packet forwarding for IPv4
net.ipv4.ip_forward=1
# Uncomment the next line to enable packet forwarding for IPv6
#net.ipv6.conf.all.forwarding=1

Następnie należy przeładować konfigurację poleceniem:
root@home:/home/grzesiek# sysctl -p /etc/sysctl.conf
net.ipv4.ip_forward = 1


Została jeszcze tylko kwestia nazwy interfejsu, którym ISP dostarcza nam połączenie (Internet), w moim przypadku jest to eth2, Twój może nazywać się zupełnie inaczej, zazwyczaj eth0 (możesz to sprawdzić wydając polecenie ifconfig). Zakładam, iż sieć wewnętrzna należy do klasy 192.168.0.0/24, czyli np. 192.168.4.0, 192.168.42.0 itp..

Oto kod konfiguracji zapory:

#!/bin/sh
##
##   DESKTOP FIREWALL by grzesiek ;)
##
##

start () {

iptables -F
iptables -X
iptables -F -t nat
iptables -X -t nat

iptables -P FORWARD DROP
iptables -P INPUT DROP
iptables -P OUTPUT DROP

# INPUT
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -A INPUT -i eth1 -s 192.168.0.0/16 -p udp -m multiport --dport 137,138 -m state --state NEW -j ACCEPT
iptables -A INPUT -i eth1 -s 192.168.0.0/16 -p tcp -m multiport --dport 139,445 -m state --state NEW -j ACCEPT
iptables -A INPUT -p tcp --dport 22 -m state --state NEW -j ACCEPT
#
# tu możemy zezwalać na łączenie się z innymi usługami świadczonymi przez nasz komputer
# np.
# iptables -A INPUT -p tcp --dport 80 -j  ACCEPT
#
iptables -A INPUT -i lo -m state --state NEW -j ACCEPT
iptables -A INPUT -p icmp -m state --state NEW -j ACCEPT
iptables -A INPUT -j REJECT --reject-with icmp-host-prohibited

# OUTPUT
iptables -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -A OUTPUT -p tcp --sport 1024:65535 -m state --state NEW -j ACCEPT
iptables -A OUTPUT -p udp --sport 1024:65535 -m state --state NEW -j ACCEPT
iptables -A OUTPUT -p icmp -m state --state NEW -j ACCEPT
iptables -A OUTPUT -j REJECT --reject-with icmp-host-prohibited

# FORWARD
iptables -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -A FORWARD -s 192.168.0.0/255.255.0.0 -p tcp --sport 1024:65535 -m state --state NEW -j ACCEPT
iptables -A FORWARD -s 192.168.0.0/255.255.0.0 -p udp --sport 1024:65535 -m state --state NEW -j ACCEPT
iptables -A FORWARD -p icmp -m state --state NEW -j ACCEPT
iptables -A FORWARD -j REJECT --reject-with icmp-host-prohibited

# NAT system
iptables -t nat  -A POSTROUTING -s 192.168.0.0/255.255.0.0 -d 0/0 -j  MASQUERADE

echo "Configuration iptables on... (more information use option: show)"
exit 0
}

stop () {
iptables -F
iptables -X
iptables -F -t nat
iptables -X -t nat

iptables -P FORWARD ACCEPT
iptables -P INPUT ACCEPT
iptables -P OUTPUT ACCEPT

iptables -t nat -A POSTROUTING -s 192.168.0.0/255.255.0.0 -d 0/0 -j  MASQUERADE

echo "Configuration iptables off (except NAT system for 192.168.0.0/16 !)... (more information use option: show)"
exit 0
}

show () {
echo "\n                            [ Table: filter ]\n"
iptables -L -nv --line-numbers -t filter
echo "\n                            [ Table: nat ]\n"
iptables -L -nv --line-numbers -t nat
echo "\n"
exit 0
}

#main:
case "$1" in 
 start)
  start ;;
 stop)
  stop ;;
 show)
  show ;;
 *)
  echo $"  Składnia: $0 {stary, stop, show}"
  echo "@@@ Firewall by grzesiek ;) @@@"
  exit 1
esac

Przedstawiony skrypt należy jeszcze dodać do rozruchu systemu, czyli do katalogu /etc/init.d/firewall. Następnie należy wykonać polecenie, które przypisze go do sekwencji startowych:

update-rc.d firewall defaults

Nasz skrypt obsługuje dwie wymagane opcje; start i stop oraz dodatkową show. Aby zobaczyć jak wygląda konfiguracja zapory należy wydać polecenie:

root@home:/home/grzesiek# /etc/init.d/firewall show

[ Table: filter ]

Chain INPUT (policy DROP 0 packets, 0 bytes)
num   pkts bytes target     prot opt in     out     source               destination         
1    22785 6326K ACCEPT     all  --  *      *       0.0.0.0/0            0.0.0.0/0           state RELATED,ESTABLISHED 
2        0     0 ACCEPT     udp  --  eth1   *       192.168.0.0/16       0.0.0.0/0           multiport dports 137,138 state NEW 
3        2   120 ACCEPT     tcp  --  eth1   *       192.168.0.0/16       0.0.0.0/0           multiport dports 139,445 state NEW 
4       10   584 ACCEPT     tcp  --  *      *       0.0.0.0/0            0.0.0.0/0           tcp dpt:22 state NEW 
5       18  1080 ACCEPT     all  --  lo     *       0.0.0.0/0            0.0.0.0/0           state NEW 
6        2   144 ACCEPT     icmp --  *      *       0.0.0.0/0            0.0.0.0/0           state NEW 
7    12728 1068K REJECT     all  --  *      *       0.0.0.0/0            0.0.0.0/0           reject-with icmp-host-prohibited 

Chain FORWARD (policy DROP 0 packets, 0 bytes)
num   pkts bytes target     prot opt in     out     source               destination         
1    36828   34M ACCEPT     all  --  *      *       0.0.0.0/0            0.0.0.0/0           state RELATED,ESTABLISHED 
2     3443  207K ACCEPT     tcp  --  *      *       192.168.0.0/16       0.0.0.0/0           tcp spts:1024:65535 state NEW 
3      174 11240 ACCEPT     udp  --  *      *       192.168.0.0/16       0.0.0.0/0           udp spts:1024:65535 state NEW 
4        7   588 ACCEPT     icmp --  *      *       0.0.0.0/0            0.0.0.0/0           state NEW 
5       39  2124 REJECT     all  --  *      *       0.0.0.0/0            0.0.0.0/0           reject-with icmp-host-prohibited 

Chain OUTPUT (policy DROP 0 packets, 0 bytes)
num   pkts bytes target     prot opt in     out     source               destination         
1    22312 3900K ACCEPT     all  --  *      *       0.0.0.0/0            0.0.0.0/0           state RELATED,ESTABLISHED 
2      794 47640 ACCEPT     tcp  --  *      *       0.0.0.0/0            0.0.0.0/0           tcp spts:1024:65535 state NEW 
3     1021 68127 ACCEPT     udp  --  *      *       0.0.0.0/0            0.0.0.0/0           udp spts:1024:65535 state NEW 
4       13  1188 ACCEPT     icmp --  *      *       0.0.0.0/0            0.0.0.0/0           state NEW 
5    14518 1240K REJECT     all  --  *      *       0.0.0.0/0            0.0.0.0/0           reject-with icmp-host-prohibited 

[ Table: nat ]

Chain PREROUTING (policy ACCEPT 16181 packets, 1264K bytes)
num   pkts bytes target     prot opt in     out     source               destination         

Chain POSTROUTING (policy ACCEPT 1754 packets, 109K bytes)
num   pkts bytes target     prot opt in     out     source               destination         
1     2941  177K MASQUERADE  all  --  *      *       192.168.0.0/16       0.0.0.0/0           

Chain OUTPUT (policy ACCEPT 15834 packets, 1320K bytes)
num   pkts bytes target     prot opt in     out     source               destination         


root@home:/home/grzesiek#

Krótki komentarz do każdej z linii:
INPUT
1 Linia: przepuszcza pakiety powrotne z połączeń, które wcześniej zainicjowaliśmy
2 Linia: przepuszcza ruch dla usługi Samba z sieci lokalnej, czyli nie przychodzącego z internetu - interfejs eth2 w moim przypadku
3 Linia: jw. porty TCP
4 Linia: zezwala na łączenie się przez SSH z każdego miejsca
5 Linia: zezwala na połączenia z interfejsem zwrotnym lo
6 Linia: zezwala na odbieranie komunikatów ICMP, czyli np. używanie polecenia ping
7 Linia: w tym miejscu wszystkie przewidziane, a tym samym dozwolone możliwości dla ruchu przychodzącego się wyczerpały, można by nie robić nic i pakiety zostałyby odrzucone ale optymalniej będzie odsyłać określony w tej regule komunikaty do nadawcy

FORWARD
1 Linia: przekazuje pakiety z połączeń, które wcześniej zainicjowali użytkownicy naszej sieci wewnętrznej - LAN
2 Linia: zezwala na przekazywanie pakietów protokołu TCP z naszej sieci do serwerów w internecie jeżeli pochodzą z portów aplikacji klienckich (1024-65535)
3 Linia: jw. porty UDP
4 Linia: zezwala na przekazywanie komunikatów ICMP między siecią WAN a LAN
5 Linia: pozostałe pakiety są odrzucane, a dla nadawcy wysyłany jest komunikat ICMP informujący, iż połączenie zostało zabronione

OUTPUT
1 Linia: zezwala na wysyłanie odpowiedzi na połączenia zezwolone przez łańcuchu INPUT
2 Linia: zezwala na wysyłanie z naszego komputera pakietów protokołu TCP do serwerów w internecie jeżeli pochodzą z portów aplikacji klienckich (1024-65535)
3 Linia: jw. porty UDP
4 Linia: zezwala na wysyłanie komunikatów ICMP z naszego komputera
5 Linia: pozostałe pakiety są odrzucane, a dla nadawcy wysyłany jest komunikat ICMP informujący, iż połączenie zostało zabronione - czyli nam :)

Czas na małe sprawdzenie, najpierw sprawdzimy jak wygląda nasza zapora z zewnątrz:

grzesiek@bvm1XX:~$ nmap 7X.X6.2X.XX5 -PN

Starting Nmap 4.62 ( http://nmap.org ) at 2010-11-07 15:18 CET
Interesting ports on PC-7X-X6-2X-XX5.xxxx-net.pl (7X.X6.2X.XX5):
Not shown: 1714 filtered ports
PORT STATE SERVICE
22/tcp open ssh

Nmap done: 1 IP address (1 host up) scanned in 8.701 seconds

oraz z sieci wewnętrznej:

[root@localhost grzesiek]# nmap 192.168.42.1 -PN

Starting Nmap 5.21 ( http://nmap.org ) at 2010-11-07 17:29 CET
Nmap scan report for 192.168.42.1
Host is up (0.00025s latency).
Not shown: 997 filtered ports
PORT STATE SERVICE
22/tcp open ssh
139/tcp open netbios-ssn
445/tcp open microsoft-ds

MAC Address: 0A:00:27:00:00:00 (Unknown)

Nmap done: 1 IP address (1 host up) scanned in 5.43 seconds
[root@localhost grzesiek]#


Jak widać wszystko jest zablokowane, oprócz tego na co zezwoliliśmy, podczas gdy możemy bez problemów korzystać z komputera. Gdyby jednak znalazły się jakieś błędy albo należało dodać jakąś funkcjonalność proszę o komentarze. Jak pisałem wcześniej zapora była tworzona szybko więc może czegoś nie przewidziałem.

Miało być krótko a wyszło jak zwykle :)

No comments:

Post a Comment