Webserver/htaccess/Zugriffskontrolle

Aus SELFHTML-Wiki
Wechseln zu: Navigation, Suche

Mit einer .htaccess-Datei können Sie u. a. eine benutzerdefinierte Zugriffskontrolle für den Directory-Zweig ab der Position der Datei erreichen. Eine der häufigsten Verwendungen ist die Einrichtung eines Passwortschutzes, sodass bestimmte Seiten oder Inhalte nur nach Eingabe eines Passworts aufgerufen werden können und für andere Nutzer und auch für Suchmaschinen verborgen bleiben.

Dies können im Aufbau befindliche, noch nicht vorzeigbare Seiten oder interne Mitgliederbereiche wie ein Vertretungsplan nur für das Lehrerkollegium sein. Außerdem können z. B. MIME-Types zugewiesen werden, u. v. m.

Für die Funktion muss der Webserver nicht neu gestartet werden. Die Konfigurationsangaben werden bei jedem Zugriff auf den Pfad verarbeitet. Dauerhafte und/oder allgemeingültige Regelungen sollten daher nicht in einer .htaccess-Datei geregelt werden, sondern in der (Virt)Host-Konfiguration der Domain.

Verzeichnisse und Dateien mit Passwort schützen

Speichern Sie in dem Verzeichnis, das Sie schützen wollen, eine .htaccess-Datei.

.htaccess-Datei für Passwortschutz
# .htaccess-Datei für Passwortschutz
AuthType Basic
AuthName "Geschützter Bereich - Bitte geben Sie ein Passwort ein!"
AuthUserFile /Individueller/Pfad/.htpasswd
Require valid-user
Hinweis:
Sollen auch CGI-Programme im cgi-bin-Verzeichnis geschützt werden, muss eine weitere .htaccess dort abgelegt werden.[1]

Um einen Passwortschutz einzurichten, brauchen Sie die Anweisungen AuthType, AuthName, AuthUserFile, und wenn Sie mit Benutzergruppen arbeiten, auch AuthGroupFile. Ferner benötigen Sie, wenn Sie den Zugriff auf bestimmte Benutzer oder Gruppen aus diesen Dateien festlegen (also einschränken) wollen, eine oder mehrere Angaben der Anweisung Require.

  • AuthType bezeichnet die Art der Authentifizierung.
    • Basic: sogenannte HTTP Basic Authentication (einfache Authentifizierung über HTTP). Dabei stehen die Benutzernamen und die zugehörigen Passwörter in einer noch anzugebenden Datei. Diese Methode verlangt aber, dass das Passwort unverschlüsselt vom Browser an den Webserver übermittelt wird. Sie ist daher nicht wirklich sicher.
    • Digest: Dabei werden Passwörter bereits in verschlüsselter Form abgefordert, allerdings beherrschen das nicht alle Browser. Sie müssen daher entscheiden, was für Sie Vorrang hat: höhere Sicherheit oder die Berücksichtigung der Browser und Clients, die nur die einfache Authentifizierung unterstützen.
  • AuthUserFile: gibt die Datei an, in der die Namen der autorisierten Benutzer und ihre Passwörter stehen. Es sollte der vollständige absolute Pfadname angegeben werden.
  • Require: Legt mit einem zweiten Schlüsselwort fest, für welche Benutzer, bzw. Benutzergruppen das Passwort gelten soll. Hinter diesem Schlüsselwort können ein oder mehrere Namen von Benutzern oder Benutzergruppen folgen. Alternativ können Sie auch das Schlüsselwort valid-user benutzen, um alle Benutzer zuzulassen, falls die Liste sonst zu lang werden würde.
    • user: gefolgt von einer Liste der Benutzer
    • group: gefolgt vom Namen der Gruppe

.htpasswd Datei erstellen

Damit der Verzeichnisschutz mit Passwort funktioniert, genügt die .htaccess-Datei alleine allerdings nicht. Sie brauchen zusätzlich eine Text-Datei, in der (der Benutzername und) das zugehörige Passwort steht.

