Maak een fort van je webserver – Bescherm jezelf tegen hackers en scriptkiddies

About

Maak een fort van je webserver – Bescherm jezelf tegen hackers en scriptkiddies

Als je een webserver beheert die onderdeel is van het internet weet je één ding zeker: je wordt aangevallen. Vierentwintig uur per dag, zeven dag in de week proberen hackers en scriptkiddies op de meest creatieve manieren je server binnen te dringen. Hoe bescherm je jezelf daartegen? In deze workshop leggen we stap voor stap uit hoe je een groot deel van de bedreigingen het hoofd kunt bieden.

Martijn de Meulder

Een van de wonderen van het moderne internet is de beschikbaarheid van serverinfrastructuur. Betaalde je jezelf vroeger blauw aan een gedeeld hostingaccountje met een hele batterij beperkingen, tegenwoordig kun je bij de grotere hostingproviders al voor 15 euro in de maand een virtual private server (VPS) huren. Met vier processorcores en acht gigabyte geheugen bieden deze genoeg kracht om enorme hoeveelheid webservers en databaseapplicaties op te draaien. Als je weet hoe je ermee om kunt gaan zijn de mogelijkheden eindeloos. Maar zoals zijn oom Ben als in de eerste Spidermanfilm al aan Peter Parker vertelt: ‘met grote kracht komt ook grote verantwoordelijkheid’. Dat geldt ook voor jou als je zo’n server huurt. Want zo’n krachtige server kun je ook geweldig inzetten voor doelen die jij vermoedelijk helemaal niet voor ogen hebt, zoals voor het versturen van miljarden spamberichten, het hosten van dubieuze content of het aanvallen van andere servers op het internet. Criminelen, hackers en scriptkiddies zijn dag en nacht op zoek naar slecht beveiligde machines. Ook bij jouw VPS komen ze aankloppen, kijk je toegangslogs er maar eens op na. Je krijgt er koude rillingen van als je ziet hoe vaak allerlei volk uit de hele wereld langskomt. Meestal zijn het portscans of andere eenvoudige methodes om een indruk te krijgen van hoe je server eruit ziet, vergelijkbaar met het rammelen aan de deur om te voelen of het slot het er goed op zit. Maar ze zijn er wel en als jij even verslapt zullen ze binnendringen en toeslaan.

Zo’n krachtige server is ook geschikt voor doelen die jij helemaal niet voor ogen hebt


Zero-day-exploits

Om dat te voorkomen, is het zinvol je te verdiepen in het beveiligen van je machine. We benadrukken dat een waterdichte methode niet bestaat. Altijd kan er ergens diep in je software een zero-day-exploit zitten (een nog ongepubliceerde kwetsbaarheid) die alleen door de makers van de software kan worden gepatcht. Maar met de maatregelen in deze workshop kun je je server in ieder geval tot een moeilijk te nemen vesting maken en zo de meeste aanvallers buiten de deur houden.

In deze workshop richten we ons op het beveiligen van een Linux-webserver met een zogenoemde LAMP-configuratie: met Linux, Apache, MySQL en PHP – de meestgebruikte webservercombinatie ter wereld. Wij gebruiken CentOS als besturingssysteem, maar de kennis kun je ook toepassen op bijvoorbeeld Ubuntu of een van de andere Linux-varianten. Het belangrijkste verschil voor de interpretatie van deze workshop is vooral de gebruikte packagemanager, het systeem voor softwarepakketbeheer. Op CentOS is dat yum, terwijl Ubuntu – gebaseerd op Debian – apt-get gebruikt. Ook kan een enkel configuratiebestand op een andere plek staan, maar als je zoekt op internet op de naam van het bestand in combinatie met je besturingssysteem zul je snel de locatie weten. De configuratiebestanden zelf zullen in alle gevallen precies hetzelfde zijn.

Ook gaan we ervan uit dat je de webserver met bovenstaande software al draaiende hebt. We gebruiken de editor nano in de voorbeelden, heb je deze nog niet geïnstalleerd dan kun je dat doen met het commando yum install nano. Of als je Ubuntu/Debian gebruikt: sudo apt-get install nano. Wanneer je fan van vi of vim bent, kun je natuurlijk ook deze editors gebruiken.


