Introduction til Iptables - Arch Linux som firewall.

Som almindelig opstart til denne guide, vil jeg betragte at man kender de normale begreber indenfor Linux, og har installeret en funktionsdygtig ArchLinux installation - elllers kan den ses her

Krav til installationen:

Da IPTABLES/Firewall er et enormt område at bevæge sig ind på, vil jeg i denne artikel kun tage diverse hovedemner op, og derefter vise et par enkelte scripts til forskellige muligheder.
Dette er ikke en absolut guide til IPTABLES, men den giver et indblik i hvad man skal kigge nærmere efter og hvad man skal være opmærksom på indenfor dette område - dog vil jeg under alle omstændigheder bede folk om at læse netfilters egen dokumentation omkring IPTABLES/netfilter HOWTO.

I denne artikel vil der også kun være taget hensyn til IPV4 og IKKE IPV6 - Men principperne er det samme.

Feedback

Da jeg startede med Linux for 2år siden, anede jeg ikke de muligheder der var her - og kan til dd stadig blive overrasket over de mange utrolige ting som man kan udføre - Dette skriver jeg gerne selv om på min egen linuxside (Som er generelle ting hvad jeg syntes er spændene)

Hvis nogen skulle være i tvivl så er jeg meget interesseret i feddback af enhver art. Er der noget der er uklart, noget der mangler, sider jeg burde linke til, noget der er direkte forkert, døde links, manglende installationskilder eller andre kommentarer. Skriv til udbytossen@gmail.com


Introduktion til IPTABLES:

Hvis man står med det brændende ønske omkring at ville have have fuld kontrol over sit netværk eller hvem der har adgang til en maskine, vil jeg stærk anbefale IPTABLES som er et modul i kernel som filtrerer de pakker som bliver sendt på netværket. Dette kan bruges til beskyttelse af enkeltstående maskiner, eller som firewall for et helt netværk. Derfor vil jeg anbefale folk at starte med at læse netfilter´s dokumentation igennem (Specielt hvis man vil ud i flere detaljer) som kan findes her: Netfilter Dokumentation

Denne guide kan være til extrem stor hjælp i tilfælde af du skal administrere større netværk, da jeg ikke kommer ind på alle detaljer i denne howto - dog vil den grundlæggende viden komme

Selve installationen:

Selve installationen af IPTABLES på; Archlinux er det nemmeste i hele denne sammenhæng, men dog vil jeg stærkt pointere at det er en selv der opsætter reglerne for hvordan og hvilken trafik der kommer videre eller ind på maskinen.

$ pacman -Syu
$ pacman -Sy iptables

Derefter ville IPTABLES være installeret på din maskine og du kan nu starte/stoppe/reloade den med den normale kommando:

$ /etc/rc.d/iptables {start | stop | reload }

Selve scriptet kan man nu gøre på mange forskellige måder - enten ved at bruge de indbyggede kommandoer og script og taste reglerne ind løbende eller man kan lave et script selv direkte i hånden. Det er helt op til en selv men grundlæggende er alt det samme uanset hvilken metode man vælger.
Da jeg personligt bedst kan lide at lave scriptet selv fra bunden af - vil jeg derfor gøre dette i denne forklaring.

Forklaringer:

For at kunne opsætte regelsæt, må man nok starte med at have en forklaring på hvilke ting og hvorfor det hele er som det er. Det vil jeg komme ind på her - men igen kun de vigtigste kommandoer - da man iptables har de korrekte oplysninger om resten. Dog vil jeg prøve at forklare løbende hvorfor - hvad og hvordan.

For at starte et sted :
Der vil altid være 3 kæder i IPTABLES, som man ikke kan slette --> INPUT - OUTPUT - FORWARD. Til gengæld kan man lave alle de kæder ekstra man vil og skal bruge i sit script.
Enhver pakke der modtages på et netkort vil have en masse oplysninger vedhæftet omkring afsender, modtager porte osv. Det er de oplysninger som vi bruger i IPTABLES til at filtrere vores pakker - efter VORES ønsker.
En firewall, baseret på pakke-filtrering , består egentlig af en masse kæder med påhæftede tabeller indeholdende accept og benægtelse regler. Disse regler kan man sætte efter hvilke ønsker man har til sit netværk.

Først og fremmest kræver det en masse viden omkring OSI-modellen, som jeg ikke vil komme ind på her, men det er frit tilgængelige informationer på internettet: wikipedia´s version

