Blog & Astuces

Empêcher l'accès direct à un site web protégé par Cloudflare

Empêcher l'accès direct à un site web protégé par Cloudflare

Tuto

Si vous utilisez Cloudflare pour protéger votre site web, vous devez savoir que le service agit comme un proxy inverse en se connectant à votre serveur, mais vos visiteurs se connectent au réseau de Cloudflare pour atteindre votre site.

La problématique sur laquelle va porter cette article est la suivante : si un attaquant connait l'adresse IP de votre serveur, il pourra s'y connecter directement, outrepassant la protection offerte par Cloudflare. Il pourra ainsi accéder directement à votre site web sans cette protection.

Comment ? Il suffit à l'attaquant de modifier son fichier hosts pour pointer vers l'adresse IP du serveur pour outrepasser les DNS qui pointent vers les serveurs de Cloudflare, par exemple

Je vais vous montrer ici plusieurs façons de faire pour protéger votre serveur et votre site web de cette problématique de sécurité

Protection via pare-feu

Cloudflare alimente une API qui propose deux listes (une pour IPV4, l'autre pour IPV6) contenant les différentes ranges d'IPs qui appartiennent au réseau. Il suffit d'ajouter des règles de pare-feu pour exclure toute IP qui ne fait pas partie de ces listes.

Les listes sont disponibles aux adresses suivantes : https://www.cloudflare.com/ips-v4/ et https://www.cloudflare.com/ips-v6/

Par exemple, si vous utilisez le pare-feu UFW, vous pouvez vous inspirer de ce script Bash pour effectuer ces ajouts de règles automatiquement :

#!/bin/sh

curl -L -s https://www.cloudflare.com/ips-v4/ -o /tmp/cf_ips
echo "" >> /tmp/cf_ips
curl -L -s https://www.cloudflare.com/ips-v6/ >> /tmp/cf_ips

# Allow all traffic from Cloudflare IPs (no ports restriction)
for NUM in $(ufw status numbered | grep 80 | awk -F"[][]" '{print $2}' | tr --delete [:blank:] | sort -rn); do
    yes | ufw delete $NUM
done
for NUM in $(ufw status numbered | grep 443 | awk -F"[][]" '{print $2}' | tr --delete [:blank:] | sort -rn); do
    yes | ufw delete $NUM
done
for cfip in `cat /tmp/cf_ips`; do ufw allow from $cfip to any port 80 comment 'Cloudflare IP'; done
for cfip in `cat /tmp/cf_ips`; do ufw allow from $cfip to any port 443 comment 'Cloudflare IP'; done

ufw reload

Il faut que votre pare-feu bloque les connexions entrantes par défaut pour que ce script fonctionne.

Ce script supprime d'abord les anciennes règles correspondant aux ports 80 et 443 puis ajoute de nouvelles règles autorisant les adresses IP de Cloudflare uniquement.

Vous pouvez changer les ports 80 et 443 selon ceux qui correspondent aux ports sur lesquels écoute votre serveur. Ajoutez également les règles que vous voulez avoir en plus (par exemple pour autoriser les adresses IP locales à accéder à votre sereur).

Lancez ce script en mode super-utilisateur pour effectuer la mise à jour automatique des règles.

Ce script peut aussi être mis en place sous forme d'une tâche Cron, afin que les règles se mettent à jour automatiquement, étant donné que les listes d'IP peuvent changer régulièrement.

Protection via Nginx

Si vous utilisez Nginx pour exposer votre site web, il est possible de se baser sur le même type de réglage pour refuser toute connexion d'une IP n'appartenant pas à Cloudflare, en se basant sur la même liste.

Voici un script Bash qui effectue ce traitement automatiquement :

#!/bin/bash
cloudflare_real_ip_conf='CHEMIN_VERS_LE_FICHIER_DE_CONFIGURATION_A_CREER'

echo "# Ce fichier est automatiquement mis à jour. Ne pas ajouter de config à ce fichier manuellement, car elle sera effacée." > ${cloudflare_real_ip_conf};
echo "# Cloudflare" >> ${cloudflare_real_ip_conf};

for i in `curl -L -sk https://www.cloudflare.com/ips-v4/`; do
        echo "set_real_ip_from $i;" >> ${cloudflare_real_ip_conf};
done

for i in `curl -L -sk https://www.cloudflare.com/ips-v6/`; do
        echo "set_real_ip_from $i;" >> ${cloudflare_real_ip_conf};
done

echo "" >> ${cloudflare_real_ip_conf};
echo "# Utiliser les IPS" >> ${cloudflare_real_ip_conf};
echo "real_ip_header CF-Connecting-IP;" >> ${cloudflare_real_ip_conf};

echo "Config OK"

Ce script crée un fichier de configuration dans le fichier dont le chemin est indiqué dans la variable "cloudflare_real_ip_conf". De la même manière, il est possible de mettre en place le script sous la forme d'une tâche Cron.

Il faut ensuite inclure ce fichier de configuration dans votre fichier de configuration principal Nginx comme suit, avec la directive include :

(...le début de votre configuration)
http {
    server {
        include CHEMIN_VERS_LE_FICHIER_DE_CONFIGURATION;
    }
}

Protection avec le certificat de Cloudflare

Les serveurs de Cloudflare, en se connectant à votre serveur, envoient un certificat. Il est possible de vérifier ce certificat pour authentifier qu'il s'agit bien de Cloudflare qui se connecte à votre site web. Cette technique est appelée "Authenticated Origin Pulls".

Pour mettre en place cette protection, il faut que le mode Full ou Full (Strict) de SSL/TLS soit activé dans le dashboard de Cloudflare pour votre site, sinon cela ne fonctionnera pas :

Capture d'écran de Cloudflare présentant le mode SSL/TLS

Il faut aussi activer le mode Authenticated Origin Pull dans le Dashbaord :

Capture d'écran de Cloudflare montrant l'activation du mode Authenticated Origin Pull

Pour cela, vous pouvez télécharger le certificat client de Cloudflare à l'adresse suivante : https://developers.cloudflare.com/ssl/static/authenticated_origin_pull_ca.pem

Ensuite, enregistrez le sur votre serveur

Vous devez ensuite activer la vérification du certificat. Si votre site web fonctionne derrière nginx, vous devez configurer cela comme suit :

(...le début de votre configuration)
http {
    server {
        ssl_client_certificate /etc/nginx/certs/cloudflare.crt;
        ssl_verify_client on;
    }
}

Par exemple si le certificat est à l'emplacement /etc/nginx/certs/cloudflare.crt (il faudra donc renommer l'extension du certificat en .crt)

Pour Apache, il faut configurer comme suit :

SSLVerifyDepth 1
SSLVerifyClient require
SSLCACertificateFile /path/to/origin-pull-ca.pem

Avec le chemin du certificat à modifier.

Cloudflare Tunnel

Il est également possible d'utiliser Cloudflare Tunnel avec Cloudflared, ce qui empêchera votre serveur d'être appelé directement. Plus d'infos ici : https://developers.cloudflare.com/cloudflare-one/connections/connect-networks/

Conclusion

Mettre en place ce type de protections est très important si vous utilisez Cloudflare, sinon la protection qu'offre le service pourra s'avérer inutile, surtout si vous utilisez le WAF (Web Application Firewall) proposé par Cloudflare.

Je vous conseille personnellement de mettre en place, si possible, les 3 premières protections que j'ai présentées. Vous pouvez aussi voir du côté de Cloudflare Tunnel si cela vous intéresse. D'autres protections existent bien sûr, présentées sur la documentation officielle de Cloudflare : https://developers.cloudflare.com/fundamentals/basic-tasks/protect-your-origin-server/.

Commentaires