Hur du skyddar din Linuxmaskin med netfilter/iptables-brandväggsregler

Från och med 2.4-kärnan (egentligen 2.3.x) har man ett nytt förbättrat system som heter netfilter/iptables. Netfilter/iptables används även i 2.6-kärnor. Den kan allt som ipchains kan och lite till. Ipchains fungerar även den med 2.4-kärnor men då går det inte att dra nytta av den förbättrade funktionaliteten som kommer med netfilter/iptables. Se http://netfilter.samba.org/unreliable-guides/packet-filtering-HOWTO-8.html för mer information om hur du gör för att köra gamla ipchains i en 2.4-kärna.

Om du är osäker på vilken kärna du kör kan du i ett kommandoskal skriva: uname -a.

Hur gör man för att sätta upp lite brandväggsregler för att höja säkerheten? Här följer en kort beskrivning av netfilter/iptables och en kort beskrivning av lite handgrepp som kan göras med netfilter/iptables.

Se först och främst till att du har brandväggsstöd i din kärna. Netfilter/Iptables kan kompileras in i kärnan eller ligga som en kärnmodul, iptable_filter.o, som laddas in innan reglerna sätts upp. Du ska slå på Network packet filtering, IP tables support och FTP protocol support. Om maskering ska användas måste även Connection tracking slås på. Den är mycket användbar även om maskering inte används. Om stöd för att hålla reda på uppkopplade förbindelser (connection tracking) är kompilerat som moduler istället för att ligga fast i kärnan måste de aktuella modulerna laddas in innan de kan användas.
insmod ip_conntrack
insmod ip_conntrack_ftp


Om TCP syncookie support är påslaget kan det aktiveras vid till exempel boot med följande kommando:
echo 1 >/proc/sys/net/ipv4/tcp_syncookies

Observera att det finns ett säkerhetshål i ip_conntrack_ftp för ftp-svarstrafik. Det finns en patch på
http://netfilter.samba.org/security-fix/
Alternativt använd en 2.4.4-kärna eller nyare där detta är åtgärdat.

Om du använder regler med matchning mot MAC-adresser (ethernetadresser) bör du vara medveten om att det i kärnor äldre än 2.4.12 finns ett säkerhetshål. Om du använder sådana regler behöver du patcha filen
/usr/src/linux/net/ipv4/netfilter/ipt_mac.c
och kompilera om kärnan och installera den nykompilerade kärnan. Se bugtraq för mer detaljer. Detaljerna finns även i avsnittet om att kompilera en 2.4-kärna. Matchar du inte mot MAC-adresser eller kör en 2.4.12-kärna eller nyare behöver du inte vara orolig.

Netfilter

Netfliter är själva brandväggsstödet i kärnan. Se bild nedan:

bild som visar netfilter
ovanpå resten av kärnan



Iptables och maskering

Iptables är brandväggsreglerna som styr om trafiken ska släppas fram eller spärras. Iptables består av ett antal kedjor med brandväggsregler, INPUT, OUPUT, FORWARD och eventuella egna kedjor. Mer om de olika kedjorna hittar du lite längre ned på denna sida. NAT står för Network Address Translation och innebär en omskrivning av en adress där maskering är en sådan form av adressomskrivning. För mer information om maskering se separat avsnitt längre ner.

Iptables, maskering och ipchains ligger som moduler/block ovanpå netfilter.

bild som visar netfilter
och ovanpå den blocken för iptables och maskering



Hur netfilter/iptables fungerar

Netfilter/iptables fungerar enligt följande:

Routing

Routing bestämmer i vilken riktning trafiken ska gå. Det kan vara till den egna datorn eller vidare ut via forward. Ut kan då vara till exempel ett annat nätverkskort.

INPUT

Input är de brandväggsregler som reglerar inkommande trafik till den egna datorn.

OUTPUT

Output är de brandväggsregler som reglerar trafiken ut från den egna datorn.

FORWARD

Forward är de brandväggsregler som typiskt reglerar trafiken mellan två nätverksinterface.

Prerouting

Prerouting innehåller förbearbeting av trafiken, till exempel adressomskrivning, NAT.

Postrouting