INPUT - Pakker der modtages af et netkort og som har en af den lokale host´s IPadresser som destination, vil blive routet af INPUT kæden først. Her er det vigtigt at det er KUN de pakker vi have til vores lokale host - bliver accepteret.
OUTPUT - Pakker der sendes fra localhost (processor - programmer) går gennem denne kæde ud fra maskinen. I de fleste tilfælde accepterer man trafikken i dennen kæde.
Forward - Pakker der modtages og skal videre til en anden maskine - NAT(Network Area Translation) foregår via denne kæde. Her er det man bestemmer hvilke pakker der modtages inde på vores lille netværk! På en enkelt maskine vil dette ikke være nødvendigt - da vi ikke skal sende pakker videre til andre maskiner. Til FORWARD kæden er der dog flere underkæder - nemlig PREROUTING (som er routing af pakkerne inden de aktuelle regler tjekker dem) og POSTROUTING (som er efter de aktuelle regler har tjekket dem).

Porte - Man skal vide hvilke programmer der bruger hvilke porte og hvilken slags transportmetode der bruges. Her findes der mange - men de 3 vi vil bruge her er TCP, UDP og ICMP. Listen over hvilke porte der bruges af hvad er forudbestemt og kan ses i filen /etc/services. Dog skal man vide forskellen på typerne:
TCP - (Transmission Control Protocol) Dette er en forbindelsesorienteret protokol, der mest af alt bekræfter alt data modtages frem og tilbage. Det er samtidigt også den mest benyttede protokol.
UDP - (User Datagram Protocol) Dette er en forbindelsesløs protokol, der ikke bekræftiger modtaget data. Den sender det den skal og ikke andet.
ICMP - (Internet Control Message Protocol) som bruges til bla. ping osv. Denne kan man faktisk ikke betegne som en transportmetode, men det er en vigtig del af at sætte en firewall op.

Policies - Det er hvilken standart politik man vælger til at starte med. Enten kan man acceptere alt (ACCEPT) eller benægte alt (Deny) Her skal man tænke lidt over hvad man vil og hvilken maskine det script man vil lave er til. Dog er det mest anbefalede benægt. Her sætter man regler efter hvilke ting man vil acceptere, og ALT andet bliver smidt væk. Man kan også vælge det modsatte, men jeg vil ikke anbefale dette.
Man kan også afvise pakkerne(REJECT), hvilket vil give en ICMP-meddelse til afsenderen.

Muligheder under en filtrering - Idet man laver en regel kan man sætte visse krav til disse regler som f.eks afsender/modtager, hvilke port det skal være osv. Disse muligheder har jeg defineret de mest almindelige her nedenunder - dog er der mange flere muligheder - se man IPTABLES:

Grundlæggende:

  -t -> Tabel - hvilken slags tabel man vil tilføje reglen (Default er filter)
  -A -> Append - Hvilken kæde reglen skal tilføjes
  -N -> New - tilføjer nyt objekt
  -F -> Flush - flusher objektet
  -D -> Delete - sletter objektet.
  -P -> Policies - sætter Politik på objektet

Hvilke muligheder man har med de enkelte objekter/kæder

  -p -> Beskriver protokollen
  -s -> Beskriver kilde ipadressen
  -d -> Beskriver destinations ipadressen
  -i -> Beskriver input interfacet.
  -o -> Beskriver output interfacet.
  -j ->Jump target - Hvad skal der gøres med pakkerne
  -f -> beskriver fragmenter af pakker.

Til detaljer af TCP protokol:

  --tcp-flags (SYN,ACK,FIN,RST,URG,PSH)
  --syn (SYN,RST,ACK SYN)
  --source-port
  --destination-port
  --tcp-option

Til beskrivelse af UDP protokol:

  --source-port
  --destination-port

Til beskrivelse af ICMP:

  --icmp-type

Udover disse muligheder, er der en række udvidelser tilgængelige i IPTABLES

    mac
          --mac-source
    limit
          --limit
          --limit-burst
    owner
          --uid-owner userid
          --uid-owner groupid
          --pid-owner processid
          --sid-owner processid
    state
          NEW
          ESTABLISHED
          RELATED
          INVALID
Med alt dette i frisk erindring kan vi nu lave en regel - og derefter beskrive den, således at man får en forståelse for hvad det er helt præcist der sker
$IPTABLES -t nat -A FORWARD -s 143.65.243.21 -d 29.34.56.78 -p tcp --dport 22 -j DNAT --to-destination 192.168.0.10:22

