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