Postrouting innehåller efterbearbetning av trafiken, till exempel adressomskrivning, NAT.

Du som använt ipchains innan är van vid att all trafik till datorn passerar INPUT-kedjan, oavsett om den är avsedd för datorn själv eller menad att routas vidare (och då passera FORWARD-kedjan). Så är det inte i iptables: trafiken som ska routas vidare (om FORWARD tillåter det) passerar inte INPUT.

Skiss över de olika delarna i netfilter/iptables
Bild 1

Brandväggsreglernas ordning har betydelse då de i drift används i den ordning de står. Om två regler matchar samma trafik kommer den regel som står först i ordning att vara den som används.

Genom att ta hänsyn till ordningen går det t.ex. att sätta upp regler som släpper fram viss typ av trafik och längre ned i listan regler som spärrar all typ av trafik.

Genom att kombinera IP-adress med mask får vi ett intervall av IP-adresser. Vill vi att en brandväggsregel endast ska gälla för datorer på Linköpings universitet kan vi sätta upp att regeln gäller för 130.236.0.0/16, dvs 130.236.0.0 till 130.236.255.255. vill vi att den enbart ska gälla för en dator anger vi datorns IP-adress och mask 32, t.ex. 172.22.1.42/32. Se avsnittet en kort introduktion till TCP/IP-trafik för mer detaljer.

Standardregler (Defaultregler)

Börja med att sätta upp standardregler (defaultregler) för inkommande och utgående trafik och för omdirigerad trafik. Att rekommendera är att du sätter förvalt till DROP för inkomande och omdirigering (FORWARD). DROP kastar paketen utan att skicka några svar. För utgående trafik vill vi släppa fram allt och sätter den däremed till ACCEPT. Notera att det är skillnad på stora och små bokstäver.
/sbin/iptables -P INPUT DROP
/sbin/iptables -P FORWARD DROP
/sbin/iptables -P OUTPUT ACCEPT

Som standrard till iptables finns endast DROP och ACCEPT. Förutom dessa finns det även tillägg till iptables som innehåller LOG och REJECT. Mer om dessa längre fram. Det går även att ladda in olika moduler till netfilter/iptables och att skriva egna moduler. Ett exempel på modul som används nedan är state.

Rensa bort eventuella gamla brandväggsregler

Fortsätt därefter med att rensa bort eventuella gamla regler genom att göra
/sbin/iptables -F
/sbin/iptables -t nat -F

Rensa även bort eventuella gamla kedjor
/sbin/iptables -X

Sätta upp standardregler och rensning av gamla regler och gamla kedjor görs lämpligen innan nätverket sätts upp på datorn. När väl nätverket är igång på datorn kan brandväggsreglerna sättas upp. Se /etc/rc.d/init.d/firewall-start, respektive /etc/rc.d/init.d/firewall i ett större exempel.

Brandväggsregler

Nu är det dags att börja sätta upp brandväggsregler. Nya regler läggs till med -A (append) för att lägga till en brandväggsregel i slutet på en kedja, -I för att lägga till en brandväggsregel i början av en kedja. Vi kommer här att koncentrera oss på att sätta upp brandväggsregler in och ut till den egna datorn (localhost). Nya kedjor skapas med -N.

När det kommer in trafik från nätet till datorn tittar iptables på reglerna för inkommande trafik och använder den brandväggsregel som är den första i listan att matcha den aktuella typen av trafik.

Flaggorna till iptables för att ställa in protokoll, portar, avsändar- och mottagaradress etc. som ska användas till brandväggsreglerna är:

Portar, adresser, interface etc. kan föregås med ett utropstecken, !, vilken ger en negation.

Innan vi sätter upp några regler skapar vi en variabel ME som vi tilldelar den egna datorns IP-adress som värde. t.ex. ME=172.22.1.42 . Om datorn får sin IP-adress via t.ex. dhcp måste vi ta reda på vad den har för IP-adress. Det kan vi göra med:
ME=`/sbin/ifconfig eth0 |sed -n '/inet/s/^[ ]*inet addr:\([0-9.]*\).*/\1/p'`

logdrop

