Je website beveiligen met .htaccess en .htpasswd
.htaccess is een bestand dat aanwezig is op de meeste “niet-Windows” gebaseerde Apache) webservers. .htaccess is een directory-level configuratiebestand. Middels het .htaccess bestand kun je bepaalde configuratiewaardes overschrijven die standaard door de webserver ingesteld zijn. Aan de naam valt al af te lezen dat het bestand oorspronkelijk gemaakt is omwille van veiligheidsoverwegingen. Tegenwoordig kun je nog veel meer met het .htaccess bestand. Ik gebruik .htaccess erg vaak omwille van beveiligingsredenen. Echter kan fout of geen gebruik juist resulteren in een (groot) beveiligingsrisico. In deze post leg ik je graag uit hoe je je website kunt beveiligen met het .htaccess bestand.
*Let op: de beste beveiliging voor je CMS is een speciaal .htaccess script dat toegespitst is op de structuur van je CMS systeem. In deze post behandelen we alleen de algemene beveiligingsmogelijkheden.
Het .htaccess bestand uitgelegd
Het .htaccess bestand heeft hetzelfde formaat als het httpd.conf bestand van een Apache webserver. Ook Sun Java en Zeus webservers ondersteunen tegenwoordig het .htaccess bestand maar de layout is overal hetzelfde. Het voordeel van het .htaccess bestand is dat het door gebruikers zelf in te stellen is en dat de effecten meteen zichtbaar zijn. Echter kan fout gebruik van het .htaccess bestand er ook voor zorgen dat de website foutmeldingen genereert of niet meer benaderbaar is. Dit is de reden dat het bestand populair is op shared hosting servers waar gebruikers zelf het httpd.conf bestand niet kunnen gebruiken om bepaalde zaken te regelen. Het .htaccess bestand wordt opgebouwd middels een “Directive Syntax”. Het bestand moet worden opgeslagen in ASCII formaat (niet binair).
De eerste beveiligingstip
Geef het bestand RW-R—R—(644) rechten en niet 777 (toegang voor iedereen).
Dit zorgt ervoor dat het bestand wel door de webserver gebruikt kan worden maar niet door iedereen met een browser gelezen kan worden.
Opbouw van het .htaccess bestand
Om het .htaccess bestand te begrijpen en te modificeren moeten we weten hoe het is opgebouwd.
Allereerst bevat het .htaccess bestand een syntax die werkt per commandoregel. Dit geldt niet voor alle commando’s maar wel voor het merendeel. Mocht je het bestand aanpassen in een tekstverwerker zorg dan dat “word-wrap” uit staat want anders gaat het mis en werkt je commando niet.
Het .htaccess bestand is van toepassing op de directory waar het instaat en alle subdirectory’s. Kijk uit met het plaatsen van .htaccess bestanden.
Zorg ervoor dat er geen dubbele commando’s worden uitgevoerd waardoor een oneindige lus (loop) veroorzaakt kan worden.
Syntaxis:
Om .htaccess bestanden te begrijpen is het goed om eerst de algemene syntaxis te begrijpen. De belangrijkste zijn:
Het hekje #:
Het hekje in een .htaccess bestand betekent een comment. Plaats comments in je .htaccess bestand om verschillende commando’s te verduidelijken. Alle regels die beginnen met een # hekje worden niet uitgevoerd als commando.
.
Een wildcard. Op de punt kunnen alle mogelijke letters ingevuld worden.
c.t komt overeen met: cat, cot, cut.
+
De + herhaalt het vorige commando een of meerdere malen.
a+ komt overeen met: a, aa, aaa
*
De * herhaalt het vorige commando geen of meerdere malen.
a* komt overeen met: a, aa, aaa en met niks (een lege string)
?
Het vraagteken maakt de voorgaande letter optioneel.
colou?r komt overeen met: color and colour.
^
Dit teken noemen we een “anchor” ofwel een anker. Het anker betekent het begin van een string.
^a komt overeen met een string die begint met: a
$
Dit teken noemen we ook een “anchor”. Dit is echter het eind-anker en betekent het einde van een string .
a$ komt overeen met een string die eindigt met: a
( )
De haakjes groeperen verschillende karakters in 1 unit en onthoud deze voor later gebruik (een soort array).
(ab) komt overeen met: ab en (ab)+ komt overeen met ababab (let op de +)
[ ]
Een karakter klasse. Alle karakters tussen de brackets zijn optioneel .
c[uoa]t komt overeen met: cut, cot or cat.
[^ ]
Dit is de negatieve karakterklasse. Dit komt overeen met elk teken dat niet tussen deze brackers staat.
c[^/]t komt overeen met: cat, cot, c+t of c=t maar niet met c/t
–
De dash betekent dat er geen substitution (vervolgactie) ondernomen hoeft te worden en dat het commando door moet gaan met het uitvoeren van de opgegeven flags zonder het pad te veranderen.
!
Het uitroepteken is het “not” commando. Dit betekent als de opgegeven waarde NIET voldoet aan de prefix dan…
Flags
Flags zijn algemene commando parameters die bepalen met welke eigenschappen het commando wordt uitgevoerd.
Belangrijke flags zijn:
[G]
Gone. Dit betekent dat bepaalde URLs niet meer bestaand. Apache zal de gebruiker meteen een 410 pagina retourneren.
[F]
Forbidden. Dit betekent dat de gebruikte URL verboden is voor de gebruiker. Apache zal meteen een 403 foutmelding retourneren.
[R]
Redirect. Redirect tijdelijk naar de volgende URL.
[NC]
No Case. Dit zorgt ervoor dat de opgegeven URL niet hoofdlettergevoelig is.
[OR]
Or. Dit betekent het huidige commando of het volgende commando.
[L]
Lastrule. Als het commando wordt uitgevoerd dan is dit het laatste commando dat wordt uitgevoerd.
.htaccess voorbeelden
Om bovenstaande informatie goed uit te leggen noemen we hieronder een paar veelgebruikte voorbeelden van .htaccess commando’s.
Alle .htaccess directives (commando’s) zijn hier te vinden: http://httpd.apache.org/docs/2.2/mod/quickreference.html
RewriteEngine on|off:
RewriteEngine wordt gebruikt om URL rewrites mogelijk te maken. RewriteEngine moet aangezet worden om de RewriteRule te laten werken. Om rewrites uit te schakelen is het verstandiger om de RewriteEngine op off te zetten i.p.v. om alle RewriteRules uit te schakelen door er een # hekje voor te plaatsen.
Nadat de ReWriteEngin aan is gezet zijn er ook verschillende opties mogelijk.
RewriteEngine On Options –Indexes Options –FollowSymLinks |
De optie “Indexes” geeft aan dat de server een directory kan laten zien als een lijst als er geen index bestand is. FollowSymLinks betekent dat symbolische links (shortcuts) gevolgd kunnen worden.
RewriteRule:
Met RewriteRule maken we het werkelijk rewriten (herschrijven) mogelijk. RewriteRule is als volgt opgebouwd:
commando pattern substitution [flags]
Bijvoorbeeld:
RewriteRule ^jarnobaselier-beveiligd-websites/?$ jarnobaselier-website-beveiliging.php [NC,L] |
Dit commando zorgt ervoor dat als er iemand een URL opvraagt waarin “jarnobaselier-beveiligd-websites” voorkomt ze doorgestuurd worden naar jarnobaselier-website-beveiliging.php. Hoe dit exact werkt is beter uit te leggen als we de code stap voor stap ontleden:
^/jarnobaselier-beveiligd-websites/?$
Bovenstaande deel uit de code is een pattern (ofwel het patroon). Elke binnenkomende URL wordt gecontroleerd op dit patroon. Als het overeenkomt wordt de rest van het commando uitgevoerd.
jarnobaselier-website-beveiliging.php
Dit is de substitution. Appache zal de gebruiker naar deze URL redirecten.
RewriteCond:
Het RewriteCond commando geeft de voorwaarden / condities aan waaraan moet worden voldaan alvorens de ReWrite conditie wordt uitgevoerd. Er kunnen meerdere ReWriteCond commando’s zijn voor 1 ReWrite regel. Als dat het geval is dan wordt de rewrite pas doorgevoerd als er is voldaan aan de ReWrite Patern en alle RewriteCond(ities).
Het ReWriteCond Command is opgebouwd als:
ReWriteCond Teststring CondPattern
Met ReWriteCond starten we het commando.
Teststring is de waarde die waar moet zijn alvorens de conditie ingeschakeld wordt.
CondPattern is wat er moet gebeuren als de conditie ingeschakeld wordt.
Voorbeeld:
RewriteCond %{HTTP_HOST} ^jarnobaselier\.nl [NC] |
Bovenstaande commando is van toepassing op alle binnenkomende aanvragen zonder www prefix. Laten we de code ook weer stap voor stap ontleden:
%{HTTP_HOST}
Dit is de teststring. Deze variabele betekent dat het pattern getest wordt op de meegezonden HTTP HOST
^jarnobaselier\.nl
Dit is de RewritePattern. ^jarnobaselier\.nl betekent alle verbindingen (http host header) die beginnen met jarnobaselier.nl.
Totaalvoorbeeld:
RewriteEngine On Options –Indexes Options –FollowSymLinks RewriteCond %{HTTP_HOST} ^jarnobaselier\.nl [NC] #Dit commando is van toepassing op alle binnenkomende aanvragen zonder www prefix. RewriteRule ^(.*)$ //www.jarnobaselier.nl/$1 [L,R=301] #Dit commando zorgt ervoor dat als er iemand een URL opvraagt waarin "jarnobaselier-beveiligd-websites" voorkomt ze doorgestuurd worden naar jarnobaselier-website-beveiliging.php # end of code |
Nog even een paar verduidelijkingen op bovenstaande code:
^(.*)$:
Dit betekent feitelijk alles. ^ is het begin van de string en $ is het einde van de string. (.*) betekent alles.
//www.jarnobaselier.nl/$1
Dit zorgt ervoor dat alles dat binnenkomt en voldoet aan de ReWriteCond doorgestuurd wordt naar //www.jarnobaselier.nl/xxx Dus jarnobaselier.nl/website-beveiliging wordt doorgestuurd (herschreven naar) //www.jarnobaselier.nl/website-beveiliging
Website beveiligen met .htaccess
Nu we hebben gezien hoe .htaccess werkt kunnen we al met een aantal makkelijke regels onze website beveiligen. Probeer bijvoorbeeld eens de volgende voorbeelden:
Beveilig je website op IP / hostname basis
order allow,deny deny from 22.22.22.22 deny from 33.33.33. allow from all |
Uitleg:
Order is een regel die de opvolgende regels controleert en als de laatste waarde of enigste waarde overeenkomt dan wordt de regel uitgevoerd. Order allow, deny controleert eerst of een waarde voldoet om hem toe te staan (allow) vervolgens of hij aan een waarde voldoet om hem te weigeren (deny).
Order deny, allow doet hetzelfde maar dan omgekeerd. De volgende regel zegt dus eigenlijk al het verkeer van het ip adres: 22.22.22.22 te weigeren en om al het verkeer van 33.33.33.x te weigeren. Deze regel is dus bedoeld om je website af te schermen of te beveiligen van bekende IP adressen of subnets. I.p.v. ip adressen kun je ook hostnames gebruiken. Hetzelfde commando kun je dus ook gebruiken om de website (bijvoorbeeld in construction mode) alleen voor jezelf zichtbaar te maken. Als jou IP adres 22.22.22.22 is dan ziet deze regel er als volgt uit:
order allow,deny allow from 22.22.22.22 deny from all |
Zorg ervoor dat het .htaccess bestand niet bekeken kan worden:
<Files .htaccess> order allow,deny deny from all </Files> |
Uitleg:
Bovenstaande commando is hetzelfde als het voorgaande commando. De prefix
Voorkom hotlinking:
RewriteEngine on RewriteCond %{HTTP_REFERER} !^$ RewriteCond %{HTTP_REFERER} !^http://(www\.)?jarnobaselier.nl/.*$ [NC] RewriteRule \.(gif|jpg|js|css)$ - [F] |
Uitleg:
Hotlinking ontstaat wanneer iemand linkt naar jou scripts, afbeeldingen etc. Door een link naar jou bestanden te maken wordt deze content opgevraagd op jou server. Hierdoor wordt jouw bandbreedte verbruikt. Om dit tegen te gaan voor GIF, JPG, Javascripts en CSS bestanden kan bovenstaande commando gebruikt worden. Zoals je ziet wordt hiervoor het Rewrite commando gebruikt. De Rewrite condities zorgen ervoor dat:
Lijn 1: RewriteEngine aangezet wordt.
Lijn 2: Deze lijn zegt “als het niet een lege doorverwijzing (empty referral) is”
Lijn 3: Deze lijn zegt “als het niet afkomstig is van je eigen domein”
Lijn 4: En er wordt gelinkt naar de opgegeven bestandstypes, blokkeer ze dan. Hier zorgt de Forbidden [F] flag voor.
Beveilig je directories met wachtwoorden:
Het laatste voorbeeld is wellicht ook de meest gebruikte toepassing. Je kunt namelijk je directories beveiligen met een wachtwoord. Dit zorgt voor een extra beveiligingslaag alvorens de website benaderd wordt. Zo kun je directories met bestanden beveiligen of directories waarin de backend van je CMS aanwezig is. Dit kan bij padgestuurde CMS systemen zoals Joomla. Joomla heeft een standaard “administrator” directory. In deze directory bevinden zich de bestanden om je toegang te geven tot de backend. Om deze directory extra te beveiligen zou je er een wachtwoord op kunnen plaatsen met .htaccess. Om dit goed te doen heb je ook een .htpasswd bestand nodig. In het .htpasswd bestand plaatsen we de gebruikersnaam en het wachtwoord. Deze staan op 1 lijn en het wachtwoord is versleuteld middels crypt maar ook MD5 en SHA kunnen hier gebruikt worden.
We gebruiken in dit voorbeeld 1 gebruiker met de naam “test” en het wachtwoord “testtest”. Er kunnen meerdere gebruikersnamen per lijn worden opgegeven. Probeer een sterk wachtwoord te gebruiken en gebruik niet dezelfde referenties als voor de inlog van je backend.
Om het wachtwoord te genereren raden we het gebruik van een online .htpasswd generator aan. Een voorbeeld hiervan is: https://www.transip.nl/htpasswd/
Ons .htpasswd bestand ziet er dan als volgt uit:
test:Rw01p2Klz1iMs |
Dit .htpasswd bestand mag je overal op de webserver plaatsen. In dit voorbeeld plaatsen we hem boven de www folder zodat niemand via het internet hier bij kan. In dit voorbeeld gebruiken we als pad: /srv/jarnobaselier/user/jarnobaseliernl/pw
Vervolgens ziet het .htaccess bestand in de beveiligde directory er zo uit:
AuthName "Beveiligd gedeelte" AuthUserFile /srv/jarnobaselier/user/jarnobaseliernl/pw.htpasswd AuthGroupFile /dev/null AuthType Basic require valid-user |
Uitleg:
AuthName “Beveiligd gedeelte”:
Deze regel is de naam van de gebruikersnaam / wachtwoord popup.
AuthUserFile /srv/jarnobaselier/user/jarnobaseliernl/pw.htpasswd:
Deze regel specificeert het pad naar het .htpasswd bestand.
AuthGroupFile /dev/null:
Deze regel vertelt dat er niet met gebruikersgroepen gewerkt wordt.
AuthType Basic:
Deze regel vertelt het type authenticatie dat we gebruiken. Omdat dit http authenticatie is moeten we “basic” gebruiken.
require valid-user:
Deze line zorgt ervoor dat elke gevalideerde gebruiker toegang tot de directory krijgt. Je kunt dit ook afschermen per gebruikersnaam. Bijvoorbeeld door het volgende te gebruiken: require user test
Wanneer bezoekers nu naar de beveiligde directory browsen krijgen ze een inlogscherm te zien. Pas na het succesvol inloggen zal de inhoud van de directory getoond worden.
Tot slot:
Er is op het internet nogal wat commotie over het .htaccess bestand en of dit bestand nog niet overbodig is. Hoewel alles vanuit het .htaccess bestand ook op andere manieren te regelen is zorgt het .htaccess bestand ervoor dat gebruikers (zeker op shared hosting servers) vrijheid krijgen in de manier waarom hun website / domein omgaat met aanvragen naar de webserver. Ik zelf gebruik het bestand veel voor beveiligingsdoeleinden en denk dat het zeker een extra laag van bescherming kan zijn. De enige reden om het .htaccess bestand te vervangen voor een ander systeem is de leesbaarheid en duidelijkheid. Voor de beginnende gebruiker zal het .htaccess bestand niet duidelijk en zelfs niet leesbaar zijn.
Ik hoop met deze post iets meer inzicht te hebben gegeven in het .htaccess bestand. Meer geavanceerde en toegespitste .htaccess trucks behandelen we verder in een toekomstige posts.
Bedankt voor het lezen!
Moeilijke woorden in deze post:
Apache (webserver):
Apache is een open-source webserver. Apache wordt meestal gebruikt op *nix (Unix, linux) machines maar kan ook gebruikt worden op Windows en Mac. Apache is een van de meest gebruikte webservers en is populair door de vele ondersteunde databases en scripttalen. Apache werkt v.a. versie 2 ook als threaded webserver. Dit zorgt voor een verbeterde prestatie, zeker op Windows.
ASCII formaat:
ASCII is een tekenset. Er bestaan veel verschillende tekensets op het internet. ASCII staat voor American Standard Source Code for Information Interchange. Het voordeel van ASCII is letters, cijfers en leestekens te representeren en om aan elk teken een getal te kunnen koppelen. ASCII bestaat uit 128 codes waarvan 95 zichtbare tekens en 33 stuurcodes.
Shared hosting:
Shared hosting is het delen van alle resources die een webserver tot zijn beschikking heft met meerdere gebruikers. Instellingen van een Shared Hosting server worden vaak niet aangepast aan individuele belangen.
Syntax:
Een syntax is een bepaalde (programmeer)taal opgebouwd volgens een gedefinieerde structuur. Als de syntax goed is opgebouwd zal de ontvanger deze begrijpen en interpreteren.
Wildcard:
Een wildcard wordt vaak vergeleken met de joker in een kaartspel. Een wildcard is een symbool die elk symbool representeert.
Word-wrap:
Word-wrap is een methode die door veel tekstverwerkers gebruikt wordt om tekst overzichtelijk in 1 venster te laten zien. Door word-wrap toe te passen wordt tekst op een volgende lijn geplaatst wanneer deze het einde van het venster van de tekstverwerker bereikt heeft en niet wanneer werkelijk een nieuwe zin begint.