blog.bartlweb - a technologist's external brain

Thema: Apache

cURL kann URLs mit HTTPS nicht abrufen

Ich habe versucht mit meiner PHP-Installation und cURL eine Website mit HTTPS abzurufen und dabei die folgende Fehlermeldung erhalten:

Uncaught exception 'GuzzleHttp\Exception\RequestException' with message 'cURL error 60: SSL certificate problem: unable to get local issuer certificate (see http://curl.haxx.se/libcurl/c/libcurl-errors.html)'

Das Problem liegt darin, dass cURL die aktuellen Root-Zertifikate der offiziellen Zertifizierungsstellen nicht kennt. Das lässt sich ganz einfach durch Aktualisieren bzw. Bereitstellen dieser Liste beheben.

Laden Sie dazu unter curl.haxx.se/ca/cacert.pem die aktuelle Liste herunter und legen Sie diese im Installationsverzeichnis Ihrer PHP-Installation ab. Danach editieren Sie die PHP-Konfigurationsdatei php.ini und geben für den Parameter curl.cainfo den Pfad zur Zertifikatsdatei an.

curl.cainfo = "C:/Program Files (x86)/PHP/cacert.pem"

Self-signed Zertifikate für lokale Webservices mit OpenSSL selbst erstellen

Nicht für jeden Webservice ist es notwendig, ein kostenpflichtiges SSL-Zertifikat von einer anerkannten Registrierungsstelle zu erwerben. So kommen Entwicklungssysteme oder Dienste für eine eingeschränkte nicht-öffentliche Zielgruppe, bei denen es nur auf eine zuverlässige Verschlüsselung, aber nicht auf eine Verifizierung ankommt durchaus mit selbst erstellten Zertifikaten aus.

Self-signed Zertifikat erstellen

Eigene Zertifikate lassen sich mit OpenSSL sowohl unter Linux als auch Windows sehr einfach und rasch mit dem folgenden Befehl erstellen. Die für das Zertifikat notwendigen Daten werden dabei durch das Tool über die Kommandozeile abgefragt. Im unteren Beispiel habe ich ein Zertifikat für einen Entwicklungsrechner erstellt und daher eine Gültigkeit von 10 Jahren (3650 Tage) gesetzt, dieser Wert lässt sich aber beliebig an die eigenen Bedürfnisse anpassen.

Pfade oder Dateien von Redirects mit mod_rewrite in Apache ausnehmen

Der Apache Webserver bietet mit mod_rewrite ein mächtiges Werkzeug, um URLs zu modifizieren. Die Klassiker sind dabei der Redirect von HTTP auf HTTPS oder auch von einer ganzen Domain auf eine andere (z.B. von example.com auf www.example.com).

Doch nicht immer sollen alle Pfade oder Dateien umgeleitet werden. Einen konkreten Fall bilden die Validierungsdateien für Domains, wie Sie von Let's Encrypt verwendet werden, die immer von der Originaldomain für welche die Zertifikate ausgestellt werden sollen abgefragt werden müssen.

Die folgenden beiden Beispiele zeigen, wie ein Pfad vom Redirect auf HTTPS bzw. auf eine andere Domain ausgenommen werden kann:

RewriteEngine On
RewriteCond %{HTTPS} off
RewriteCond %{REQUEST_URI} !^/\.well-known/acme-challenge/.*$ [NC]
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
RewriteEngine On
RewriteCond %{REQUEST_URI} !^/\.well-known/acme-challenge/.*$ [NC]
RewriteRule ^(.*)$ https://www.example.com/ [R=301,L]

Eigene Ressourcen in Website die mit mod_proxy von Apache ausgeliefert werden einbinden

Oft dient der Apache Webserver nur als Gateway für weitere im internen Netzwerk liegende Webservices, die aber nach außen hin über Standardports bzw. öffentliche Domains erreichbar gemacht werden sollen. Dazu bedient man sich dem Konzept des Reverse Proxy und dem Apache Modul mod_proxy.

