Nous avons vu dans l’article précédent comment mettre en place Cloudflare sur un domaine en général, et sur WordPress en particulier. J’avais également évoqué une limite dans cette configuration : mes services restaient accessibles en direct si l’on connaissait l’adresse IP.
Il y a deux façons de remédier à cela : soit n’autoriser que les IP de Cloudflare (je ne suis pas fan des protections par whitelist), soit authentifier Cloudflare par certificat (solution nettement plus robuste).
Initialement, en dehors du mTLS évidemment, je n’avais pas souhaité trop modifier mes configurations ni devenir trop dépendant de Cloudflare. De plus, CrowdSec est toujours en place et assure un niveau de protection supplémentaire. Jusqu’à présent, il était autosuffisant, je n’avais donc pas entrepris de mettre en place une authentification systématique, notamment par crainte d’un overhead inutile.
Mais il n’y a que les imbéciles qui ne changent pas d’avis, et j’ai d’ailleurs revu ma position. En effet, Cloudflare intègre de nombreux mécanismes de sécurité (WAF, rate limiting, protection DDoS, etc.). Si un attaquant contourne Cloudflare en accédant directement à votre serveur, ces protections deviennent inopérantes.
Pour limiter cela, Cloudflare propose un mécanisme : l’authentification des connexions via certificat.
Authenticated Origin Pulls level 1 : vérifier que c’est bien Cloudflare
Cloudflare permet d’authentifier ses connexions vers votre serveur via un certificat client. Cette fonctionnalité s’appelle Authenticated Origin Pulls.
Elle se configure dans : SSL/TLS > Serveur d’origine > Authenticated Origin Pulls.