.htpasswd-Datei
# Passwort-Datei
name:$2y$05$MQ7RdCCRrKmBEDD/u4pks.9qAV8RCKy4YCP2pzgmc4lppfli41zC

Achtung!

Theoretisch können Sie Passwörter im Klartext notieren. Da sie so aber auch von Fremden ausgelesen werden können, sollten Sie sie immer verschlüsseln. Dabei sollten Sie folgendes berücksichtigen:
  • Verzichten Sie dabei auf die veraltete MD5-Verschlüsselung.
  • Benutzernamen dürfen nicht länger als 255 Bytes sein und weder den Punkt noch den Doppelpunkt als Zeichen enthalten.
  • Da der Apache Webserver Kommentare in den Passwortdateien unterstützt, ist es - obwohl mit htpasswd möglich - keine gute Idee, das Raute-Zeichen ("#") im Benutzernamen zu verwenden. Der Benutzer kann sich dann ganz einfach nicht anmelden.
  • Unter Windows werden Passwörter, die länger als 255 Bytes sind auf 255 Bytes gekürzt. Beachten Sie, dass deutsche Umlaute unter UTF-8 zwei Bytes benötigen.

Wenn nicht ausdrücklich vom Provider bzw. Webmaster anders bestimmt, sollten Sie außerdem für die Datei einen Namen wählen, der mit .ht beginnt, üblicherweise eben .htusers oder .htpasswd. Wir verwenden in diesem Artikel den Namen .htpasswd.

Mit der Standardkonfiguration des Apache-Servers werden Dateien, die mit .ht beginnen, grundsätzlich weder angezeigt noch an den Client ausgeliefert, selbst wenn man sie ausdrücklich namentlich anfordert.

Zusammen mit dem Apache wird ein kleines Hilfsprogramm ausgeliefert, das die Erstellung solcher Passwortdateien vereinfacht. Es heißt htpasswd (unter Windows: htpasswd.exe) und ist über die Konsole (Eingabeaufforderung) zu bedienen. Rufen Sie es einfach mit dem Befehl htpasswd -h auf, um eine kurze Hilfe zu seiner Verwendung zu erhalten. Im einfachsten Fall geben Sie zur Erzeugung folgenden Befehl ein:

htpasswd -c -B .htpasswd smuenz

oder, falls die Datei schon existiert:

htpasswd -B .htpasswd smuenz

ein. Sie müssen für den neuen Benutzer smuenz ein Passwort angeben und bestätigen. Diese Passwortdatei können Sie dann in das vorgesehene Verzeichnis verschieben oder hochladen.

Beachten Sie,

  • den Schalter bzw. die Option -c setzen Sie, um die Datei neu anzulegen. Achtung! Eine bestehende Datei wird dabei ohne Warnung überschrieben!
  • wenn Sie den Schalter bzw. die Option -c nicht verwenden wird das neue Benutzer-Passwort -Paar entweder an die Datei angehängt oder ein eventuell bestehender Eintrag für diesen Benutzer neu gesetzt.
  • Um Backups dieser Datei müssen Sie sich selbst kümmern.
  • den Schalter bzw. die Option -B verwenden Sie um einen „gesalzenen“ Passwort-Hash mit einem aktuell (04.07.2022) als sicher geltenden Verfahren (bcrypt) zu erzeugen. Andere Verfahren sind als „unsicher“ verworfen, deren Verwendung ist grob fahrlässig.

    Achtung!

    Sie müssen das große B verwenden. Es gibt auch einen -b Schalter, aber der sorgt dafür, dass das Passwort im Klartext im Befehl erwartet wird, und nicht in einem eigenen Schritt verdeckt danach gefragt wird!
  • dass diese Datei auf Unix- oder Linux-basierten Systemen wegen des Punktes am Anfang des Dateinamens nicht angezeigt wird, wenn Sie den Verzeichnisinhalt auflisten. Verwenden Sie daher den Schalter -a (all) oder -A(allmost), wenn Sie mit ls in der Konsole arbeiten. Falls Sie einen graphischen Dateimanager verwenden, stellen Sie ihn so ein, dass er versteckte Dateien mit anzeigt.