Was aber, wenn zusätzliche Ressourcen von diesen Domains ausgeliefert werden sollen (z.B. Verifizierungsdateien für Google Analytics oder Let's Encrypt, robots.txt, ...), die aber nicht über den eigentlichen Webservice bereitgestellt werden können? Hier kann der Apache Webserver bzw. mod_proxy helfen und einzelne Pfade von der Weiterleitung an das Zielsystem ausnehmen und damit dessen Inhalte selbst bereitstellen. So können dann z.B. global verfügbare Alias-Definitionen oder einzelne virtuelle Verzeichnisse in den Proxy-Hosts verfügbar gemacht werden.

HTML-Anmeldeformulare mit Apache Modul mod_auth_form

Apache stellt verschiedene Varianten für die Authentifizierung von Nutzern bereit. Die bekannteste ist wohl AuthType Basic die im Browser eine schnöde Eingabeaufforderung für Benutzername und Passwort erzeugt. Aber der Apache Webserver liefert mit mod_auth_form auch ein Modul mit, mit dem sich ein HTML-Formular für die Anmeldung nutzen und vor allem selbst adaptieren und gestalten lässt.

Module laden

Damit mod_auth_form funktioniert, muss das entsprechende Modul durch Auskommentieren in der httpd.conf geladen werden. Außerdem werden noch weitere Module zum Verarbeiten der Requests und zum Erzeugen und Speichern der Sessions benötigt.

Zugriff auf Apache vHosts vom internen Netzwerk erlauben, aber für externe Netzwerkzugriffe absichern

Gerade bei einfachen Netzwerkdiensten, wie z.B. einem Medienserver, soll im internen Netzwerk der Zugriff uneingeschränkt möglich sein, aber sobald jemand aus dem Internet darauf zuzugreifen versucht, dies entweder untersagt oder mittels Passwort geschützt sein. Dazu lässt sich die Konfiguration des virtuellen Hosts entsprechend anpassen, um für einzelne IP-Bereiche bereits gemachte Einschränkungen wieder aufzuheben.

Konfiguration ab Apache 2.4

Ab Apache 2.4 wird die RequireAny-Direktive genutzt, um Ausnahmen für die aktivierte Basic-Authentifizierung zu schaffen. In diesem Fall wird der Zugriff gestattet, wenn der Nutzer entweder eine IP aus dem Netzwerk 192.168.0.* nutzt oder einen gültiger Nutzer (Authentifizierung) ist.

Apache HTTP-Server hängt unter Windows beim Ausliefern von Webseiten

Ich nutze den Apache Webserver unter Windows für die lokale Entwicklung und habe dabei in letzter Zeit des Öfteren beobachtet, dass plötzlich Anfragen gar nicht mehr oder nur mit erheblicher Zeitverzögerung beantwortet werden und das sowohl bei lokalen Aufrufen (localhost) als auch Aufrufen aus dem Netzwerk.

In der Log-Datei habe ich den folgenden Fehler entdeckt:

[Sun Mar 06 19:55:41.729117 2016] [mpm_winnt:warn] [pid 3820:tid 2240] (OS 64)Der angegebene Netzwerkname ist nicht mehr verf��r.  : AH00341: winnt_accept: Asynchronous AcceptEx failed.

Eine kurze Recherche hat zwei mögliche Lösungsansätze aufgezeigt, die das Phänomen behoben haben.

cURL in PHP 5.5 unter Windows aktivieren

Nachdem ich meine Entwicklungsumgebung unter Windows 8 auf den aktuellen PHP-Release 5.5 aktualisiert habe, konnte ich die PHP-Erweiterung cURL einfach nicht zum Laufen bekommen. Eine kurze Recherche ergab, dass dazu die Datei libssh2.dll aus der PHP-Installation in den Apache Binary-Ordner kopiert werden muss.

D.h. folgende Schritte sind notwendig um cURL unter PHP 5.5 für Windows zu aktivieren:

1) Aktivieren Sie die Extension in dem Sie in Ihrer PHP-Konfigurationsdatei php.ini die folgende Zeile aktivieren:

extension=php_curl.dll

2) Kopieren Sie die Dateien libeay32.dll, libssh2.dll und ssleay32.dll aus der PHP-Installation in den bin-Ordner Ihrer Apache-Installation.

Ladeprobleme mit Apache und PHP unter Windows – Die Verbindung zum Server wurde zurückgesetzt

Nachdem ich mich dazu entschieden habe auf meiner Workstation das Entwicklungspaket XAMPP gegen eine pure Apache- und PHP5-Installation zu tauschen, bin ich bei aufwendigeren PHP Seiten (vorwiegend mit Regular Expressions) immer wieder auf Ladeprobleme gestoßen. Dabei habe ich im Browser die Meldung bekommen, dass die Verbindung vom Server zurückgesetzt wurde. Weder in den PHP- noch in den Apache-Logdateien fand sich jedoch ein brauchbarer Hinweis auf einen Fehler im PHP-Code.

Schließlich habe ich im Apache-Log den folgenden Hinweis gefunden, der darauf hindeutet, dass hier der Apache Prozess immer wieder abstürzt.

Parent: child process exited with status 255 -- Restarting.

Shorturls mit mod_rewrite erstellen

Die folgende RewriteRule für das Apache-Modul mod_rewrite wird in die htaccess-Datei integriert und bewirkt eine Weiterleitung bei Eingabe der Kurzurl auf die angegebene Seite. Dabei ignoriert die Regel unterschiedliche Groß- und Kleinschreibung und ein nachgestelltes Slash.

RewriteRule ^short?/$ /your/target/page.html [NC,R=301,L]

D.h. die oben angegebene Weiterleitung wird z.B. bei folgenden Schreibweisen durchgeführt:

http://www.example.com/short
http://www.example.com/Short
http://www.example.com/SHORT
http://www.example.com/short/
http://www.example.com/sHoRt/

Nicht aber bei Eingabe von:

http://www.example.com/short/test.de
http://www.example.com/sub/short