Firewally se používají lze používat z nejrůznějších důvodů, např.: zvýšení bezpečnosti privátních sítí proti vnějším útokům, omezení toku dat mezi sítěmi, monitorování toků dat, přesnější specifikace práv jednotlivých uživatelů, znemožnění zmapování vnitřích chráněných sítí a soustředění přístupu do jednoho místa, atd.
Typy firewalů lze rodělit na dvě hlavní skupiny:
V historii vývoje Linuxu existují zatím 4 verze paketového filtru.
Průchod paketu systémem netfilteru:
--->[PREROUTING]--->[ROUTE]--->[FORWARD]--->[POSTROUTING]---> | ^ | | | [ROUTE] v | [INPUT] [OUTPUT] | ^ | | v | ------------------------- | Local processes | -------------------------
Systém netfilteru se skládá z několika tabulek (tables) obsahujících řetězy pravidel (chains) pro filtrování a případnou úpravu procházejících paketů (NAT):
Netfilter obsahuje 5 základních řetězů pro nastavení pravidel pro filtrování a překlad paketů, ale je možné si nadefinovat vlastní řetezy a do nich přesměrovat určité pakety (zejména pro zvýšení přehlednosti nastavení netfiltru a zjednodušení pravidel):
Aby bylo možno linuxový paketový filtr použít je nutno při kompilaci jádra povolit některé volby (kompilace netfilteru pro jádro verze 2.4.14) :
CONFIG_PACKET - tato volba umožňuje některým aplikacím a programům, které to vyžadují, přímý přístup k síťovým zařízením. Příkladem je třeba tcpdump nebo snort.
CONFIG_NETFILTER - tato volba je nutná pokud chceme používat počítač jako firewall nebo gateway do internetu. Je pro nás nezbytně nutná ;-).
CONFIG_IP_NF_CONNTRACK - tento modul je nutný pro sledování spojení, je nutný pokud chceme používat NAT (Masquerading).
CONFIG_IP_NF_FTP - modul potřebný pro sledování FTP spojení, je nezbytný pokud chceme nechat projít FTP spojení přes firewall korektně.
CONFIG_IP_NF_IPTABLES - tato volba je nezbytně nutná pokud chceme provádět jakékoliv filtrování, maškarádu nebo NAT.
CONFIG_IP_NF_MATCH_LIMIT - tento modul není nezbytně nutný, ale přídává možnost určit kolik paketů za minutu může projít přes určité pravidlo, lze ho s výhodou použít pro zabránění Denial of Service útokům.
CONFIG_IP_NF_MATCH_MAC - tento modul umožňuje určovat pakety podle MAC adres (Ethernetové adresy síťových karet).
CONFIG_IP_NF_MATCH_MARK - tato volba umožnuje označovat a kontrolovat z předchozích pravidel označené pakety. Ty jejichž cíl je MARK.
CONFIG_IP_NF_MATCH_MULTIPORT - tento modul umožňuje v jednom pravidle specifikovat celý rozsah zdrojových/cílových portů, což by normálně nebylo možné
CONFIG_IP_NF_MATCH_TOS - touto volbou umožníme filtrování paketů na základě pole TOS (Type of Service), TOS může být určitými pravidly modifikován v tabulce mangle, viz CONFIG_IP_NF_TARGET_TOS.
CONFIG_IP_NF_MATCH_TCPMSS - umožní sledovat TCP SYN pakety na základě pole MSS.
CONFIG_IP_NF_MATCH_STATE - tato volba je největší novinkou v jádrech 2.4.x. Je to stavová kontrola spojení.
CONFIG_IP_NF_FILTER - tento module přidává do netfilteru základní tabulku filter - pro filtrování paketů v řetězech input, forward, output. Nutná pro jakékoliv filtrování paketů.
CONFIG_IP_NF_TARGET_REJECT - modul přídávající cíl REJECT, místo zahazování odmítaných paketů se posílají nazpět ICMP error zprávy.
CONFIG_IP_NF_TARGET_MIRROR - modul umožňující vracení nepříjímaných paketů tím, že se prohodí zdrojová a cílová adresa a paket se odešle, např. jako odpověď na DoS attack (aby nevznikaly nekonečně přeposílané pakety v případě, že by cílový počítač měl také nastavený cíl MIRROR se paketům bude snižovat TTL)
CONFIG_IP_NF_NAT - tento modul umožňuje NAT v různých formách, jako je přesměrování portů, maškaráda atd. Nutný pro masquerading privátních sítí.
CONFIG_IP_NF_TARGET_MASQUERADE - tento module přídává cíl MASQ pro masquerading, je vhodnější než SNAT v případě, že neznáme předem internetovou IP adresu (PPP, DHCP, SLIP), je ale trošku náročnější než SNAT.
CONFIG_IP_NF_TARGET_REDIRECT - modul přídávající cíl REDIRECT, užitečný např. pro transparentní proxy. Místo propuštění paketu skrz ho přemapujeme pro lokální počítač - vytvoříme transparentní proxy.
CONFIG_IP_NF_MANGLE - module přídávajíci do netfilteru tabulku mangle pro upravování paketů a změnu filtrování.
CONFIG_IP_NF_TARGET_TOS - module přídávajíci cíl TOS pro úpravu pole Type of Service.
CONFIG_IP_NF_TARGET_MARK - module přídávajíci cíl MARK pro označování paketů.
CONFIG_IP_NF_TARGET_LOG - modul přídávající cíl LOG, nutný pro logování paketů přes syslogd. Dobrý pro ladění a sledování firewallů.
CONFIG_IP_NF_TARGET_TCPMSS - řeší problém se servery ISP blokující ICMP Fragmentation needed, použítím cíle TCPMSS a předejitím problému tím, že se MSS (Maximum Segment Size) nastaví na PMTU (Path Maximum Transmit Unit).
CONFIG_IP_NF_COMPAT_IPCHAINS - přídává modul pro zpětnou kompatibilitu s ipchains.
CONFIG_IP_NF_COMPAT_IPFWADM - přídává modul pro zpětnou kompatibilitu s ipfwadm.
Po kompilaci nového jádra a jeho zavedení je ještě nutné zapnout směrování:
bash# echo 1 > /proc/sys/net/ipv4/ip_forwarda v případě, že máme dynamicky přidělovanou IP adresu (PPP) můžeme zapnout i:
bash# echo 1 > /proc/sys/net/ipv4/ip_dynaddr
Hlavním programem pro ovládání netfilteru je program iptables. Dalšími pomocnými programy jsou ješte iptables-save (pro uložení nastavení netfilteru do souboru) a iptables-restore (pro nahrání nastavení netfilteru ze souboru vytvořeného iptables-save).
Pomocí programu iptables lze určitým chainům přidávat pravidla, která se prochází v tom pořadí, v jakém byla zadána. Pokud paket odpovídá nejakému pravidlu, které přímo určí jeho cíl (ne LOG, MARK, apod.), je vyhodnocování ukončeno. Každému řetězu pravidel (chain) lze nastavit i implicitní politiku - tzn. co provést s paketem, který nebyl vyhodnocen žádným pravidlem.
Jak taková pravidla a příkazy manipulace s chainy vypadají obecně:
iptables -[ADC] chain rule-specification [options]
iptables -[RI] chain rulenum rule-specification [options]
iptables -D chain rulenum [options]
iptables -[LFZ] [chain] [options]
iptables -[NX] chain
iptables -P chain target [options]
iptables -E old-chain-name new-chain-nam
manipulace s chainy:
manipulace s pravidly v rámci chainu:
některé důležité nebo zajímavé parametry v rámci specifikace pravidla:
A konečně nějaké příklady:
bash# iptables -P FORWARD DROP- nastavení politiky (chain policy) chainu FORWARD na DROPbash# iptables -A INPUT -d 127.0.0.0/8 -j DROP- zahazování paketů pro localhostbash# iptables -A INPUT -s 193.86.135.0/24 -j ACCEPT- důvěryhodná síť, přijímáme všechnobash# iptables -A OUTPUT -d www.microsoft.cz -p tcp --destination-port http -j DROP- zákaz přístupu na webserver www.microsoft.czbash# iptables -A FORWARD -p tcp --syn -m limit --limit 1/s -j ACCEPT- ochrana proti syn-floodingubash# iptables -A FORWARD -p icmp --icmp-type echo-request -m limit --limit 1/s -j ACCEPT- ochrana proti ping-of-deathbash# iptables -t nat -A POSTROUTING -o ppp+ -j MASQUERADE- maškaráda pro pakety vycházející ze zařízení ppp0, ppp1, ...bash# iptables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to-ports 81- přesměrování TCP paketů přícházejících na port 80 na port 81
Příklad startovacího skriptu firewallu pro distribuce RedHat:
#!/bin/bash # # Firewall Script # chkconfig: 2345 11 89 # description: firewall script for 2.4.x kernel ################################################ # Fill in the values below to match your # local network. LAN_IP_RANGE="192.168.0.0/24" LAN_IP="192.168.0.1/32" INET_IP="123.124.125.126/32" LAN_BCAST_ADRESS="192.168.0.255/32" LOCALHOST_IP="127.0.0.1/32" INET_IFACE="eth1" LAN_IFACE="eth0" LO_IFACE="lo" IPTABLES="/sbin/iptables" ################################################ # some handy generic values to use ANY=0.0.0.0/0 ALLONES=255.255.255.255 # Source function library. . /etc/rc.d/init.d/functions # Source networking configuration. . /etc/sysconfig/network # Check that networking is up. [ ${NETWORKING} = "no" ] && exit 0 # Check kernel version if [ ! -x $IPTABLES ]; then echo "$IPTABLES not found - cannot run firewall !!!" exit 0 fi if [ ! -f /proc/net/ip_tables_names ]; then modprobe ip_tables > /dev/null 2>&1 if [ $? -ne 0 ]; then echo "CANNOT RUN FIREWALL !!!" exit 1 fi fi # See how we are called case "$1" in start) # Start providing access action "Starting firewall: " /bin/true # Flush all lists $IPTABLES -F # Turn on packet forwarding echo 1 > /proc/sys/net/ipv4/ip_forward # Plug up everything $IPTABLES -I INPUT -i ! lo -j DROP $IPTABLES -I FORWARD -j DROP $IPTABLES -I OUTPUT -o ! lo -j DROP ## ## Install Modules ## # Insert the active ftp module. This will allow non-passive ftp to machines # on the local network (but not to the router since it is not masq'd) needed_mods="ipt_LOG ip_nat_ftp ipt_REJECT ipt_MASQUERADE ip_conntrack_ftp" for mod in $needed_mods; do if ! ( /sbin/lsmod | /bin/grep $mod > /dev/null ); then /sbin/modprobe $mod || echo "Cannot load module : $mod" fi done ## ## Some Security Stuff ## # turn on Source Address Verification and get spoof protection # on all current and future interfaces. if [ -e /proc/sys/net/ipv4/conf/all/rp_filter ]; then for f in /proc/sys/net/ipv4/conf/*/rp_filter; do echo 1 > $f done else echo echo "PROBLEMS SETTING UP IP SPOOFING PROTECTION. BE WORRIED." echo fi ######## ## Firewall rules ## # # POSTROUTING chain in the nat table # $IPTABLES -t nat -A POSTROUTING -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu $IPTABLES -t nat -A POSTROUTING -o $INET_IFACE -j MASQUERADE # # Bad TCP packets we don't want # $IPTABLES -A FORWARD -p tcp ! --syn -m state --state NEW -j LOG --log-prefix "New not syn:" $IPTABLES -A FORWARD -p tcp ! --syn -m state --state NEW -j DROP # # Accept the packets we actually want to forward # $IPTABLES -A FORWARD -i $LAN_IFACE -j ACCEPT $IPTABLES -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT $IPTABLES -A FORWARD -m limit --limit 3/minute --limit-burst 3 -j LOG --log-level DEBUG --log-prefix "IPT FORWARD packet died: " # # Set default policies for the INPUT, FORWARD and OUTPUT chains # $IPTABLES -P INPUT DROP $IPTABLES -P OUTPUT DROP $IPTABLES -P FORWARD DROP # # Create separate chains for ICMP, TCP and UDP to traverse # $IPTABLES -N icmp_packets $IPTABLES -N tcp_packets $IPTABLES -N udp_in_packets # # The allowed chain for TCP connections # $IPTABLES -N allowed $IPTABLES -A allowed -p TCP --syn -j ACCEPT $IPTABLES -A allowed -p TCP -m state --state ESTABLISHED,RELATED -j ACCEPT $IPTABLES -A allowed -p TCP -j LOG --log-prefix "TCP not established: " $IPTABLES -A allowed -p TCP -j DROP # # ICMP rules # $IPTABLES -A icmp_packets -p ICMP -s 0/0 --icmp-type 0 -j ACCEPT $IPTABLES -A icmp_packets -p ICMP -s 0/0 --icmp-type 3 -j ACCEPT $IPTABLES -A icmp_packets -p ICMP -s 0/0 --icmp-type 5 -j ACCEPT $IPTABLES -A icmp_packets -p ICMP -s 0/0 --icmp-type 11 -j ACCEPT # # TCP rules # $IPTABLES -A tcp_packets -p TCP -s 0/0 --dport 22 -j allowed # SSH $IPTABLES -A tcp_packets -p TCP -s 0/0 --dport 25 -j allowed # SMTP $IPTABLES -A tcp_packets -p TCP -s 0/0 --dport 80 -j allowed # WWW $IPTABLES -A tcp_packets -p TCP -s 0/0 --dport 113 -j allowed # auth # # UDP ports # $IPTABLES -A udp_in_packets -p UDP -s 0/0 --sport 53 -j ACCEPT # DNS $IPTABLES -A udp_in_packets -p UDP -s 0/0 --sport 123 -j ACCEPT # NTP # # PREROUTING chain. # # Do some checks for obviously spoofed IP's # $IPTABLES -t nat -A PREROUTING -i $INET_IFACE -s 192.168.0.0/16 -j DROP $IPTABLES -t nat -A PREROUTING -i $INET_IFACE -s 10.0.0.0/8 -j DROP # # INPUT chain # # Take care of bad TCP packets that we don't want # $IPTABLES -A INPUT -p tcp ! --syn -m state --state NEW -j LOG --log-prefix "New not syn:" $IPTABLES -A INPUT -p tcp ! --syn -m state --state NEW -j DROP # # Rules for incoming packets from the internet # $IPTABLES -A INPUT -p ICMP -i $INET_IFACE -j icmp_packets $IPTABLES -A INPUT -p TCP -i $INET_IFACE -j tcp_packets $IPTABLES -A INPUT -p UDP -i $INET_IFACE -j udp_in_packets # # Rules for special networks not part of the Internet # $IPTABLES -A INPUT -p ALL -i $LAN_IFACE -d $LAN_BCAST_ADRESS -j ACCEPT $IPTABLES -A INPUT -p ALL -i $LO_IFACE -d $LOCALHOST_IP -j ACCEPT $IPTABLES -A INPUT -p ALL -i $LO_IFACE -d $LAN_IP -j ACCEPT $IPTABLES -A INPUT -p ALL -i $LAN_IFACE -d $LAN_IP -j ACCEPT $IPTABLES -A INPUT -p ALL -i $INET_IFACE -m state --state ESTABLISHED,RELATED -j ACCEPT $IPTABLES -A INPUT -m limit --limit 3/minute --limit-burst 3 -j LOG --log-level DEBUG --log-prefix "IPT INPUT packet died: " # # OUTPUT chain # $IPTABLES -A OUTPUT -p tcp ! --syn -m state --state NEW -j LOG --log-prefix "New not syn:" $IPTABLES -A OUTPUT -p tcp ! --syn -m state --state NEW -j DROP $IPTABLES -A OUTPUT -p ALL -s $LOCALHOST_IP -j ACCEPT $IPTABLES -A OUTPUT -p ALL -s $LAN_IP -j ACCEPT $IPTABLES -A OUTPUT -p ALL -o $INET_IFACE -j ACCEPT $IPTABLES -A OUTPUT -m limit --limit 3/minute --limit-burst 3 -j LOG --log-level DEBUG --log-prefix "IPT OUTPUT packet died: " ####### # Let's open the plug $IPTABLES -D INPUT 1 $IPTABLES -D FORWARD 1 $IPTABLES -D OUTPUT 1 ;; stop) action "Stoping firewall: " /bin/true echo 0 > /proc/sys/net/ipv4/ip_forward $IPTABLES -F INPUT $IPTABLES -F OUTPUT $IPTABLES -F FORWARD $IPTABLES -t nat -F PREROUTING $IPTABLES -t nat -F POSTROUTING $IPTABLES -F allowed $IPTABLES -F tcp_packets $IPTABLES -F icmp_packets $IPTABLES -F udp_in_packets $IPTABLES -X allowed $IPTABLES -X tcp_packets $IPTABLES -X icmp_packets $IPTABLES -X udp_in_packets echo ;; restart) action "Restarting firewall: " /bin/true $0 stop $0 start echo ;; status) # List out settings $IPTABLES -L ;; *) echo "Usage: $0 {start|stop|restart|status}" exit 1 esac