Cloudflare před serverem: skutečná IP návštěvníků a zabezpečení originu
Jak v nginx obnovit skutečnou IP za Cloudflare proxy, nastavit SSL režim Full (strict), Origin certifikát a zavřít server pro přístup mimo Cloudflare.
Když doménu přepnete na Cloudflare s proxy (oranžový mráček v DNS), návštěvníci se připojují k Cloudflare a ten pak k vašemu serveru. Získáte CDN, ochranu proti DDoS a WAF – ale také pár nových problémů: v logu vidíte jen IP Cloudflare, rate limiting nefunguje a útočník, který zná IP serveru, může Cloudflare obejít.
Problém: všichni mají IP Cloudflare
V access.log nginx uvidíte adresy z rozsahů Cloudflare. Skutečnou IP návštěvníka posílá Cloudflare v hlavičce CF-Connecting-IP (a také v X-Forwarded-For). Nginx ji umí převzít modulem ngx_http_realip_module, který je v balíčku Ubuntu zkompilovaný.
Konfigurace real_ip
Vytvořte /etc/nginx/conf.d/cloudflare-realip.conf:
# IPv4 rozsahy Cloudflare
set_real_ip_from 173.245.48.0/20;
set_real_ip_from 103.21.244.0/22;
set_real_ip_from 103.22.200.0/22;
set_real_ip_from 103.31.4.0/22;
set_real_ip_from 141.101.64.0/18;
set_real_ip_from 108.162.192.0/18;
set_real_ip_from 190.93.240.0/20;
set_real_ip_from 188.114.96.0/20;
set_real_ip_from 197.234.240.0/22;
set_real_ip_from 198.41.128.0/17;
set_real_ip_from 162.158.0.0/15;
set_real_ip_from 104.16.0.0/13;
set_real_ip_from 104.24.0.0/14;
set_real_ip_from 172.64.0.0/13;
set_real_ip_from 131.0.72.0/22;
# IPv6
set_real_ip_from 2400:cb00::/32;
set_real_ip_from 2606:4700::/32;
set_real_ip_from 2803:f800::/32;
set_real_ip_from 2405:b500::/32;
set_real_ip_from 2405:8100::/32;
set_real_ip_from 2a06:98c0::/29;
set_real_ip_from 2c0f:f248::/32;
real_ip_header CF-Connecting-IP;
Rozsahy se mohou změnit. Aktuální seznam vždy najdete na https://www.cloudflare.com/ips-v4 a https://www.cloudflare.com/ips-v6. Proto je lepší soubor generovat skriptem:
#!/usr/bin/env bash
set -euo pipefail
OUT=/etc/nginx/conf.d/cloudflare-realip.conf
V4=$(curl -fsS https://www.cloudflare.com/ips-v4)
V6=$(curl -fsS https://www.cloudflare.com/ips-v6)
[ -n "$V4" ] && [ -n "$V6" ] || { echo "Prázdný seznam IP" >&2; exit 1; }
TMP=$(mktemp)
{
for ip in $V4 $V6; do
echo "set_real_ip_from $ip;"
done
echo "real_ip_header CF-Connecting-IP;"
} > "$TMP"
cp "$OUT" "$OUT.bak" 2>/dev/null || true
install -m 644 "$TMP" "$OUT" && rm -f "$TMP"
nginx -t && systemctl reload nginx
Spouštějte ho třeba jednou týdně timerem nebo cronem. Přiřazení V4=$(curl -f ...) při chybě stahování díky set -e skript ukončí, takže se původní konfigurace nepřepíše. Před reloadem navíc proběhne nginx -t.
Důležité: set_real_ip_from musí obsahovat jen důvěryhodné rozsahy. Kdybyste hlavičce věřili od kohokoli, útočník si podvrhne libovolnou IP.
Ověření
sudo nginx -t && sudo systemctl reload nginx
sudo tail -f /var/log/nginx/access.log
Otevřete web a v logu byste měli vidět svou veřejnou IP, ne adresu Cloudflare. Proměnná $remote_addr teď obsahuje skutečnou IP, takže fungují i limit_req, allow/deny a aplikace dostává správnou adresu přes X-Real-IP.
SSL režim: vždy Full (strict)
V Cloudflare (SSL/TLS → Overview) jsou režimy:
| Režim | Prohlížeč → CF | CF → server | Hodnocení |
|---|---|---|---|
| Off | HTTP | HTTP | nepoužívat |
| Flexible | HTTPS | HTTP | provoz k serveru nešifrovaný, riziko smyček přesměrování |
| Full | HTTPS | HTTPS, certifikát se neověřuje | lepší, ale ne ideální |
| Full (strict) | HTTPS | HTTPS s platným certifikátem | doporučeno |
Režim Flexible je častou příčinou chyby ERR_TOO_MANY_REDIRECTS: server přesměruje HTTP na HTTPS, Cloudflare se k němu ale připojuje přes HTTP, a tak dokola.
Certifikát na serveru
Pro Full (strict) potřebujete na serveru platný certifikát. Dvě možnosti:
- Let’s Encrypt přes certbot – funguje i pro přístup mimo Cloudflare.
- Cloudflare Origin CA – vygenerujete v SSL/TLS → Origin Server, platnost až 15 let. Důvěřuje mu jen Cloudflare, takže je vhodný, když server nikdy nebude dostupný přímo.
ssl_certificate /etc/ssl/cloudflare/origin.pem;
ssl_certificate_key /etc/ssl/cloudflare/origin.key;
Zavřete origin pro všechny ostatní
Pokud útočník zjistí skutečnou IP serveru (ze starých DNS záznamů, MX záznamu, hlaviček e-mailů), může Cloudflare obejít. Ochrana: porty 80 a 443 povolte jen z rozsahů Cloudflare.
for ip in $(curl -fsS https://www.cloudflare.com/ips-v4) $(curl -fsS https://www.cloudflare.com/ips-v6); do
sudo ufw allow from "$ip" to any port 80,443 proto tcp
done
sudo ufw delete allow 'Nginx Full'
sudo ufw status numbered
Silnější varianty jsou Authenticated Origin Pulls (Cloudflare se prokazuje klientským certifikátem, nginx ověřuje ssl_verify_client) nebo Cloudflare Tunnel (cloudflared), kdy server nemá otevřený žádný příchozí port.
Na co si dát pozor
- E-mail na stejné IP – MX záznam nelze proxovat, takže prozradí IP serveru. Ideálně provozujte poštu jinde.
- SSH a jiné porty – proxy Cloudflare funguje jen pro HTTP(S) na podporovaných portech. Pro SSH použijte A záznam bez proxy nebo připojení přes IP.
- Cache dynamických stránek – Cloudflare ve výchozím stavu necachuje HTML, ale pravidla typu „Cache Everything“ mohou cachovat i přihlášené stránky. Pozor na ně.
- Fail2ban – i s real_ip blokuje IP na firewallu, kam ale provoz přichází z Cloudflare. Pro webové útoky použijte WAF pravidla v Cloudflare.
Shrnutí
set_real_ip_from+real_ip_header CF-Connecting-IPa pravidelná aktualizace rozsahů.- SSL režim Full (strict) s certifikátem na serveru.
- Porty 80/443 jen pro Cloudflare, případně Tunnel.