Alleen Nederlandse ip-adressen voor SSH
Van de week zat ik met collega Bart in de auto en hadden we het kort over één van mijn hobby’s: servertje spelen. In een poging alle services op te sommen, bleven we even steken bij de firewall/router functionaliteit. Hiervoor maak ik gebruik van netfilter die ik configureer middels iptables. Hoe we er precies op kwamen weet ik niet meer, maar Bart vroeg of ik veel SSH break-in attempts te verwerken had, én of ik in de firewall nog bijzondere maatregelen had genomen dit te beperken.
Als voorbeeld van een maatregel noemde Bart het blokkeren van SSH verkeer voor niet-Nederlandse ip-adressen. Het eerste wat ik dacht: waarom heb ik dat zelf nooit bedacht? Als ik al eens in het buitenland ben, is de kans echt ontzettend klein dat ik via SSH wil inloggen op mijn server. Het blokkeren van alle niet-Nederlandse ip-adressen voor SSH-verkeer klonk me dan ook goed in de oren.
Gisteravond besloot ik de zaak eens nader te onderzoeken. In mijn auth.log zag ik voor wat betreft SSHD behoorlijk wat authentication failures voorbij komen. In 4 dagen tijd zo’n 2200 (!) attempts, waarvan een groot deel inderdaad afkomstig uit het buitenland. Voor mij voldoende reden voor het nemen van een maatregel.
Na 5 minuten googelen kwam ik terecht op http://www.ipdeny.com/. Op deze website worden per land de beschikbare ip-adressen bijgehouden. Helaas was de online tool om op basis van deze lijsten een iptables-script te genereren niet beschikbaar. Dan maar even zelf een scriptje schrijven:
#!/usr/bin/perl
print “Generating IPTABLES script\n”;
print `wget http://www.ipdeny.com/ipblocks/data/countries/nl.zone`;
open (FILE, “>iptables-script”) || die “kan bestand niet maken”;
open (ZONEFILE, “nl.zone”) || die “kan bestand niet lezen”;
while ($regel = <ZONEFILE>)
{
chomp($regel);
print FILE ” \$IPTABLES -A ssh_accept -p TCP -s $regel –dport 22 -j ACCEPT\n”;
}
close(FILE);
close(ZONEFILE);
Bovenstaand Perl scriptje zorgt ervoor dat de zonefile met alle ip-adressen van Nederland wordt gedownload. Vervolgens wordt dit bestand (nl.zone) gelezen en wordt er een nieuw bestand (iptables-script) aangemaakt waar de ip-adressen in een kant-en-klaar iptables script worden gegoten. Een voorbeeld:
199.7.70.0/24 wordt $IPTABLES -A ssh_accept -p TCP -s 199.7.70.0/24 –dport 22 -j ACCEPT
en dan kan de inhoud van iptables-script worden toegevoegd aan het firewall script. Vergeet dan niet aan het einde de “deny-by-default” regel toe te voegen:
$IPTABLES -A ssh_accept -p TCP -s 0/0 –dport 22 -j DROP
Zonder deze laatste regel worden alsnog de ip’s van andere landen toegelaten, dus deze is erg belangrijk. Merk op dat het Perl scriptje en de syntax van het iptables script specifiek zijn voor mijn server. Verder ben ik erg benieuwd in hoeverre ik hiermee het aantal authentication failures in mijn log ga reduceren.
Prima verhaal, alleen lijkt de nl.zone lijst niet compleet aangezien bijvoorbeeld Wageningen UR ontbreekt (137.224/16) en nog meer onderwijsinstellingen, dus ik zou er niet helemaal blind op varen ;-)
Het is inderdaad geen lijst om helemaal blind op te varen, maar vooralsnog kan ik vanaf al mijn “favoriete locaties” inloggen. Wellicht dat de lijst in de toekomst vollediger wordt of dat ik een andere lijst tegenkom.
Het werkt in ieder geval goed. Het aantal authentication failures per dag is nu op twee handen te tellen, en ik heb zelfs dagen dat er niks voorbij komt.
Dag Dennis,
ik heb belang bij dit script, ik wil alleen bezoekers uit NL op mijn site hebben.
Zou je mij willen uitleggen hoe ik dit script moet installeren op mijn website ?
MvG
Roel
Hoi Roel,
Mijn oplossing is gebaseerd op de firewall in de linux kernel. Met andere woorden: als je de hierboven beschreven filtering wil toepassen op jouw website, dan zul je hiervoor de firewall moeten aanpassen. Hiervoor heb je root rechten nodig op de server.
Daarnaast moet je je realiseren dat de bovenstaande oplossing prima werkt voor HTTP verkeer, maar dat dit van toepassing is op alle websites die er op die server gehost worden.
Wellicht dat je met behulp van PHP of een andere scripttaal een script kan maken wat bezoekers van niet Nederlandse IP-adressen weigert.
Als je van script kiddies af wilt zijn kun je SSH bij de port forwarding in je router een obsure poort toewijzen. Dus forwarden van 50000 > 22 bijvoorbeeld. als dat niet lukt je SSH server op 50000 istellen en dan forwarden van 50000 > 50000. Ik doe dit zelf ook en het is nu afgelopen met auth failures.