Houd je server actueel

Zorg ervoor dat de software op je server altijd up-to-date is om oude lekken geen kans te geven. Gebruik het commando sudo yum check-update om te zien of er updates voor je systeem zijn. Zit er wat voor je bij? Tik dan yum update in waarna de pakketten worden bijgewerkt.

Deze manier van updaten is in de praktijk natuurlijk vrij lastig omdat je zelf alles moet doen. Je kunt het pakketbeheer ook automatiseren met yum-cron. Om deze service te installeren en activeren, gebruik je het volgende commando:

sudo yum install yum-cron

Kijk het configuratiebestand na en pas deze eventueel aan je wensen aan met:

sudo nano /etc/yum/yum-cron.conf

Bij alle opties zul je voldoende uitleg vinden om er de juiste beslissingen bij te maken. Let wel op de optie apply_updates, deze staat standaard op no. Maar om automatische updates uit te laten voeren – en dat wil je – moet je deze veranderen in yes.

Start nu de service en kijk de status na met deze commando’s:

sudo systemctl enable yum-cron.service
sudo systemctl start yum-cron.service
sudo systemctl status yum-cron.service

Om nu deze service altijd te laten starten, gebruik je de volgende twee commando’s:

sudo chkconfig yum-cron on

sudo service yum-cron start
Succes! Yum-cron draait en zorgt ervoor dat je server automatisch up-to-date blijft.

 

Ubuntu en Debian

Ook op Ubuntu is er een dergelijke service, ‘unattended upgrades’ genoemd. Deze kun je op een vergelijkbare manier configureren en installeren. Installeer de service met:

apt-get install unattended-upgrades

En bewerk daarna het configuratiebestand met:

sudo nano /etc/apt/apt.conf.d/50unattended-upgrades

Haal hier de beide slashes weg voor de regel met het woord updates en open het volgende bestand:

sudo nano /etc/apt/apt.conf.d/20auto-upgrades

Plaats daar de volgende regels in om iedere twee dagen te controleren op updates:

APT::Periodic::Update-Package-Lists "1";
APT::Periodic::Download-Upgradeable-Packages "1";
APT::Periodic::AutocleanInterval "2";
APT::Periodic::Unattended-Upgrade "1";

Test ten slotte of het werkt:

sudo unattended-upgrades --dry-run –debug

Alles in orde? Gefeliciteerd, je server houdt zichzelf nu bij de tijd.


Beveilig ssh

Ssh (Secure shell) is een onmisbaar gereedschap voor het onderhoud van je server, het zorgt ervoor dat je door een versleuteld kanaal verbinding maakt met je machine en de opdrachtregel kunt gebruiken. Ssh werkt in een standaardinstallatie echter met een gebruikersnaam en een wachtwoord, en dat is een gapend gat in de beveiliging. Wachtwoorden kunnen worden geraden met zogenoemde brute-force-aanvallen. Het beste kun je de toegang tot je server met inlognaam en wachtwoord helemaal verwijderen. Ssh biedt daarvoor ondersteuning, je kunt met een sleutelpaar toegang krijgen: de publieke sleutel staat op je server, de private sleutel staat op de machine waarmee je toegang wilt hebben tot de server. Heeft iemand deze sleutel niet (iedereen buiten jezelf), dan wordt deze meteen geweigerd door de server.

Installeren doe je als volgt. Als eerste moet je de sleutels genereren. Download daarvoor het programma PuTTYgen vanaf www.puttygen.com. Start PuTTYgen na installatie en druk op de knop Generate. Na het genereren zie je de publieke sleutel in het venster verschijnen, kopieer deze naar het klembord. Geef in dit venster ook het wachtwoord op, en bewaar de publieke en private sleutel in een bestand door op de daarvoor aangegeven knoppen te drukken.

Met PuTTYgen kun je het sleutelpaar genereren waarmee je ssh beveiligt.

Ssh werkt standaard met een inlognaam en een wachtwoord: een gapend beveiligingsgat


Laatste keer met wachtwoord