Passwortschutz für mehrere Benutzer

Sie können wahlweise das ganze Verzeichnis mit all seinen Unterverzeichnissen oder nur bestimmte Dateien oder Dateitypen schützen. Sie können den Passwortschutz außerdem wahlweise für einzelne Benutzer oder für ganze Benutzergruppen einrichten. Auch Kombinationen beider Formen sind möglich. Außerdem ist es auch möglich, den "oben" eingrichteten Schutz (egal welcher Art: Passwort, Dateityp, IP, ...) weiter unten im Verzeichnisbaum wieder aufzuheben. Und nicht vergessen: Verzeichnisbäume stehen in der Darstellung immer auf dem Kopf ;-)


.htaccess-Datei für mehrere Benutzer
# .htaccess-Datei für Web-Verzeichnis /service
AuthType Basic
AuthName "Service-Bereich"
AuthUserFile /usr/verwaltung/web/.htpasswd
AuthGroupFile /usr/verwaltung/web/.htgroups
Require user  Werner Dieter Heidi
Require group Servicetechniker

Damit der Verzeichnisschutz mit Passwort funktioniert, genügt die .htaccess-Datei alleine allerdings nicht. Sie brauchen zusätzlich eine Datei, in der die Benutzernamen und die zugehörigen Passwörter stehen. Falls Sie mit Benutzergruppen arbeiten, benötigen Sie außerdem noch eine Datei, in der die Benutzergruppen definiert werden.

Im obigen Beispiel werden die drei Benutzer Werner, Dieter, Heidi sowie alle Benutzer der Gruppe Servicetechniker angegeben. Damit der Passwortschutz funktioniert, müssen nun die angegebenen Dateien mit den Benutzernamen und (falls benötigt) den Gruppen angelegt werden:

Benutzerdatei

.htpasswd-Datei
# BenutzerDatei für Web-Projekt
Werner:$2y$05$MQ7RdCCRrKmBEDD/u4pks.9qAV8RCKy4YCP2pzgmc4lppfli41zC
Dieter:{SHA}i8xKRW2XJbkGN4UbpkXBfVjSKXs=
Heidi:$apr1$.P2k7JQX$dBcOPzzpEcQYcR0ZGw24Q0

Jede Zeile der Benutzerdatei enthält einen Benutzernamen, und gleich dahinter, durch einen Doppelpunkt getrennt, das "gehashte" (eine Art "Einwegverschlüsselung") Passwort (es wurde jeweils "hallo" verwendet).

  • Der erste Eintrag (Werner) wurde mit dem Befehl htpasswd -B .htpasswd Werner erzeugt (ab Apache 2.4).
  • Der zweite Eintrag (Dieter) wurde mit dem Befehl htpasswd -s .htpasswd Dieter erzeugt.
  • Der dritte Eintrag (Heidi) wurde mit htpasswd .htpasswd Heidi erzeugt.
Beachten Sie: Die dritte (es handelt sich um den veralteten MD5-Algorithmus mit einem zusätzlichen 32-Bit-Salt) und die zweite Methode (sha1, ohne Salt) gelten beide als unsicher, wobei sha1 die schlechteste der vorgestellten Varianten ist! Wenn Sie mehr über die Hashfunktionen wissen wollen, dann lesen Sie in der Dokumentation des Apache 2.4. nach. Wenn die Passwörter durch ein PHP-Skript erzeugt werden sollen, dann sehen Sie sich die Funktion password_hash und das Manual an.

Gruppendatei

