Last updated on 15. August 2025
Wenn Cloudflare als Reverse-Proxy vorgeschaltet ist, zeigt Nginx in den Logs standardmäßig nur die IP-Adressen der Cloudflare-Server an, nicht die tatsächliche Besucher-IP. Um eine korrekte Auswertung von Zugriffen, Sicherheitsmaßnahmen wie IP-Blocking und genaue Analyse-Statistiken zu ermöglichen, müssen die offiziellen Cloudflare-IP-Bereiche mit der Direktive set_real_ip_from in der Nginx-Konfiguration hinterlegt werden. Da sich diese IP-Listen von Zeit zu Zeit ändern, ist es sinnvoll, die Aktualisierung vollständig zu automatisieren … beispielsweise mit einem Cronjob, der die aktuellen IPv4- und IPv6-Adressen regelmäßig abruft und einbindet.
Prinzip
Nur im globalen http-Block der nginx.conf stehen:
include /etc/nginx/conf.d/realip.conf; real_ip_header CF-Connecting-IP; real_ip_recursive on;
Die Datei /etc/nginx/conf.d/realip.conf enthält ausschließlich set_real_ip_from-Zeilen mit den Cloudflare-CIDRs.
Ein Script lädt die offiziellen IPv4/IPv6-Listen, erzeugt die Datei neu, testet die Config und führt bei Erfolg ein Reload aus. Wenn sich nichts geändert hat, passiert nichts.
Offizielle IP-Quellen: cloudflare.com/ips
1) Script anlegen
Datei /usr/local/sbin/update-cloudflare-realip.sh erstellen und ausführbar machen:
sudo tee /usr/local/sbin/update-cloudflare-realip.sh >/dev/null <<'EOF'
#!/usr/bin/env bash
set -euo pipefail
OUT_FILE="/etc/nginx/conf.d/realip.conf"
TMP_FILE="$(mktemp)"
LOCK_FILE="/var/lock/update-cf-realip.lock"
IPS_V4_URL="https://www.cloudflare.com/ips-v4"
IPS_V6_URL="https://www.cloudflare.com/ips-v6"
# Nur eine Instanz gleichzeitig
exec 9>"${LOCK_FILE}"
flock -n 9 || { echo "Another update is running."; exit 0; }
# Cloudflare-IP-Listen abrufen
curl -fsS "${IPS_V4_URL}" > /tmp/cf-ips-v4.txt
curl -fsS "${IPS_V6_URL}" > /tmp/cf-ips-v6.txt
# Temporäre Datei mit set_real_ip_from-Zeilen erzeugen
{
echo "# This file is managed by update-cloudflare-realip.sh"
echo "# Source: ${IPS_V4_URL} / ${IPS_V6_URL}"
echo "# Generated: $(date -u +'%Y-%m-%dT%H:%M:%SZ')"
echo
while read -r cidr; do
[[ -z "$cidr" ]] && continue
echo "set_real_ip_from ${cidr};"
done < /tmp/cf-ips-v4.txt
while read -r cidr; do
[[ -z "$cidr" ]] && continue
echo "set_real_ip_from ${cidr};"
done < /tmp/cf-ips-v6.txt
} > "${TMP_FILE}"
# Keine Änderung? → Beenden
if [[ -f "${OUT_FILE}" ]] && diff -q "${TMP_FILE}" "${OUT_FILE}" >/dev/null 2>&1; then
rm -f "${TMP_FILE}"
exit 0
fi
# Neue Datei übernehmen, testen und Nginx neu laden
install -o root -g root -m 0644 "${TMP_FILE}" "${OUT_FILE}"
rm -f "${TMP_FILE}"
if nginx -t; then
systemctl reload nginx
else
echo "nginx test failed, restoring previous config."
exit 1
fi
EOF
Wichtig: Das Script schreibt bewusst nicht real_ip_header CF-Connecting-IP; oder real_ip_recursive on; in die Datei. Diese Direktiven gehören in den globalen http-Block der nginx.conf.
2) Cronjob einrichten
Tägliche Ausführung um 03:17 Uhr (mit Logging):
echo '17 3 * * * root /usr/local/sbin/update-cloudflare-realip.sh >/var/log/update-cf-realip.log 2>&1' | sudo tee /etc/cron.d/update-cf-realip
Die Cloudflare-Netze ändern sich selten, täglich oder wöchentlich ist beides sinnvoll.
Danach Ausführungsrechte setzen:
sudo chmod +x /usr/local/sbin/update-cloudflare-realip.sh
3) Funktionstest
Manuell starten:
sudo /usr/local/sbin/update-cloudflare-realip.sh
Erwartete Ausgabe:
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok nginx: configuration file /etc/nginx/nginx.conf test is successful
Neue Netze prüfen:
nginx -T | grep set_real_ip_from
Und sicherstellen, dass im http-Block nur diese drei Zeilen stehen:
include /etc/nginx/conf.d/realip.conf; real_ip_header CF-Connecting-IP; real_ip_recursive on;
Optional
Wer strikt über Cloudflare ausliefern will, kann auf Firewall-Ebene Port 80/443 nur für die Cloudflare-CIDRs erlauben und direkten Zugriff blockieren.
Hinweis:: Wenn dir dieser Beitrag gefallen oder geholfen hat, kannst du mich gerne mit einer kleinen Unterstützung motivieren 😊
₿/Ξ: Donate with Bitcoin
Address: bc1qt7wc6jfth4t2szc2hp6340sqp3y0pa9r3ywgrr
Schreib den ersten Kommentar