Hvis man f.eks vil gøre sit script nemmere, kan man i starten angive en variabel, som man senere kan kalde igen --> derfor $IPTABLES - men mere om det senere.
Vi beder her iptables og at bruge en tabel = NAT og tilføjer den til kæden = FORWARD HVIS:
* den kommer fra IPadressen 143.65.243.21og
* er adresseret til IP-adressen 29.34.56.78 og
* kommer på port 22. hvis dette passer så
* destinationsNATter vi den til destinationen 192.168.0.10 port 22 (læg mærke til det lille kolon MEGET VIGTIGT!!!!!
Hvis ikke den pakke der kommer ind passer til disse regler - vil den følge de default policies der er sat.

Derfor er det meget vigtigt at man først og fremmest forstår OSI-modellen, derefter har gennemgået Netfilter´s Howto og dermed har en forståelse hvorfor og hvordan pakkerne går igennem vores system - og hvordan pakkernes header bliver læst. Nok om det - Nu til det alvorlige i hele dette cirkus:

Script for enkelt maskine:

Jeg vil nu starte med at lave en enkelt script til en enkelt maskine der står f.eks på et LAN-netværk og modtager pakker. Denne kunne i princippet ligeså godt være en maskine der sidder direkte på netværket!

Forudsætninger:
Maskinen har kun et netværkskort med IPadressen 192.168.0.10
Vi ønsker åbent for FTP - SSH - HTTP - POP3

Derfor starter vi med at lave et script som ligger i /etc/iptables/ og kalder det test_firewall


#Opretter en variabel med vores IPadresse og 1 med Interfacet og 1 med vores loopback-interface
LAN_IP="192.168.0.10"
LAN_NIC="eth0"
Lo_NIC="lo"

# Vi skal have loaded enkelte moduler da vi ønsker at bruge FTP
modprobe ip_nat_ftp
modprobe ip_conntrack_ftp

# Flusher og nulstiller vores kæder
$IPTABLES -F # Flusher alle kæder (Når der ikke er betegnelse på)
$IPTABLES -X # Nulstiller alle kæder (-----------| |--------------)

# Sætter vores default Policies
$IPTABLES -P INPUT DROP # Benægter alt input
$IPTABLES -P FORWARD DROP # Benægter al forwardning
$IPTABLES -P OUTPUT ACCEPT # Accepterer alt trafik UD

# Opretter de kæder vi skal bruge
$IPTABLES -N intern
$IPTABLES -N extern

# Accepterer al trafik fra vores loopback interface
$IPTABLES -t filter -A lo -i $LO -j ACCEPT


# Nu er vi klar til at åbne de enkelte porte vi ønsker - da det er på lokalmaskinen vi vil acceptere bruger vi EXTERN kæden til dette
$IPTABLES -t filter -A extern -p tcp --dport 21-i $LAN_NIC -j ACCEPT # Accepterer trafik ind til FTP
$IPTABLES -t filter -A extern -p tcp --dport 22 -i $LAN_NIC -j ACCEPT # Accepterer trafik ind til SSH
$IPTABLES -t filter -A extern -p tcp --dport 80 -i $LAN_NIC -j ACCEPT # Accepterer trafik ind til HTTP
$IPTABLES -t filter -A extern -p tcp --dport 110 -i $LAN_NIC -j ACCEPT # Accepterer trafik ind til POP3

# Sætter State relateret politik op for INPUT
$IPTABLES -t filter -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT

# Tilsidst tilføjer vi vores kæder til INPUT
$IPTABLES -A INPUT -j intern
$IPTABLES -A INPUT -j extern

Det var egentligt det hele for opsætningen på en enkelt maskine - dog skal vi lige sikre os at den starter op med det script ved hver opstart. Dette gøres i /etc/conf.d/iptables:

# Configuration for iptables rules
IPTABLES=/usr/sbin/iptables

IPTABLES_CONF=/etc/iptables/test_firewall
IPTABLES_FORWARD=0 # disable IP forwarding!!!
Herefter skriver vi iptables ind i vores rc.conf således at vi er sikre på den starter fremover
DAEMONS=(... andre daemons ... iptables )

Nu kan vi så starte vores firewall og dermed skulle der ikke komme nogle fejl her:

$ /etc/rc.d/iptables start

Og således har vi nu en firewall kørende for vores enkelte maskine - man kan nu bagefter se vores "kørende regler" med kommandoen:

$ iptables -v -L

 

Opsætning af en firewall som router/gateway:

Det ovennævnte script er kun beregnet som firewall til en enkelt maskine, og vi har slet ikke været inde på vores NAT tabel og alle de andre ting man nu kan i IPTABLES. Det næste eksembel skal bruges til en Router, hvr vi har en webserver kørende på det interne net, som omverdenen skal have adgang til - samtidigt med vil vi gerne have andre maskiner på nettet samtidigt. Det skal hertil siges, at man dertil skal have en switch stående + en kørende DHCP-server hvis man ønsker DHCP adresser.

Til dette eksembel, tager vi følgende forudsætninger:
* Vores offentlige IP-adresse er 12.34.56.78 og vores WAN kommer ind på eth0
* Vores LAN netværk hedder 192.168.0.0/24 og sidder på eth1
* Vores webserver har følgende adresse: 192.168.0.10
* Vi ønsker åbent fra omverdenen til FTP - SSH - HTTP - POP3

Dette er lidt alá 1 script - dog kommer der lidt flere ting ind i perspektivet, men prøver at forklare det så godt som jeg kan. Vi starter med at lave et nyt script i /etc/iptables som vi kalder router_firewall:

# Vi starter med at oprette de variabler som vores firewall skal bruge
# Starter med IPadresserne og netkort + subnet
WAN="eth0"
LAN="eth1"
LO="lo"

WAN_IP="12.34.56.78"
LAN_IP="192.168.0.1"
LO_IP="127.0.0.1"

LAN_NET="192.168.0.0/24"
# Vores servers Adresse
SERVER="192.168.0.10"

# Vi skal have loaded enkelte moduler da vi ønsker at bruge FTP
modprobe ip_nat_ftp
modprobe ip_conntrack_ftp

# Accepterer forwardning
echo 1 > /proc/sys/net/ipv4/ip_forward

# Flusher og nulstiller vores kæder
$IPTABLES -F # Flusher alle kæder (Når der ikke er betegnelse på)
$IPTABLES -X # Nulstiller alle kæder (-----------| |--------------)

# Sætter vores default Policies
$IPTABLES -P INPUT DROP # Benægter alt input
$IPTABLES -P FORWARD DROP # Benægter al forwardning
$IPTABLES -P OUTPUT ACCEPT # Accepterer alt trafik UD

# Nu opretter vi vores kæder vi gerne vil bruge
$IPTABLES -N intern
$IPTABLES -N extern
$IPTABLES -N wantoserver

# Accepterer trafik indkommen til firewall
$IPTABLES -t filter -A INPUT -d ! WAN_IP -j ACCEPT

# Traffik fra LO interfaces
$IPTABLES -t filter -A INPUT -i $LO -j ACCEPT

# Herefter forwarder vi extern traffik videre til vores server - dette kan gøres som tidligere eller vi kan gøre dette via multiport som bare er flere # porte i en linie
$IPTABLES -t nat -A PREROUTING -d $WAN_IP -p tcp -m multiport --dports 21,22,80,110 -j DNAT --to-destination $SERVER
$IPTABLES -A wantoserver -d $SERVER -p tcp -m multiport --dports 21,22,80,110 -j ACCEPT
# Accepterer al returntraffik
$IPTABLES -A wantoserver -m state --state ESTABLISHED,RELATED -j ACCEPT

# Opsætning af MASQUERADE - dvs al trafik får vores offentlige IP som afsender - når det IKKE kommer fra WAN
$IPTABLES -A intern -i $LAN -j ACCEPT
$IPTABLES -t nat -A POSTROUTING -s ! $WAN_IP -o $WAN -j MASQUERADE

# Så tilføjer vi kæderne til de forindstillede kæder
$IPTABLES -A INPUT -j intern
$IPTABLES -A INPUT -j extern
$IPTABLES -A FORWARD -i $WAN -o $LAN -j wantoserver

Igen skal vi sikre os at det er det rigtige script der hentes - så tjek det lige i /etc/conf.d/iptables

# Configuration for iptables rules
IPTABLES=/usr/sbin/iptables

IPTABLES_CONF=/etc/iptables/test_firewall
IPTABLES_FORWARD=1 # enable IP forwarding!!!

Tilsidst sikrer os at det starter efter reboot mm - så ind i /etc/rc.conf

DAEMONS=(... andre daemons ... iptables )

Og derefter kan vi starte vores script

$ /etc/rc.d/iptables start

 


Specielle ting omkring IPTABLES:

Da der kan være flere ting der driller omkring det at tilgå egen servere internt - Specielt i forbindelse med DMZ - er der flere løsninger til dette problem.

* Natte interne kald direkte til serverens IP
* Opsætning af intern DNS - da dette giver den rigtige IP til det kald man laver

Dog vil jeg sige at den nemmeste måde at finde ud af dette er at google efter løsningen.
Netfilters egen dokumentation er et aldeles godt sted at starte hvis man leder efter den slags informationer

 

Kilder:

http://www.netfilter.org

Hvis der skulle være kommentarer eller spørgsmål til dette indlæg - så hold jer ikke tilbage for at skrive til udbytossen@gmail.com

Denne artikel er skrevet af Per Jørgensen - Peque


Alt indhold er skrevet af Per Jørgensen

Valid XHTML 1.0 Strict Valid CSS!
arch linux inkscape Linux kernel

Creative Commons License
Dette værk er licensieret under en
Creative Commons Navngivelse-Del på samme vilkår 2.5 Danmark Licens.