Iptables script

Deze handleiding helpt je een op iptables firewall script te maken dat automatisch gestart wordt bij het opstarten van de server en als service gestart en gestopt kan worden. Daarnaast omschrijft het een methode om een blacklist te bouwen met behulp van ipset.

Iptables installeren

Voor de juiste werking van dit script is het iptables en ipset pakket benodigd. Deze pakketten zijn op nagenoeg alle distributies standaard beschikbaar, waardoor je ze gemakkelijk kunt installeren via de standaard package manager:

apt-get install iptables ipset

Voor oudere distributies van debian kan het zijn dat niet alle benodigde modules voor het generen van een iphash (zie uitleg blacklist met ipset) beschikbaar zijn, via de module-assitent (m-a) kan deze alsnog geïnstalleerd worden:

apt-get install xtables-addons-common xtables-addons-source
m-a prepare
m-a build xtables-addons
m-a install xtables-addons

Vanaf nu zijn de iptables en ipset commando's beschikbaar.

Iptables flushen

Wanneer het script start of stopt worden de bestaande regels verwijderd uit de iptables. Op die manier wordt alle verkeer naar jouw server weer geaccepteerd. Het flushen kan op de volgende manier:

iptables -F INPUT
iptables -F FORWARD
iptables -F OUTPUT

Iptables policies

Policies bepalen de standaard actie voor elk type verkeer. Als er geen regels en geen policies zijn ingesteld wordt alle verkeer geaccepteerd. Door onderstaande regels worden bestemmingsverkeer en verkeer dat doorgestuurd word geweigerd en uitgaand verkeer toegestaan. 

iptables -P INPUT DROP
iptables -P FORWARD DROP
iptables -P OUTPUT ACCEPT

 Uiteraard dien je zelf te bepalen welke policies voor jou werken. Wanneer je bovenstaande regels hanteert, dien je bij het stoppen van de firewall alle policies op ACCEPT in te stellen. 

Let op!

Wanneer je de policies hebt ingesteld zijn deze direct van kracht op alle nieuwe verbindingen. Als je ingelogd bent via SSH zul je huidige verbinding dus niet verbroken worden, maar nieuwe verbindingen zullen met bovenstaande regels worden geweigerd. Zorg er daarom voor dat je altijd een andere methode hebt om als nog in te loggen zodat je jezelf nooit buiten kunt sluiten.

Specifieke poorten openen

Er kan op poort niveau of met een range van poorten worden ingesteld welke poorten verbindingen mogen accepteren. Hierbij kan het protocol (tcp of udp) specifiek gedefinieerd worden:

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

Bovenstaande regels accepteren inkomend en uitgaand verkeer via tcp-poort 80, waardoor je http connecties kunt toestaan. Uiteraard kun je de poortnummers zelf aanpassen.

Onderstaand een extra voorbeeld dat gebruik maakt van een poort-range zodat passieve FTP-connecties naar jouw server geaccepteerd kunnen worden (uiteraard dient de range overeen te komen met de instellingen van de ftp service):

iptables -A INPUT -p tcp --dport 21 -j ACCEPT
iptables -A INPUT -p tcp --dport 20 -j ACCEPT
iptables -A INPUT -p tcp --dport 24000:24049 -j ACCEPT

Specifieke hosts toestaan

Wanneer je verkeer van slechts een of een paar bronnen op een bepaalde poort wilt toestaan kun je de bron definiëren met de -s-parameter (staat voor source):

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

Bovenstaand voorbeeld staat alleen ssh toe vanaf een specifiek IP-adres (absoluut aan te raden!) 

Blacklist

Blacklist met iptables

Wanneer je slechts een specifieke set aan IP-adressen wilt blokkeren is het afdoende om de deze adressen met losse regels te blokkeren, bijvoorbeeld:

iptables -A INPUT -s TE_BLOKKEREN_IP -j REJECT --reject-with tcp-reset

Hiermee voeg je een regel toe aan de iptables waarbij je alle verkeer vanaf een bepaald IP-adres weigert en de connectie "reset", waardoor de afzender een hele nieuwe connectie moet opzetten naar de firewall en niet gebruik kan maken van bijvoorbeeld keepalive-mechanismen om snel achter elkaar verbindingen te maken  je kunt dit zien als een brute-force beveiliging.

Blacklist met ipset

Ondanks dat bovenstaande oplossing goed zal werken, wordt de firewall trager naarmate je meer regels toevoegt. Wanneer je een openbare blacklist inlaadt waar een paar duizend ip's mee worden geblokkeerd moet elk verzoek worden gecontroleerd a.d.h.v. deze lijst. Om dit proces sterk te versnellen kan er een ipset gegenereerd zodat iptables op een zeer snelle methode door deze IP-adressen scant.