Gruppendateien bestehen aus Einträgen, bei denen zunächst ein Gruppenname notiert wird und dahinter, nach einem Doppelpunkt, die Namen von Benutzern, die zu dieser Gruppe gehören. Es müssen Benutzernamen sein, für die in der Benutzerdatei ein Eintrag angelegt wurde.

.htgroups-Datei
# GruppenDatei für Web-Projekt
Servicetechniker: Andreas Karin Janine

Die Gruppendatei wird im Beispiel nur benötigt, weil in der .htaccess-Datei mit authGroupFile eine Benutzergruppe angegeben wurde; die Gruppendatei wird ausschließlich dann erforderlich, wenn Sie Gruppennamen benutzen. In einem Intranet ist auch eine Benutzerdatei nicht zwingend erforderlich, da Sie Zugriffserlaubnisse und -verbote über die Zulassung bzw. den Ausschluss der internen IP-Adresse regeln können.

Effekt:

Alle Besucher des Web-Projekts, die nun versuchen, auf das Verzeichnis mit der .htaccess-Datei zuzugreifen, bekommen von ihrem Browser einen Dialog angeboten, in dem sie Benutzernamen und Passwort eingeben müssen. Nur Besucher, die sich mit einer gültigen Kombination aus Benutzernamen und Passwort anmelden, haben Zugriff auf das Verzeichnis.

Schutz für bestimmte Dateitypen

So wie im obigen Beispiel gezeigt, gilt der Zugangsschutz für das Verzeichnis, in dem die .htaccess-Datei liegt, und für alle Verzeichnisse unterhalb davon. Sie können den Schutz aber auch auf bestimmte Dateien, Dateitypen oder Zugriffsmethoden einschränken.

.htaccess-Datei für Web-Verzeichnis
# .htaccess-Datei für Web-Verzeichnis /service

AuthType Basic
AuthName "Service-Bereich"
AuthUserFile /usr/verwaltung/web/.htpasswd
AuthGroupFile /usr/verwaltung/web/.htgroups

<Files *.htm>
Require user  Werner Dieter Heidi
Require group Servicetechniker
</Files>

<Files *.csv>
Require group Servicetechniker
Require not user meier # Darf trotz Gruppenmitgliedschaft nicht zugreifen
</Files>

Um den Schutz einzuschränken, benutzen Sie ähnlich wie in HTML oder XML Tags mit spitzen Klammern. Im einleitenden Tag kann hinter der öffnenden spitzen Klammer entweder Files stehen, wie im obigen Beispiel. Dahinter können Sie genau eine einschränkende Angabe machen. Mit *.htm wie im Beispiel beschränken Sie den Schutz auf HTML-Dateien. Mit einer Angabe wie geheim.htm würde nur diese eine Datei geschützt. Anstelle von Files können Sie auch FilesMatch einsetzen. Dann sind Reguläre Ausdrücke möglich. Beispielsweise würden Sie mit <FilesMatch "\.(htm|php)$"> alle HTML-Dokumente und alle PHP-Scripts erfassen.

Eine weitere Möglichkeit besteht darin, anstelle von Files die Anweisung Limit, oder besser noch LimitExcept anzuwenden. Sie hat Auswirkungen auf HTTP-Methoden wie GET, POST, PUT, DELETE, CONNECT, OPTIONS usw. Mit <LimitExcept GET> können Sie für alle Zugriffsmethoden Bedingungen formulieren, mit Ausnahme von GET – und mit Mit <LimitExcept POST> würden Sie für alle Zugriffsmethoden mit Ausnahme von POST Zugriffsbedingungen formulieren können.

Beachten Sie: Falls es bei Ihnen einfach nicht mit dem Schützen von Verzeichnissen klappen will, dann könnte der Grund darin liegen, dass in der zentralen Konfiguration des Apache Webservers beim Eintrag AllowOverride der Wert None gewählt wurde.

Kombinierte Zugriffsschutzfilter