Vi börjar med att skapa en egen kedja som loggar och kastar all trafik som kommer till kedjan. Loggning slås på genom att lägga till en regel som gör LOG. Loggning av brandväggsregler görs med syslog. Därefter kastas trafiken med DROP.
/sbin/iptables -N logdrop
/sbin/iptables -A logdrop -j LOG
/sbin/iptables -A logdrop -j DROP
Observera ordningen på dessa två regler. Loggningen måste ske först. Om reglerna är i omvänd ordning kastas trafiken först innan den hinner loggas. Nu går det att från brandväggsregler i de andra kedjorna hoppa till (anropa) kedjan logdrop som loggar och kastar trafiken.

Netbus

Därefter sätter vi upp en regel som anropar logdrop för att spärra ut alla eventuella försök att använda netbus. Även om det inte påverkar oss som kör Linux kan det vara intressant att se i loggarna.

/sbin/iptables -A INPUT -p tcp --destination-port 12345 -j logdrop

Regel för inkommande tcp-trafik till port 12345 kommer därmed att loggas och kastas.

Likadant kan vi sätta upp en regel för udp-trafik till port 12345.

/sbin/iptables -A INPUT -p udp --destination-port 12345 -j logdrop

Kasta nya ej SYN-paket

sedan sätter vi upp två regler för att logga och kasta nya tcp-paket som inte är uppkopplingsbegäran (SYN-paket) och som inte hör till någon etablerad förbindelse (det vill säga inte svarspaket).

Dessa regler tittar på om det är TCP-trafik som inte är SYN-paket, -p tcp ! --syn, och om det är nytt för netfilter, -m state --state NEW. Loggningen görs här med en extra text som hamnar först på loggraden i loggfilen, -j LOG --log-prefix "En text ".


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

Vissa buggiga Microsoftprodukter kan skicka några extrapaket efter att en förbindelse har kopplats ner. Dessa paket kommer att loggas och kastas av reglerna ovan men det är att betrakta som ofarligt/harmlöst.

Spärra vissa nät

Näten 10.0.0.0/8, 172.16.0.0/12 och 192.168.0.0/16 är nät som används endast för internt bruk. Dessa nät ska ej förekomma ute på Internet. Såvida du inte sitter bakom en maskerande brandvägg ska dessa adresser ej förekomma på nätet i närheten av datorn. Om en sådan avsändaradress trots allt förekommer är den en uppenbar förfalskning. Ett undantag är Comhem som envisas med att använda sådana adresser.

/sbin/iptables -A INPUT --source 10.0.0.0/8 -j DROP
/sbin/iptables -A INPUT --source 172.16.0.0/12 -j DROP
/sbin/iptables -A INPUT --source 192.168.0.0/16 -j DROP

Eftersom all trafik ska spärras ut oberoende av protokoll anges inte protokoll i reglerna.

Prata med sig själv

Vidare sätter vi upp regler som gör att datorn får prata med sig själv, dvs 127.0.0.0 - 127.255.255.255 in till interface loopback får etablera kontakt.

/sbin/iptables -A INPUT --in-interface lo --source 127.0.0.0/8 -j ACCEPT

Likaså vill vi tillåta vår adress på det externa interfacet eth0 att få prata med sig själv via lo.

/sbin/iptables -A INPUT -p tcp --in-interface lo --source $ME --destination $ME -j ACCEPT

Därefter kan vi passa på och spärra all eventuell trafik från omvärlden med avsändaradress 127.0.0.0 - 127.255.255.255.

/sbin/iptables -A INPUT --in-interface ! lo --source 127.0.0.0/8 -j DROP

Här kastas all trafik med avsändaradress 127.0.0.0 - 127.255.255.255 som inte kommer in via loopback.

ICMP