Nu je dat hebt gedaan, kun je inloggen op je server (met ssh natuurlijk, maar voor de laatste keer nog met inlognaam en wachtwoord). Kopieer nu de publieke sleutel uit het PuTTYgen-venster en open het bestand ~/.ssh/authorized_keys met het commando:

sudo nano ~/.ssh/authorized_keys

Plak daarin de publieke sleutel die je zojuist hebt gekopieerd. Bestaat de directory .ssh in je home-directory nog niet – dat kan goed als je een nieuwe server configureert – maak deze dan eerst aan met mkdir .ssh. Zet daarna de permissies in een veilige stand met:

sudo chmod 700 ~/.ssh
sudo chmod 600 ~/.ssh/authorized_keys
restorecon -Rv ~/.ssh

Als je met een Linux-client werkt (zoals het hoort!) of met macOS, dan heb je PuTTYgen en bovenstaande instructie niet nodig, je kunt je sleutelpaar genereren én meteen naar ~/.ssh kopiëren met de volgende serie commando’s (aangenomen naar je Homebrew hebt geïnstalleerd op je systeem):

sudo brew install ssh-copy-id
ssh-keygen -t rsa
ssh-copy-id -i [hier het pad naar de zojuist aangemaakte sleutel] inlognaam@serveradres

Vervang de aanduiding [hier het pad naar de zojuist aangemaakte sleutel] door het volledige pad inclusief bestandsnaam.


Testen

Je kunt nu de installatie testen door je ssh-client opnieuw te configureren, hoe je dat doet hangt natuurlijk af van de software die je gebruikt. Wij gebruiken zelf Termius (www.termius.com). Druk daar op de configuratie van je server en scrol naar onderen. Verwijder het wachtwoord, maar laat je gebruikersnaam staan. Druk op Key en in het venster dat volgt op de groene knop + key. In het venster dat je ziet, kun je de inhoud van het bestand met de private sleutel kopiëren dat je zojuist met PuTTYgen hebt opgeslagen. Geef daar ook het wachtwoord op dat je hebt ingegeven in PuTTYgen en sla de gegevens op. Nu kun je verbinding maken met de server. Lukt dat? Gefeliciteerd, je kunt nu overgaan op de laatste stap: het verbieden van toegang met inlognaam en wachtwoord.

De configuratie van Termius: geef hier de private sleutel op die je zojuist hebt gegenereerd.


Alleen nog met sleutels

Het verbieden van het gebruik van wachtwoorden doe je door op je server het sshd-configuratiebestand te bewerken met het commando:

sudo nano /etc/ssh/sshd_config

Zoek naar de regel PasswordAuthentication en veranderd yes in no. Sluit nano af en herstart de ssh-service met:

sudo systemctl restart sshd

Wel even testen natuurlijk vanaf je lokale computer of je echt niet meer kunt aanmelden met inlognaam en wachtwoord. Als dat mislukt heb je een enorme stap voorwaarts gedaan in het beveiligen van je server.


Actieve bewaking met Fail2ban

Je hoeft niet ál het beveiligingswerk zelf te doen, je kunt met Fail2ban ook een automatische bewakingsrobot op je server installeren. Fail2ban scant de logbestanden van de serversoftware die je hebt draaien, zoals ssh, Apache en ftp, op zoek naar kwaadaardige activiteit zoals inlogpogingen en zoektochten naar bekende zwakheden. Ontdekt het een poging tot inbraak, dan past Fail2ban zelf de regels van je firewall aan om de ip-adressen die verantwoordelijk zijn voor het ongewenste gedrag alle toegang tot je systeem te ontzeggen. In Fail2ban-terminologie: het ip-adres wordt in de ‘jail’ geplaatst.

Fail2ban zit niet in de standaard CentOS-distributie, maar in de Extra Packages for Enterprise Linux (EPEL) van Red Hat. Installeer de package met de commando’s:

sudo yum install epel-release

sudo yum install fail2ban

Voor Ubuntu hoef je EPEL niet te installeren, dit commando is genoeg:

sudo apt-get install fail2ban

Kopieer dan het standaard configuratiebestand en open het in nano:

sudo cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local
sudo nano /etc/fail2ban/jail.local


Jails

Lees in dit bestand rustig de opties door die op jouw machine van toepassing zijn, vooral ook de instellingen onder het kopje JAILS, waar de gevangenissen voor aanvallers van de verschillende diensten op je server worden ingesteld. De meeste opties hoef je niet te wijzigen, let echter op de optie enabled = true in de ssh-jail-sectie, die staat nog niet aan. Haal het hekje (#) voor deze regel weg.

Ben je tevreden met de instellingen? Sluit dan de editor af, voeg Fail2ban toe aan de standaard op te starten diensten van je server en start de service met:

sudo systemctl enable fail2ban

sudo systemctl start fail2ban

Wil je weten of Fail2ban draait? Dan kun je de status ervan controleren met:

sudo fail2ban-client status

Zien welke inbrekers een mislukte poging op je ssh-dienst hebben gedaan? Gebruik dan de opdracht:

sudo fail2ban-client status sshd

Welke ip-adressen zijn verbannen? Al is dat meestal pas na een paar uur of een paar dagen zinvol:

sudo zgrep 'Ban' /var/log/fail2ban.log*

Wil je een live log zien van malicieuze pogingen?

sudo tail -F /var/log/fail2ban.log
De inhoud van onze ssh-jail op een server die al een paar jaar draait.

 

Een paar dagen Fail2ban levert deze indrukwekkende lijst met dubieus volk op.

Met Fail2ban kun je een automatische bewakingsrobot op je server installeren


Ftp-toegang beveiligen

Als je een webserver draait, is de kans dat je ook een ftp-server hebt natuurlijk bijzonder groot. Ftp is een geweldig protocol dat ook heel makkelijk werkt. Het grote nadeel ervan is dat bestanden, wachtwoorden en inlognamen bij een standaardinstallatie onversleuteld worden verstuurd. Dat is niet verstandig, het maakt je kwetsbaar voor allerlei ‘man-in-the-middle’-aanvallen. Niet alleen op internet, maar bijvoorbeeld ook bij het gebruiken van een openbare hotspot (zonder vpn). Daarom gaan we de bestandsoverdracht beveiligen met een sleutel. We richten ons Vsftpd, op dit moment de meest gebruikte Linux-ftp-server en we gaan ervan uit dat je deze inmiddels draaiende hebt.

Het idee is dat je een sleutel en een certificaat genereert, en deze op je server bewaart. Maak daartoe eerst een directory aan:

sudo mkdir /etc/ssl/private

Genereer je certificaat-sleutelpaar met het volgende commando:

openssl req -x509 -nodes -days 3650 -newkey rsa:1024 -keyout /etc/ssl/private/ftp_certificaat.pem -out /etc/ssl/private/ftp_certificaat.pem

Beantwoord de vragen die aan je worden gesteld. Het belangrijkst is die van de hostnaam: deze moet overeenkomen met de hostnaam van je server.

Bij het genereren van het certificaat wordt je gevraagd wat gegevens in te vullen.


Configuratiebestand instellen

Stel nu het ftp-serverconfiguratiebestand in met:

sudo nano /etc/vsftpd/vsftpd.conf

En voeg de volgende regels toe aan het einde van het bestand:

ssl_enable=YES
allow_anon_ssl=NO
force_local_data_ssl=YES
force_local_logins_ssl=YES
ssl_tlsv1=YES
ssl_sslv2=NO
ssl_sslv3=NO
rsa_cert_file=/etc/ssl/private/ftp_certificaat.pem
rsa_private_key_file=/etc/ssl/private/ftp_certificaat.pem

Herstart je server:

systemctl restart vsftpd

Het is nu niet meer mogelijk om zonder versleutelde verbinding contact te maken met je ftp-server, precies zoals we dat wilden. Stel sftp in als de standaard verbindingsmethode van je client en maak verbinding. Je ftp-client – wij gebruiken FileZilla – zal een overzicht van de door jou gebruikte serversleutel laten zien. Accepteer deze, daarna zal de client verbinding maken met je server.

Gelukt! We krijgen het certificaatoverzicht in Filezilla te zien na de eerste keer dat we contact maken.


Versterk je MySQL-database

Geen moderne website kan zonder goede database en MySQL is daarvoor doorgaans de standaardkeuze. Met het dichttimmeren van de MySQL-installatie kom je al een heel eind als je het mysql-hardening-script op je systeem draait dat je met de installatie van de software krijgt meegeleverd. Daarmee kun je in één beweging wachtwoorden beheren, anoniem gebruik tegengaan, externe verbindingen naar je database onmogelijk maken en verwijder je testdata:

sudo mysql_secure_installation

Volg de instructies zorgvuldig en je komt een heel eind. Verder geldt dat het goed is om je gebruikers te beperken in hun bewegingsvrijheid: geef ze alleen toegang tot de hoogstnoodzakelijke databases. En mocht je toch netwerkverbindingen willen toestaan, versleutel ze. Hoe je dat instelt gaat voorbij de essentie van dit verhaal, je kunt in het diepe duiken aan de hand van dit artikel op de website Medium.com: www.tiny.cc/5mysql.

 

MySQL en php

Besteed wat extra aandacht de manier waarop je MySQL via scripts zoals php gebruikt. De klassieke methode is die met het gebruik van de mysqli-driver. Deze is inherent onveilig als je parameters uit de url accepteert en in database-query’s opneemt. Je kunt dan het slachtoffer worden van MySQL-injection-aanvallen. Een veel modernere en stabielere methode vind je in de vorm van een database-abstractielaag als PDO (PHP Data Objects), die je helpt je query’s op relatief eenvoudige wijze te beveiligen. Start met lezen op www.phpdelusions.net/pdo.

En ten tweede is er PHPMyAdmin, deze php-frontend voor MySQL is niet voor niets enorm populair en maakt het beheer van je databases veel eenvoudiger. Zorg dat de toegangspoort ertoe niet makkelijk te vinden is (zie ook het kader ‘Security through obscurity’). Dat doe je door het configuratiebestand te openen:

sudo nano /etc/httpd/conf.d/phpMyAdmin.conf

Onder Ubuntu vind je dit bestand op /etc/apache2/conf.d/phpmyadmin.conf. Verander daar deze regel in iets creatievers:

Alias /phpMyAdmin /usr/share/phpMyAdmin

Bijvoorbeeld:

Alias /pcm_masterclass_toegang /usr/share/phpMyAdmin

Daarna open je PHPMyAdmin door naar https://servernaam.nl/pcm_masterclass_toegang te gaan.

En als je toch in dit bestand bezig bent, je kunt de toegang tot PHPMyAdmin beperken tot alleen het (vaste) ip-adres van je client-pc, door direct onder de start van <Directory /usr/share/phpMyAdmin/> het volgende toe te voegen:

Order Deny,Allow
Deny from All
Allow from 1.2.3.4

Waarbij je 1.2.3.4 vervangt met jouw eigen ip-adres. Zo sluit je heel de wereld buiten, behalve jezelf. Sluit de editor af en herstart apache met:

sudo systemctl restart apache

En controleer of het werkt.


Beveilig je Apache webserver

Apache is van zichzelf al een behoorlijk veilige webserver. Maar het is goed om zelf nog het een en ander af te stellen. Daarom drie snelle tips voor een betere Apache:

Stap 1: versleutel al je verkeer

Dat doe je met een ‘Let’s Encrypt’-certificaat en de volgende commando’s. We gaan ervan uit dat je al een domeinnaam aan de server hebt gekoppeld en deze als virtual host hebt geconfigureerd:

sudo yum install epel-release (mocht je deze nog niet hebben geïnstalleerd)
sudo yum install certbot python2-certbot-apache mod_ssl
sudo certbot install
sudo certbot --apache

Volg de instructies – vergeet niet te selecteren dat al het gewone verkeer wordt doorgestuurd naar poort 443 – en herstart je webserver met:

sudo systemctl restart apache

Stap 2: verberg je softwareversies

Je server verraadt meer over zichzelf dan nodig is, geef de url van server maar eens op bij http://security.firewallmonitor.org. Dan zie je dat zaken als de Apache-versie, je besturingssysteem en php-versie zichtbaar zijn in zowel de footer van lege pagina’s als in de http-headers. Daar heeft helemaal niemand iets mee te maken. Je kunt ze gelukkig makkelijk verbergen, open het Apache-configuratiebestand met:

sudo nano /etc/httpd/conf/httpd.conf

Onder Ubuntu vind je dit bestand op /etc/apache2/conf/httpd.conf of apache2.conf. Onderaan dit bestand voeg je de volgende regels toe:

ServerSignature Off
ServerTokens Prod

Scherm ook de php-versie af door php.ini te bewerken:

sudo nano /etc/php.ini

Wijzig de regel expose_php in expose_php = Off

Als je toch bezig bent, voorkom ook dat php meer informatie over fouten laat zien met:

display_errors = 0
display_startup_errors = 0

En maak uploads onmogelijk als dat kan, zo kunnen hackers in geen geval geen dubieuze scripts naar je server uploaden via het web:

file_uploads = 0

Sla php.ini op en herstart apache met:

sudo systemctl restart apache

Stap 3: voorkom browsen directory’s

Open het configuratiebestand van Apache met:

sudo nano /etc/httpd/conf/httpd.conf

Zoek naar de content directive en wijzig deze in:

<Directory /var/www/html/>
    Options -Indexes
    AllowOverride None
    Require all granted
</Directory>

Als een directory niet is voorzien van een index.php of .html, dan zal je server niet meer laten zien welke bestanden er in staan. En ook nu geldt: herstart natuurlijk de webserver:

sudo systemctl restart apache

 

Tot slot

Je server is nu veel veiliger geworden. De meeste kwaadwillenden houd je nu buiten de deur. Maar vergeet niet dat veiligheid ook een werkhouding is, niet louter het instellen van software en hardware. Zorg dat je op de hoogte blijft van de ontwikkelingen op dit gebied, handel zelf op een veilige manier en maak je back-ups. Veilig ben je nooit honderd procent, maar als je het goed doet, dan kun je heel veel ellende voor zijn. En dat is waar het allemaal om is begonnen.

 

Security through obscurity

Het belangrijkste wat je moet doen om hackers buiten de deur van je server te houden is zorgen dat je software up-to-date is en dat je configuratie op orde is. Maar er is nog een stroming binnen het beveiligingsdenken die het verdient vermeld te worden: ‘security through obscurity’ zoals dit in de digitale wandelgangen wordt genoemd. Of zoals de Nederlandse overheid in zijn anti-inbraakcampagne aanduidt: ‘maak het ze niet te makkelijk’. Zorg dat je een goed slot op je deur hebt, maar het helpt ook als je zorgt dat die deur niet te vinden is. Veel software gebruikt immers standaardmethoden voor zijn installatie en locatie, zorg dat je daar vanaf wijkt. Een mooi voorbeeld is de database-administratiesoftware phpMyAdmin. Dat is een heel gemakkelijke webinterface voor MySQL die zichzelf standaard installeert op www.domein.nl/phpmyadmin. Dat is natuurlijk heerlijk voor hackers. Ze weten daardoor dat je deze software hebt draaien (en kunnen uitzoeken of er misschien een exploit voor is) én dat je server op MySQL draait. Ze kunnen ook proberen het wachtwoord te kraken. Het is in de configuratie van phpMyAdmin makkelijk om die locatie veranderen. Het is namelijk geen directory, maar een alias (zie de paragraaf ‘MySQL en php’). Dus verander dat echt! Weinig hackers zullen de locatie www.domein.nl/pcm_masterclass_toegang kunnen raden. Dat is een kleine maar belangrijke stap op weg naar meer veiligheid. Het is verstandig dat voor alle software met standaardlocaties te doen, denk bijvoorbeeld ook aan WordPress: www.domein.nl/wp-login is een klassieker in de poortscans. En let ook op alles onder de /vendor-directory die door Composer wordt geïnstalleerd.

Dit soortscans zie je heel de dag met onregelmatige intervallen voorbijkomen.

 

 

Share
April 2024
May 2024
No event found!

Related Topics