Debian server beheer

Firewall (iptables) instellen

Let op: als je de server op afstand beheert en je maakt een fout bij het instellen van je firewall loop je het risico dat je niet meer in kunt loggen. Voorzichtig dus.

Het eerste dat je op je nieuwe server moet doen is de firewall instellen. Uitgangspunt is dat je alle verkeer weigert tenzij je zeker weet dat je het nodig hebt. Wil je bijvoorbeeld een webserver draaien dan moet poort 80 open staan. Draai je geen webserver, laat poort 80 dan dicht. Hoe minder poorten er open staan, hoe veiliger je systeem is.

Tables en policies

iptables verdeelt zijn regels in drie tabellen. INPUT voor inkomend verkeer, FORWARD voor verkeer dat doorgestuurd moet naar een ander ip-adres en OUTPUT voor uitgaand verkeer. Per tabel kun je ook een 'policy' instellen. De policy geldt voor verkeer waar geen andere regels ingesteld worden. Om te beginnen gaan we instellen dat FORWARD altijd geweigerd wordt en OUTPUT altijd doorgelaten:

iptables -P FORWARD DROP iptables -P OUTPUT ACCEPT

Inkomend verkeer

Met INPUT moet je even wat voorzichter omgaan, vooral als je de server op afstand beheert. Helemaal aan het eind gaan we bij INPUT ook de 'policy' DROP instellen maar pas nadat we alles open gezet hebben wat open moet staan. Om te voorkomen dat je per ongeluk jezelf buitensluit stel je eerst de regel in waardoor bestaande verbindingen open blijven:

iptables -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT

"-A INPUT" betekent toevoegen aan de tabel INPUT. "-m state" betekent dat we gaan vergelijken (matchen) op de status van de verbinding. "--state RELATED,ESTABLISHED" betekent dat we zoeken naar bestaande verbindingen. Tenslotte, "-j ACCEPT" betekent dat deze verbindingen geaccepteerd worden. Deze regel is nodig om er voor te zorgen dat uitgaande verbindingen vanaf je server (bijvoorbeeld een DNS lookup) beantwoordt kunnen worden.

Nu gaan we instellen dat ook alle verbindingen vanaf de computer zelf (localhost) geaccepteerd worden:

iptables -A INPUT -i lo -j ACCEPT

Hier zie je eerst het bekende "-A INPUT" en dan "-i lo". Dat verwijst naar de netwerkinterface localhost. Dan volgt weer "-j ACCEPT".

Vervolgens zetten we poort 22, dat is de poort die nodig is voor ssh toegang. Ik heb zelf de gewoonte om die alleen voor mijn eigen ip-adressen open te zetten. Stel dat mijn ip-adres 10.11.12.13 is, dan is de vereiste opdracht aan iptables:

iptables -A INPUT -p tcp --dport 22 -s 10.11.12.13 -j ACCEPT

Nieuw hier is "-p tcp --dport 22" wat betekent dat iptables deze regel toepast op tcp poort 22. En verder zie je "-s 10.11.12.13" wat aan iptables vertelt dat deze regel alleen geldt voor verkeer van ip-adres 10.11.12.13.

Er zit een evident nadeel aan het op deze manier beveiligen van toegang tot poort 22. Als je ergens op vakantie bent kun je niet zomaar verbinding met je server maken. Ik heb dat opgelost door de ip-adressen van mijn huis en kantoor in iptables te zetten. Als ik vanaf een andere locatie verbinding met de server wil maken, maak ik eerst een VPN verbinding naar huis of kantoor en open dan een terminalsessie naar de server. Het is ook aan te raden toegang van meer dan één ip-adres toe te laten. Je weet nooit of je ip-adres een keer wijzigt.

Nu gaan we voor een aantal poorten verkeer van iedereen accepteren. Bijvoorbeeld, als je een webserver draait wil je poort 80 open hebben voor iedereen:

iptables -A INPUT -p tcp --dport 80 -j ACCEPT

Na de voorgaande voorbeelden kun je deze regel lezen. We voegen aan de tabel INPUT toe dat verkeer op poort 80 altijd toegelaten wordt. Welke poorten je open wilt zetten hangt af van wat je doet met je server. Voor inkomende mail heb je poort 25 nodig. Als je mail op wilt halen wil je poorten 443, 465, 587 en 993 open hebben. Op het internet vind je allerlei overzichten van TCP poortnummers. Herhaal de bovenstaande opdracht met alle poorten die jij open moet hebben.

Ik heb er voor gekozen om op mijn server ping alleen toe te staan vanaf bepaalde door mij ingestelde ip-adressen. Dat doe je met de volgende opdracht:

iptables -A INPUT -p icmp -s 10.11.12.13 -j ACCEPT

In ieder geval bechermt je dat tegen 'ping floods'. Als allerlaatste stap stellen we in dat alle overige inkomend verkeer geweigerd wordt:

iptables -P INPUT DROP

Regels opslaan en inladen

Je kunt de ingestelde regels opslaan met twee opdrachten:

mkdir /etc/iptables/ iptables-save > /etc/iptables/myrules

Tenslotte moet je nog instellen dat iptables na een herstart van je systeem de regels ook weer inlaadt. Daarvoor moeten we een klein shell script maken. Start nano met de opdracht:

nano /etc/network/if-up.d/iptables

Voer vervolgens deze regels in:

#!/bin/sh iptables-restore < /etc/iptables/myrules

Sla op met control+o en sluit nano af met control+x. Maak het script nu uitvoerbaar met:

chmod +x /etc/network/if-up.d/iptables

Uiteraard mogen je regels een andere naam hebben dan myrules en mag je ze op een andere plek opslaan dan /etc/iptables.

En dan testen...

Het is belangrijk nu te testen of de regels goed ingesteld zijn en op ze bij herstart van het systeem goed laden. Herstart je server met:

shutdown -r now

Als je de server op afstand beheert zal je ssh verbinding nu afgesloten worden. Tel tot tien en maak een nieuwe ssh verbinding. Vervolgens kijk je wat er nu ingesteld is in de firewall:

iptables -L

Als het goed is zie nu de door jou ingestelde regels. Dat zou er ongeveer zo uit kunnen zien:

Chain INPUT (policy DROP) target prot opt source destination ACCEPT all -- anywhere anywhere state RELATED,ESTABLISHED ACCEPT all -- anywhere anywhere ACCEPT tcp -- 10.11.12.13 anywhere tcp dpt:ssh ACCEPT tcp -- 10.11.12.14 anywhere tcp dpt:ssh ACCEPT tcp -- anywhere anywhere tcp dpt:smtp ACCEPT tcp -- anywhere anywhere tcp dpt:www ACCEPT tcp -- anywhere anywhere tcp dpt:https ACCEPT tcp -- anywhere anywhere tcp dpt:ssmtp ACCEPT tcp -- anywhere anywhere tcp dpt:submission ACCEPT tcp -- anywhere anywhere tcp dpt:imaps ACCEPT icmp -- 10.11.12.13 anywhere ACCEPT icmp -- 10.11.12.14 anywhere Chain FORWARD (policy DROP) target prot opt source destination Chain OUTPUT (policy ACCEPT) target prot opt source destination

De firewal werkt en na een herstart worden de regels goed ingeladen. Als je de regels wilt zien met nummers van de poorten in plaats van namen zoals smtp doe je:

iptables -L -n

Regel op bepaalde plek invoeren

Met bovenstaande commandos voer je een nieuwe regel steeds aan het eind van het bestand in. Je kunt regels ook op een bepaalde plek invoeren met de -I modifier:

iptables -I INPUT 9 -p tcp --dport 8080 -j ACCEPT

Dit betekent dat de regel over poort 8080 op de negende regel ingevoegd wordt.

Regels (tijdelijk) wissen

Om tijdelijk regels te wissen kun je huidige regels met regelnummers tonen:

iptables -L INPUT -n --line-numbers

11 ACCEPT tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:25 12 ACCEPT tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:80 13 ACCEPT tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:443 14 ACCEPT tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:465

Je kunt nu de regel met een bepaald nummer, 12 in dit voorbeeld, wissen door:

iptables -D INPUT 12

Dit kan handig zijn, bijvoorbeeld om toegang tot bepaalde poorten te testen. Je kunt atijd weer terug naar je originele set regels met:

iptables-restore < /etc/iptables/myrules

Eén IP-adres blokkeren

Als je in je logfiles merkt dat je vanaf een bepaald ip-adres lastig gevallen wordt kun je via iptables één ip-adres blokkeren. Bijvoorbeeld, om ip-adres 6.7.8.9 te blokkeren:

iptables -I INPUT -s 6.7.8.9 -j DROP

We gebruiken hier de -I optie om de regel aan het begin van de chain input toe te voegen. Als je er I INPUT 6 van zou maken wordt deze regel als 6e in de tabel INPUT toegevoegd. Zonder getal wordt de nieuwe regel bovenaan ingevoegd. Iptables loopt de regels namelijk op volgorde af en stopt bij de eerste regel die van toepassing is. Je moet het ip-adres dus blokkeren vóór je met andere regels toegang geeft tot, bijvoorbeeld, poort 25.

Let op dat je de regels nu opnieuw op moet slaan, anders is de blokkade verdwenen na een herstart. Overigens kies ik er juist voor om dit soort blokkades niet op te slaan. In de meeste gevallen worden ip-adressen tijdelijk misbruikt en is het dus prima dat ze bij een volgende herstart vrijgegeven worden.

Een reeks ip-adressen blokkeren

Soms wil je een hele reeks ip-adressen blokkeren. Ik blokkeer bijvoorbeeld al het verkeer een zekere Taiwanese provider, waar driekwart van de pogingen om mijn server te hacken vandaan komt. Of beter gezegd kwam:

iptables -I INPUT -s 114.37.0.69/16 -j DROP

Dit blokkeert de ip-addressen 114.37.0.0 tot en met 114.37.255.255. De /16 betekent dat alleen de eerste twee delen van het ip-adres gematcht worden. Die reeksen werken alsvolgt

114.37.0.69/32==114.37.0.69
114.37.0.69/24==114.37.0.*
114.37.0.69/16==114.37.*
114.37.0.69/8==114.*

De /32 optie heeft niet zoveel zin maar werkt wel.

Er is nog een manier om (grotere) reeksen ip-adressen te blokkeren:

iptables -I INPUT -m iprange --src-range 1.160.0.0-1.175.255.255 -j DROP

Hiermee blokkeer je alle ip-adressen die beginnen met 1.160 tot en met 1.175.