TL;DR: Einfach den fettgedruckten Anweisungen folgen um mithilfe von mod_remoteip die IP von Besuchern hinter einem Cloudflare Proxy auf einem Apache 2 Webserver wiederherzustellen.
Technischer Hintergrund
Wenn der Zugriff auf eine Website mit einem Proxy-Server erfolgt, sieht der Webserver die IP des Proxy als Urpsrungs-IP der Anfrage. Daher würden sich auch nur die IPs des Proxy in den Log-Dateien finden. Spezielle „Require ip“ Zugriffsregeln in den vHost- oder .htaccess-Dateien würden ebenfalls nur die IP des Proxy sehen. Als dieser Blog auf eine Lastverteilung von Cloudflare umgestellt wurde, hatte ich genau das Problem. Glücklicherweise schicken die meisten Proxy-Server die IPs der Besucher oft im Request-Header direkt mit. Dies erfolgt üblicherweise in den Headern „X-Forwarded-For“ oder „HTTP_CLIENT_IP“. Es wäre jedoch fahrlässig die in den Headern übersandten IPs ohne Verifizierung zu verwenden. Der Grund: Die Headerinformationen können mit Leichtigkeit gefälscht werden. Weiter kann es sein, dass in den Header-Informationen mehr als eine IP aufgelistet sind. Nämlich dann, wenn die Anfrage durch mehrere Proxies gehandhabt wurde. Dies ist beispielsweise bei Cloudflare öfters der Fall. Eine einfache Lösung für das Problem ist das Apache 2 Modul mod_remoteip. Das Modul kümmert sich eigenständig um die korrekte Formatierung und überschreibt die IP der Anfrage nur dann mit der vom Proxy-Server übermittelten Ursprungs-IP, wenn der Proxy auf einer Liste vertrauenswürdiger Quellen zu finden ist.
Installation und Konfiguration
Die Serverumgebung, die ich für dieses Tutorial verwende basiert auf einem Apache-Server (Version 2.4.) mit Ubuntu (Version 24.04.) als Betriebssystem. Dennoch sollte die Anleitung auch für ältere und zukünftige Versionen von Ubuntu- bzw. Debian-Systemen funktionieren. Dieses Tutorial funktioniert mit Anpassungen generell für alle Anwendungen, ist jedoch speziell für die Nutzung hinter Cloudflare geschrieben.
Um mod_remoteip auf dem Webserver zu aktivieren reicht ein einfaches Kommando auf der Kommandozeile:
sudo a2enmod remoteip
Damit das Modul korrekt funktioniert, muss dieses jedoch zunächst für den jeweiligen Anwendungszweck konfiguriert werden. Dazu wird zunächst im Arbeitsverzeichnis von Apache eine Konfigurationsdatei namens remoteip.conf angelegt. Die Datei wird genutzt um die Liste vertrauenswürdiger Proxies festzulegen und Apache mitzuteilen welcher Header die IP des Besuchers enthält. Cloudflare benutzt einen speziellen Header namens CF-Connecting-IP.
cd /etc/apache2/conf-available/
nano remoteip.conf
Eine Minimalkonfiguration enthält zum Einen den genauen Header, den mod_remoteip verwenden soll um die Ursprungs-IP umzuschreiben, sowie die RemoteIPTrustedProxy Direktive mit der Angabe einer vertrauenswürdigen IP-Adresse des Proxy-Servers. Eine Beispielkonfiguration könnte wie folgt aussehen:
RemoteIPHeader X-Forwarded-For
RemoteIPTrustedProxy 192.168.0.1
RemoteIPTrustedProxy 192.168.0.2
Für Cloudflare gibt es sehr viele IP-Adressbereiche, die als vertrauenswürdig deklariert werden müssen. Für genau so einen Fall gibt es die Möglichkeit mit der Direktive RemoteIPInternalProxyList alle als vertrauenswürdig eingestuften Adressbereiche in eine externe Datei auszulagern. Genau diese Funktionalität werde ich hier verwenden. Die korrekte Konfigurationsdatei für Cloudflare muss folgendes beinhalten:
RemoteIPHeader CF-Connecting-IP
RemoteIPInternalProxyList /etc/apache2/conf-available/trusted-proxies.lst
Dabei ist /etc/apache2/conf-available/ der Pfad, den ich für die Datei mit der Liste namens trusted-proxies.lst verwende. Selbstverständlich kann die Liste auch an einem beliebigen, anderen Ort gespeichert werden. In dem Fall müssen die Pfadangaben in den folgenden Anweisungen jedoch entsprechend angepasst werden. Diese Datei muss nun natürlich noch erstellt werden und mit allen IPv4- und IPv6-Adressen von Cloudflare gefüllt werden.
cd /etc/apache2/conf-available/
nano trusted-proxies.lst
Nachfolgend sind alle IP-Adressbereiche, die Cloudflare aktuell verwendet, aufgeführt. Diese können sich natürlich mit der Zeit ändern und wurden zum Zeitpunkt der Erstellung dieses Artikels von der offiziellen Website [2] abgerufen.
173.245.48.0/20
103.21.244.0/22
103.22.200.0/22
103.31.4.0/22
141.101.64.0/18
108.162.192.0/18
190.93.240.0/20
188.114.96.0/20
197.234.240.0/22
198.41.128.0/17
162.158.0.0/15
104.16.0.0/13
104.24.0.0/14
172.64.0.0/13
131.0.72.0/22
2400:cb00::/32
2606:4700::/32
2803:f800::/32
2405:b500::/32
2405:8100::/32
2a06:98c0::/29
2c0f:f248::/32
Die neue Konfigurationsdatei für mod_remoteip muss aktiviert werden, damit Apache 2 diese auch tatsächlich verwendet:
cd /etc/apache2/conf-available/
sudo a2enconf remoteip
Die neue Konfiguration wird mit dem Kommando sudo apache2ctl configtest getestet und – sofern keine Fehler angezeigt werden – aktiviert.
sudo systemctl reload apache2
Der Apache schreibt jetzt alle IP-Adressen so um, dass die die wiederhergestellte Ursprungs-IP der Anfrage enthalten. Das Format der Log- und .htaccess-Dateien muss nicht extra angepasst werden.
Zukunftssicherheit
Es ist möglich, dass Cloudflare neue IP-Adressbereiche hinzufügt oder entfernt. Alle aktuell verwendeten IPs finden sich auf der offiziellen Website [2]. Da ich keine Lust habe die Adressbereiche regelmäßig zu überprüfen, habe ich mir ein kleines PHP-Skript geschrieben, dass die Adressen auf ihre Aktualität hin prüft und bei Bedarf automatisch eine neue Liste direkt auf meinem Server erstellt. Diese Liste kann tagesaktuell und kostenlos jederzeit unter https://api.baltic-lab.com/trusted-proxies.lst abgerufen werden. Mit dem Kommandozeilen-Tool Wget und einem CronJob kann die Liste automatisch aktualisiert werden. Bei der Erstellung sollte beachtet werden, dass wget seine Ausgaben standardmäßig auf stderr anstatt stdout schreibt. Möchte man die Ausgaben unterdrücken, muss man also „&>“ hinter dem Kommando einfügen.
crontab -e
Folgende Zeile in die Crontab-Datei einfügen um einmal täglich um Mitternacht die jeweils aktuelle Liste zu installieren:
0 0 * * * wget -P /etc/apache2/conf-available/ https://api.baltic-lab.com/trusted-proxies.lst
Sofern anstatt der von mir gezeigten Pfade ein Anderer verwendet wurde, muss der Pfad in der Crontab-Datei natürlich angepasst werden!
Links and Sources:
[1] Apache Module mod_remoteip, Apache: https://httpd.apache.org/
[2] Restoring original visitor IPs, Cloudflare: https://developers.cloudflare.com/
[3] IP ranges, Cloudflare: https://www.cloudflare.com/ips/
S. Westerhold: IP-Adressen hinter Proxy wiederherstellen (2024), in: Baltic Labor Blog für Hochfrequenz- und Messtechnik, ISSN (Online): 2751-806X, URL: https://baltic-labor.de/2024/12/ip-adressen-hinter-proxy-wiederherstellen/ (Stand: 14.01.2025).
- Automatische WebP-Konvertierung ohne Plugin - 14.01.2025
- UFW Firewall Regeln mit (dynamischen) DNS Hostnamen - 14.01.2025
- IP-Adressen hinter Proxy wiederherstellen - 26.12.2024