Het genereren van zo'n ipset functioneert in de basis als volgt:

ipset --quiet --create blacklist iphash
ipset --flush blacklist
ipset --add blacklist TE_BLOKKEREN_IP

Bovenstaande regels creëren achtereenvolgens een nieuwe ipset met de naam "blacklist" en het iphash algoritme, speciaal ontwikkeld voor grote aantallen IP-adressen. Daarna wordt de set geleegd, in het geval de ipset al bestond en de laatste regel voegt een IP-adres toe aan de set. Voor elk extra ip kan de regel beginnend met ipset --add worden herhaald.

Blacklist uit bronbestand

Wanneer je een blacklist afkomstig van een externe bron gebruikt, kun je deze blacklist bij het starten van de firewall inladen in de ipset. Als we er bijvoorbeeld vanuit gaan dat in het bestand /etc/hosts.evil op elke regel een IP-adres staat kunnen we met dit bestand de ipset als volgt opbouwen:

ipset --quiet --create blacklist iphash
ipset --flush blacklist

while read IP
do
ipset --add blacklist $IP
done < /etc/hosts.evil

Bovenstaand voorbeeld is vergelijkbaar met vorige voorbeeld, uitgezonderd dat de derde regel van vorige voorbeeld voor elk IP-adres in het bronbestand wordt aangeroepen.

Blacklist koppelen aan iptables

Wanneer de ipset is opgebouwd dient deze gekoppeld te worden aan een iptable-regel, zodat er ook daadwerkelijk een actie wordt ondernomen op basis van een match met de ipset. In onderstaand voorbeeld wordt de verbinding geweigerd, maar je zou dit dus ook kunnen gebruiken om een whitelist op te stellen, door het REJECT-deel te vervangen door ACCEPT.

iptables -A INPUT -p tcp -m set --match-set blacklist src -j REJECT --reject-with tcp-reset
iptables -A INPUT -m set --match-set blacklist src -j REJECT
iptables -A FORWARD -p tcp -m set --match-set blacklist src -j REJECT --reject-with tcp-reset
iptables -A FORWARD -m set --match-set blacklist src -j REJECT

Bovenstaande regels een twee regels voor de INPUT-regelset (pakketten die voor de betreffende server bedoeld zijn) en twee voor de FORWARD-regelset (pakketten via de server worden doorgezet), waarin de eerste en derde regel specifiek voor tcp-connecties waar een tcp-reset op kan worden uitgevoerd en de tweede en vierde regel voor overige (udp) connecties waar geen tcp-reset op van kracht is.

Firewall script als service

Bovenstaande kennis kan samengevoegd tot een script dat kan worden geïnstalleerd als service in elke Linux distributie. Om het script te installeren dien je het script in de /etc/init.d/ map te plaatsen.

firewall script downloaden

Dit bestand dient vervolgens de juiste rechten te krijgen en geregistreerd te worden in het systeem als service:

chmod 755 /etc/init.d/firewall
chown root:root /etc/init.d/firewall

update-rc.d firewall defaults
update-rc.d firewall enable

Eventueel kun je in de laatse regel enable vervangen voor disable om de service tijdelijk te deactiveren.

Wanneer je een aanpassing maakt in het script dien je deze aanpassing tevens te registeren:

systemctl daemon-reload

Conclusie

Het is relatief simpel om een goed werkende firewall te realiseren door gebruik te maken van bovenstaand script. Je zult zien dat het script is aangevuld met extra regels om traceroute en ping toe te staan, maar deze kun je optioneel zelf uit het script verwijderen.

De grootste tekortkoming van het script in haar huidige vorm is dat deze geen ondersteuning heeft voor ip6. Echter zijn er genoeg andere leveranciers die vergelijkbare scripts hebben ontwikkeld waar wel een ondersteuning voor ipv6 in is verwerkt.

Als laatste kan het lastig zijn om een goede lijst van kwaadwillende ip's te onderhouden, wanneer deze lijst niet bijgewerkt is worden bijvoorbeeld "nieuwe" spammers niet geblokkeerd door de firewall waardoor ze alsnog schade aan zouden kunnen richten.

Altijd up-to-date hosts.evil bestand?

Via de gratis Restfull API kan een blacklist bestand gedownload worden dat altijd up to date is! De documentatie geeft code-voorbeelden die je direct kunt implementeren in bovenstaand Firewall script. Je krijgt toegang tot de RestFull api als je een domein bij ons registreerd, als je gebruik maakt van de e-mailhosting of back-up diensten.

Meer informatie »