ICMP kan i stort sett spärras ut helt men vill vi kunna köra ping och traceroute måste en del ICMP-trafik kunna ta sig tillbaka in. Likaså är det bra att ta emot ICMP svaret Destination Unreachable, ICMP-typ 3, för att själv få reda på om en dator, ett nät eller en port är onåbar. Source Quench är också bra att ta emot. Om avsändare inte anges är det samma som att avsändare är alla IP-adresser. Som första regel bland icmp-reglerna kan det vara vettigt att spärra för inkommande ICMP echo (ping) till det egna nätets broadcastadress för att minska smurfpingandet på det egna nätet. Det göra att den här datorn inte svarar på pingpaket till broadcast. I annat fall hjälper den här datorn också till med att fylla nätet med skräp om den hade svarat. Återigen om datorn får sin IP-adress via t.ex. dhcp måste vi ta reda på vad den har för broadcast-adress. Det kan vi göra med:
MINBROADCASTADRESS=`/sbin/ifconfig eth0 |sed -n '/inet/s/^.*Bcast:\([0-9.]*\).*/\1/p'`

/sbin/iptables -A INPUT --destination $MINBROADCASTADRESS/32 -j DROP

Därefter är det dags att sätta upp regler som släpper in viss ICMP-trafik. ICMP-typ kan antingen ges i namnform:

/sbin/iptables -A INPUT -p icmp --icmp-type destination-unreachable -j ACCEPT
Lista namn med:/sbin/iptables -p icmp --help

Det går även att skriva ICMP-typ i numerisk form:

/sbin/iptables -A INPUT -p icmp --icmp-type 3 -j ACCEPT
ICMP-kod kan ges till ICMP-typ där det ges på formen ICMPTYP/ICMPKOD. Till exempel: 3/3.

Brandväggsreglerna blir då:
/sbin/iptables -A INPUT -p icmp --icmp-type 0 -j ACCEPT
/sbin/iptables -A INPUT -p icmp --icmp-type 8 -j ACCEPT
/sbin/iptables -A INPUT -p icmp --icmp-type 3 -j ACCEPT
/sbin/iptables -A INPUT -p icmp --icmp-type 11 -j ACCEPT

Egna servertjänster

För egna servertjänster behövs brandväggsregler som släpper in uppkopplingar till den aktuella servertjänsten. Nedan har vi tillåtit följande trafik: ssh, smtp (mail) och WWW.

# Släpp in trafik till servertjänster på låga portar
# Tjänst protokoll klientportar serverport
# ssh tcp 1-65535 22
/sbin/iptables -A INPUT -p tcp --destination-port 22 -j ACCEPT
# smtp tcp 1-65535 25
/sbin/iptables -A INPUT -p tcp --destination-port 25 -j ACCEPT
# www tcp 1-65535 80
/sbin/iptables -A INPUT -p tcp --destination-port 80 -j ACCEPT

För att höja säkerheten en liten gnutta går det att lägga till att netfilter/iptables ska titta på om det är en ny förbindelse eller ej och tillåta nya uppkopplingsförbindelser respektive släppa fram fortsättningstrafik som hör till en upprättad förbindelse men ingenting annat. För att det ska fungera måste Connection tracking vara påslaget i kärnan eller kompilerat som moduler som laddas in med insmod eller modprobe. Följa förbindelser åstadkoms genom att använda state: -m state --state NEW och för att se att det är en uppkopplingsbegäran måste vi till tcp ge flaggan --syn. För fortsättningstrafiken behövs en regler som släpper fram endast relaterad trafik.

Detta ger:
# Släpp in trafik till servertjänster på låga portar
# Tjänst protokoll klientportar serverport
# ssh tcp 1-65535 22
/sbin/iptables -A INPUT -m state --state NEW -p tcp --syn --destination-port 22 -j ACCEPT
/sbin/iptables -A INPUT -m state --state ESTABLISHED,RELATED -p tcp --destination-port 22 -j ACCEPT
# smtp tcp 1-65535 25
/sbin/iptables -A INPUT -m state --state NEW -p tcp --syn --destination-port 25 -j ACCEPT
/sbin/iptables -A INPUT -m state --state ESTABLISHED,RELATED -p tcp --destination-port 25 -j ACCEPT
# www tcp 1-65535 80
/sbin/iptables -A INPUT -m state --state NEW -p tcp --syn --destination-port 80 -j ACCEPT
/sbin/iptables -A INPUT -m state --state ESTABLISHED,RELATED -p tcp --destination-port 80 -j ACCEPT

Svarstrafik