Une fois activée, Cloudflare présentera un certificat client à votre serveur pour chaque requête.
Vous avez alors deux options :
- ne rien faire, c’est-à-dire accepter ce certificat sans le rendre obligatoire,
- exiger sa présence (recommandé).
Si vous choisissez de l’exiger, vous devez configurer votre serveur pour vérifier le certificat présenté par Cloudflare.
Par défaut, Cloudflare fournit un certificat CA global que vous pouvez utiliser :
wget https://developers.cloudflare.com/ssl/static/authenticated_origin_pull_ca.pemAttention toutefois : ce certificat est partagé par tous les clients Cloudflare. Vous vérifiez donc « Cloudflare » en général, mais pas « votre » Cloudflare en particulier.
Configuration Apache
VerifyClient require
SSLVerifyDepth 1
SSLCACertificateFile /usr/local/apache2/ssl/cloudflare/authenticated_origin_pull_ca.pemConfiguration Nginx
ssl_client_certificate /etc/nginx/ssl/cloudflare/authenticated_origin_pull_ca.pem;
ssl_verify_client on;
ssl_verify_depth 1;Configuration Traefik
Avec Traefik, l’authentification du client se configure via une TLSOption en utilisant la section clientAuth. Traefik recommande de renseigner la ou les autorités de certification dans clientAuth.caFiles, puis de forcer la vérification avec clientAuthType: RequireAndVerifyClientCert.
Exemple en configuration dynamique (dynamic_config) YAML :
tls:
options:
cloudflared:
clientAuth:
caFiles:
- /etc/traefik/certs/cloudflare/authenticated_origin_pull_ca.pem
clientAuthType: RequireAndVerifyClientCertSi vous déployez Traefik avec Docker, il faut passer par le provider file pour cette partie : les TLS options ne sont pas prises en charge par les providers basés sur des labels ou des tags.
Ensuite dans votre docker compose :
labels:
- traefik.enable=true
- traefik.http.routers.myapp.entrypoints=web
- traefik.http.routers.myapp.rule=Host("sub.domain.ltd")
- traefik.http.routers.myapp.tls.certresolver=letsencrypt
- traefik.http.routers.myapp.tls.options=cloudflared@fileÀ ce stade, vous avez la garantie que les connexions entrantes proviennent bien de Cloudflare.
Limites de cette approche
Authenticated Origin Pulls avec le certificat global permet :
- de bloquer les accès directs sans certificat,
- d’empêcher un client externe d’atteindre votre serveur sans passer par Cloudflare.
Mais cela ne permet pas :
- de distinguer votre compte Cloudflare d’un autre ;
- de mettre en place une authentification forte spécifique à votre infrastructure.
Pour aller plus loin, il est nécessaire de mettre en place votre propre chaîne de confiance avec des certificats dédiés.
Authenticated Origin Pulls level 2 : vérifier que c’est bien Cloudflare & votre CA
Cloudflare permet d’aller plus loin en utilisant un certificat client dédié, que vous contrôlez. Contrairement au niveau 1 (certificat partagé), vous êtes ici capable d’identifier précisément votre instance Cloudflare puisque vous l’aurez signé avec votre CA.
Au passage, un CA (Certificate Authority) est une autorité de confiance qui signe des certificats. En pratique, votre serveur ne fait pas confiance à un certificat « en lui-même », mais à l’autorité (CA) qui l’a signé. En utilisant votre propre CA, vous définissez explicitement qui est autorisé à se connecter.
Cloudflare vous permet de générer et d’uploader votre propre certificat, soit au niveau de la zone, soit par hostname. Pour des raisons de simplicité, j’ai choisi un certificat au niveau de la zone, mais la démarche est identique pour un hostname (il faudra simplement répéter l’opération pour chaque sous-domaine).
Création de votre CA et de votre certificat
Ceci est une adaptation / traduction de la documentation officielle de Cloudflare.
- Assurez-vous que le fichier d’extension de certificat
cert.v3.extest présent et bien configuré :
echo 'basicConstraints=CA:FALSE' >> ./cert.v3.ext- Exécutez la commande suivante pour générer une clé privée RSA de 4096 bits, utilisant le chiffrement AES-256. Saisissez une phrase secrète lorsque vous y êtes invité :
openssl genrsa -aes256 -out myrootca.key 4096- Créez le certificat racine de l’autorité de certification. Lorsque vous y êtes invité, renseignez les informations à inclure dans le certificat. Pour le champ Nom commun (
Common Name), utilisez le nom de domaine (domain.ltd) et non un nom d’hôte (sub.domain.ltd) :
openssl req -x509 -new -nodes -key myrootca.key -sha256 -days 1826 -out myrootca.crt- Créez une demande de signature de certificat (CSR). Quand vous y êtes invité, renseignez les informations à inclure dans la demande. Pour le champ Nom commun (
Common Name), utilisez un nom d’hôte (servername.domain.ltd) :
openssl req -new -nodes -newkey rsa:4096 -keyout authenticated_origin_pull.key -out authenticated_origin_pull.csr- Signez le certificat en utilisant les fichiers
myrootca.keyetmyrootca.crtcréés lors des étapes précédentes :
openssl x509 -req \
-in authenticated_origin_pull.csr \
-CA myrootca.crt \
-CAkey myrootca.key \
-CAcreateserial \
-out authenticated_origin_pull.crt \
-days 730 \
-sha256 \
-extfile ./cert.v3.extUpload dans Cloudflare

Rendez-vous dans l’interface Cloudflare pour uploader votre certificat :
- Certificat :
authenticated_origin_pull.crt - Clé privée :
authenticated_origin_pull.key

Vous aurez remarqué que j’ai un peu eu la main lourde sur la durée de vie des certificats… Faites ce que je dis, pas ce que je fais 😉.
Vous devez ensuite adapter votre configuration serveur pour utiliser votre propre CA, myrootca.crt dans mon cas (et non plus celle de Cloudflare). Par exemple ma configuration apache devient :
SSLCACertificateFile /usr/local/apache2/ssl/cloudflare/myrootca.crtÀ ce stade, vous ne vérifiez plus seulement que la requête provient de Cloudflare, mais qu’elle provient de votre Cloudflare. Cela empêche tout autre client Cloudflare d’accéder à votre infrastructure, même en passant par le réseau Cloudflare.
Pour tester
Sans Authenticated Origin Pulls, la requête suivante fonctionne :
curl -v https://sub.domain.ltd --resolve sub.domain.ldt:443:<IP_SERVER>Avec, vous devez avoir une erreur :
curl: (56) OpenSSL SSL_read: OpenSSL/3.5.5: error:0A00045C:SSL routines::tlsv13 alert certificate required, errno 0