Ab Apache 2.4 steht die Methode <require...> zur Verfügung mit ihren vielfältigen Möglichkeiten für Zugriffsschutz-Container.

Ein Beispiel für den kombinierten Zugriffsschutz über Username:Passwort und/oder passende Requestor-IP könnte folgendermaßen aussehen:

.htaccess-Datei für kombinierten Zugriffsschutz nebst weiterer Optionen
 
## .htaccess
AuthName "Bitte User und Passwort eingeben"
AuthUserFile /var/www/.htpasswd
AuthType Basic

<RequireAny>
    Require ip 192.168.178.
    Require ip 127.
    Require ip ::1
    Require valid-user
</RequireAny>

IndexOptions +NameWidth=80
IndexOptions +IgnoreCase
IndexOptions +FoldersFirst
IndexOptions +FancyIndexing


Hier wäre der Zugriff erlaubt aus dem LAN des Webservers (192.168.178.###), vom Host des Webservers selbst (via http/s) und für alle berechtigten Benutzer aus der Identifikationsdatei /var/www/.htpasswd. Weitere Anzeigeoptionen für das Verzeichnis sind möglich.

IP-Adressen oder IP-Bereiche zulassen/ausschließen

Sie können bestimmte IP-Adressen oder IP-Bereiche davon ausschließen, auf Webseiten zuzugreifen. Anwender, die über eine nicht autorisierte IP-Adresse zugreifen, erhalten dann eine HTTP-Fehlermeldung (den HTTP-Status-Code 403), und der Zugriff wird ihnen verweigert.

Sinnvoll ist das beispielsweise, wenn Ihr Web-Angebot nur den Mitarbeitern Ihrer Firma im firmeninternen Intranet zugänglich sein soll. In einem solchen Fall kennen Sie vermutlich die vorhandenen Netze, möglicherweise sogar alle im Intranet fest vergebenen IP-Adressen. Oder Sie möchten bestimmte Anwender, die mit festen IP-Adressen unterwegs sind, ausschließen.

Sie können

  • IP-Adressen, partielle IP-Adressen, ein Netzwerkadresse/Netzwerkmaske-Paar, auch in CIDR[2]-Schreibweise.
  • sowohl IPv4 als auch IPv6-Adressen
  • DNS-Hostnamen oder DNS-Domainnamen

angeben.

Beachten Sie, dass beim Ausschluss nach Domainnamen jeweils ein reverser DNS-Request notwendig wird. Das ist „teuer“ und bringt eine Reihe von Volatilitäten bzw. Unwägbarkeiten mit sich (z.B. ob die Antwort auf den DNS-Request überhaupt erfolgt und mit dem korrektem/erwartetem Ergebnis übereinstimmt).

In der Regel wird man dieses ergo nur tun, wenn sich diese Angaben auf selbst verwaltete IPs, Netzbereiche und Domains und diese durch im eigenen DNS-Netzwerk befindlichen DNS-Server überprüft werden. Ansonsten kann „alles“ passieren: Falsches Verbieten, falsches Erlauben, ungewöhnlich lange Wartezeiten für Clients.

1. Ausschluss bestimmter IPs oder Namensdomains.
# Erlauben des Zugriffs für jeden (Entspricht dem Default)
Require all granted

# Regel zum Ausschluss von einzelnen IPs
Require not ip 198.51.100.17

# Regel zum Ausschluss eines IP-Bereichs (203.0.113.0/24)
Require not ip 203.0.113
# identisch wirkende Regel zum Ausschluss eines IP-Bereichs (203.0.113.0/24)
Require not ip 203.0.113.0/24
# identisch wirkende Regel zum Ausschluss eines IP-Bereichs (203.0.113.0/255.255.255.0)
Require not ip 203.0.113.0/255.255.255.0

# Regel zum Ausschluss eines Hostnamens:
Require not host complete.idiot.example
# Regel zum Ausschluss von allen Hosts einer DNS-Domain:
Require not host idiots.example

Die Notation einer Netzwerkadresse mit CIDR (e.g. „203.0.113.0/24“) ist aus Gründen der leichten Er- und Übersichtlichkeit zu bevorzugen. Aus technischer Sicht gibt es keinen merkbaren Unterschied.

2. Erlauben des Zugriffs von bestimmten IPs oder Namensdomains.
# Verbieten des Zugriffs für jeden
Require all denied

# Regel zum Erlauben des Zugriffs von einer einzelnen IP:
Require ip 198.51.100.17

# Regel zum Erlauben des Zugriffs von einem IP-Bereich (203.0.113.0/24)
Require ip 203.0.113.0/24

# Regel zum Erlauben des Zugriffs von einem Gerät mit bekanntem Hostnamen:
Require host one.of.the.hosts.example
# Regel zum Erlauben des Zugriffs von allen Hosts einer DNS-Domain:
Require host trusted.hosts.example

Die oben ersichtlichen Regeln für die Schreibweisen gelten auch hier.

Bei einem Mix dieser Regeln werden diese von oben nach unten abgearbeitet:

3. Selektierendes Verbieten → Erlauben → Verbieten.
# Allen Hosts den Zugriff verbieten
Require all denied

# Nun die Regel zum Erlauben des Zugriffs von einem IP-Bereich (203.0.113.0/24)
Require ip 203.0.113.0/24

# ... Und dann den Zugriff für einen „bösen“ Rechner aus diesem Bereich verbieten:
Require not ip 203.0.113.254
  • Die oben ersichtlichen Regeln für die Schreibweisen gelten auch hier.
  • Bei diesem Mix können natürlich auch Host- oder Domainnamen verwendet werden.

Fazit

Schutzmechanismen mit .htaccess-Dateien auf Server-Seite, die mit HTTPS verschlüsselt übermittelt werden, sind wesentlich sicherer als solche, die mit Hilfe von JavaScript, VBScript o. ä. auf Client-Seite erstellt werden. Dennoch sollten Sie beachten, dass .htaccess keinen Generalschutz bietet.

Der Schutz gilt nur über das HTTP/s-Protokoll, also wenn z. B. per Browser oder wget (Linux-Tool) beim Server eine Anfrage gestellt wird.

Der Schutz gilt nicht, wenn der Zugriff mit einem anderen Protokoll, wie z. B. mit s/FTP, SSH, SMB, usw. direkt auf das Dateisystem des Hosts erfolgt. Die Umgehung des HTTP-Servers bedeutet auch die Umgehung des Schutzmechanismus.

Problematisch bei diesem HTTP-Authentication-Verfahren ist außerdem, dass es keine standardisierte Methode zum Ausloggen gibt. Der Browser speichert die erfolgreichen Zugangsdaten bis zum Ende der Sitzung und vergisst sie erst, wenn alle Browserfenster (das Programm) geschlossen wurden. Mittlerweile bieten alle gängigen Browser an, die Zugangsdaten dauerhaft zu speichern, was die Problematik mit dem Ausloggen nicht gerade vereinfacht.

Als Workaround kann man zum "Ausloggen" eine falsche Anmeldung senden, also Username und falsches Passwort. Dies funktioniert z.B. auch per XML-HttpRequest (AJAX) und damit auch per vom Webseitengestalter vorgesehenen Button (/?logout). Hier sollte dann von der Serverseite die passend gestaltete Error-Page als Antwort kommen.

Generell wäre der Einsatz eines Token-basierten Login-Systems (Cookies) flexibler und eventuell etwas sicherer.

Beachten Sie: Die Übertragung von Credentials ("Login"-Daten) sollte immer nur über eine gesicherte Verbindung (TLS) erfolgen.
Hauptartikel: PHP/Tutorials/Loginsystem


Weblinks

Quellen

  1. SELFHTML-Forum: Passwortschutz (02.07.2001)
  2. Classless Inter-Domain Routing(de.wikipedia.org)