För utgående uppkopplingar behöver vi sätta upp regler som släpper in svarstrafiken.

Antingen sätter vi upp liknande regler som tidigare med ipchains och för tcp-trafik tittar på om det är en uppkopplingsbegäran eller ej med hjälp av ! och flaggan --syn.

Den bättre metoden är att använda state och endast tillåta relaterad trafik till våra etablerade förbindelser.
/sbin/iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT

För att RELATED ska fungera för FTP-trafik måste kärnmodulen ip_conntrack_ftp vara laddad. Istället för att ha den som en kärnmodul går det även att vid kompilering av kärnan aktivera CONFIG_IP_NF_FTP så att den ligger fast inbäddad i kärnan istället för att ha den som en kärnmodul. De flesta linuxdistributioner har den kompilerad som en kärnmodul.

Loggning av spärrad trafik

Enklaste sättet att få loggning på spärrad trafik är att sätta upp en regel som loggar och spärrar och lägga denna sist.

/sbin/iptables -A INPUT -j logdrop

ARP-spoofing

ARP används vid lokal trafik för att slå upp mellan en dators IP-adress och dess hårdvaruadress/macadress/ethernetadress. När dator A vill kommunicera med dator B på samma lokala nätverk känner A endast till B:s IP-adress. A skickar då ut en förfrågan (ARP-fråga) på det lokala nätverket efter datorn med B:s IP-adress. B svarar (ARP-svar) och skickar med sin ethernetadress. På det viset känner de till varandras ethernetadresser och kan vidare kommunicera direkt med varandra.

Skydd mot arp-spoofing

ARP-svaren går att förfalska (spoofa) men ett visst skydd mot sådana falska svar går att sätta upp. Pinga din defaultrouter/defaultgateway och håll tummarna att ingen ARP-spoofar dig just nu. Gör sedan: /sbin/arp -an. Du ska nu ha en rad som ser ut ungefär så här:
? (17.42.3.1) at 00:80:3E:77:4B:E6 [ether] on eth0
där 17.42.3.1 är din defaultrouter. Det kan förekomma fler rader i ARP-cachen men de kan du ignorera.

Nu ska du skriva in en permanent rad i din ARP-cache (gäller tills du bootar om) för din defaultrouter.
/sbin/arp -s 17.42.3.1 00:80:3E:77:4B:E6
Se gärna till att detta görs varje gång datorn bootar.

På samma sätt kan du göra för andra datorer på ditt lokala nätverk.

Skydd mot att utomstående trafik kommer från rätt router

Du kan sätta upp ett skydd mot att trafik från omvärlden verkligen kommer via din defaultrouter och har defaultrouters ethernetadress.

Börja med att definiera vad som är lokalt nätverk.
LOCALNETS="17.42.3.0/24"

Fortsätt med att tala om routerns ethernetadress:
DEFGWETHSOURCES="00:80:3E:77:4B:E6"

Om du har flera routrar, till exempel för redundans, ska alla routrars ethernetadress stoppas i i variabeln DEFGWETHSOURCES. Exempel:
DEFGWETHSOURCES="00:80:3E:77:4B:E6 00:02:2D:04:DF:25"

Nu är det dags att sätta upp regler med iptables. Börja med att skapa en ny kedja för ethernetkontrollen:
/sbin/iptables -N ethchk 2>/dev/null

Lägg in de lokala näten i kedjan så att om det är lokal trafik ska vi hoppa ut ur kedjan igen:

for ln in $LOCALNETS; do
   /sbin/iptables -A ethchk --source $ln -j RETURN
done

Nästa steg är att lägga in regler för trafik som kommer från omvärlden via rätt router/routrar. Den trafiken som kommer från rätt router/routrar ska inte behandlas vidare i denna kedja:

for mac in ${DEFGWETHSOURCES}; do
   /sbin/iptables -A ethchk -m mac --mac-source $mac -j RETURN
done

Sist i kedjan lägger vi in regler för att logga och kasta all övrig trafik. Logga med texten ethchk i loggarna.

/sbin/iptables -A ethchk -j LOG --log-prefix "ethchk: "
/sbin/iptables -A ethchk -j DROP

När detta är gjort är det dags att lägga in en regel som hoppar till kedjan och gör denna kontroll. Är trafiken godkänd går den vidare till nästa brandväggsregel. Är trafiken inte godkänd fastnar den i logdrop i kedjan ethck. Lägg in denna regel innan alla ordinarie brandväggsregler. Ovan blir det innan netbus-reglerna.
/sbin/iptables -A INPUT --in-interface eth0 -j ethchk

Regler som tittar på ethernetadresser även för lokal trafik kan eventuellt vara ett bra komplement till ovanstående.



Tack Kent Engström, UNIT, för grunderna till ARP-spoofingskyddet.

PPP-förbindelser och brandväggsregler

Här är en snabbguide för dig som kör PPP.
# Ladda modulerna för connection-tracking (behövs inte om stödet ligger fast i kärnan).
insmod ip_conntrack
insmod ip_conntrack_ftp

# Skapa en ny kedja som ges namnet block. Kedjan block släpper endast fram svarstrafik till redan etablerade förbindelser och den tillåter nya förbindelser om de kommer från det egna nätet eller den egna maskinen.
iptables -N block
iptables -A block -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -A block -m state --state NEW -i ! ppp0 -j ACCEPT
iptables -A block -j DROP

# Hoppa till den nya kedjan från INPUT- och FORWARD-kedjorna.
iptables -A INPUT -j block
iptables -A FORWARD -j block


Lista regler

Lista alla regler görs med:
/sbin/iptables -L


Ett större exempel

Här hittar du ett större exempel.


Maskering

Maskering är en form av adressomskrivning. Avsändaradressen skrivs om så att det ser ut som att det är brandväggens utsida som skickar trafiken.

FTP och maskering

För att ftp ska fungera tillsammans med maskering behöver man ladda in kärnmodulerna ip_conntrack_ftp och ip_nat_ftp .

De kan laddas in med:
modprobe ip_conntrack_ftp
modprobe ip_nat_ftp

För att pptp ska fungera tillsammans med maskering behövs kärnmodulerna ip_conntrack_pptp och ip_nat_pptp.

De kan laddas in med:
modprobe ip_conntrack_pptp
modprobe ip_nat_pptp.





Nedan följer några exempel på maskering.

Exempel på en enkel maskerande brandvägg

Exempel på en dator med två nätverkskort, Linux, netfilter/iptables och maskering.

Om du vill kunna köra irc från en dator bakom en maskerande brandvägg brukar det vara nödvändigt att släppa in ident från irc-servern. Till det behövs ident-maskering, midentd är en sådan. Läs mer på freshmeat.net.



Ett lite större exempel på en maskerande brandvägg

Ett lite större exempel på en maskerande brandvägg.



RedHat/Fedora

Om du kör RedHat 7.1 eller nyare RedHat eller Fedora core kan du sätta upp brandväggsregler för hand enligt ovan. I äldre RedHat kan du inte rakt av använda iptables eftersom de kör med kärnor äldre än 2.4. När brandväggsreglerna är igång kan du spara dessa med iptables-save > /etc/sysconfig/iptables.

Observera att du inte behöver boota om datorn om du har följt beskrivningen ovan och kört igång brandväggsreglerna och sparat dem med iptables-save > /etc/sysconfig/iptables.


Trimmning av brandväggsinställningarna

Några saker som kan göras för att trimma upp hastigheten på brandväggen är att:

Mer avancerade saker

Ovan beskrivs grunderna i netfilter/iptables. Det finns mycket mer avancerade saker som kan göras med hjälp av netfilter/iptables.
Här hittar du lite beskrivningar av några av de lite mer avancerade sakerna du kan göra. Jag kommer att fylla på sidan vart efter.

Länkar

Den officiella netfiltersidan http://netfilter.samba.org/

Läs gärna även IP Masquerade HOWTO. Den tar även upp NAT/maskering med netfilter/iptables.

Oskar Andreasson Iptables Tutorial: http://iptables-tutorial.haringstad.com/

Copyright © 2010 Kjell Enblom.
This document is covered by the GNU Free Documentation License, Version 1.1