Sécurité Nginx : configurer le serveur pour WordPress pro

Quand un site WordPress devient “pro”, la sécurité ne peut plus rester un sujet périphérique. On ne parle plus seulement d’un plugin “qui désactive l’affichage de version”, mais d’une posture globale. Côté Nginx, le serveur est souvent la première ligne de défense, celle qui filtre les requêtes avant même que WordPress et ses plugins ne voient quoi que ce soit. Et c’est exactement là que le gain est le plus rentable: moins de trafic inutile, moins d’expositions, moins de surfaces d’attaque.

Je vois régulièrement le même scénario: le thème est bon, la sauvegarde est en place, mais la configuration Nginx laisse passer trop de choses. Un panneau d’admin exposé, des méthodes HTTP acceptées à tort, un mauvais découpage des chemins, des règles trop faibles sur les en-têtes, et parfois une version de PHP servie sans garde-fous. Résultat, soit le site subit des tentatives brutales, soit des scans “silencieux” qui finissent par casser quelque chose de manière indirecte.

Dans ce qui suit, je vais partir d’une base Nginx propre, puis je montrerai comment durcir la configuration pour WordPress, sans casser le fonctionnement. L’objectif est concret: protéger sans rendre l’administration pénible.

Commencer par les prérequis: le cadre de sécurité avant Nginx

Avant d’écrire des directives, je vérifie trois points, parce qu’ils changent la manière de configurer Nginx.

D’abord, TLS. Si le site n’a pas de HTTPS, aucune optimisation Nginx ne compensera les risques liés au transport. Ensuite, le mode de déploiement de WordPress: est-il en sous-dossier (/blog) ou à la racine (/)? Est-ce que vous utilisez un reverse proxy, par exemple devant Nginx avec un load balancer? Enfin, PHP: WordPress exécute le code PHP, donc la partie PHP doit être raccordée correctement, avec un fastcgi param propre.

La sécurité Nginx se joue aussi sur la discipline: une configuration lisible, découpée en fichiers de site et en règles partagées, plutôt qu’un gros bloc copié collé. Sur des environnements pro, on a rarement une seule application Nginx. Travailler proprement évite les “surprises” lors des mises à jour.

Hardening de base: limiter ce que Nginx révèle et accepte

La première couche consiste à réduire les informations renvoyées et à refuser des comportements inutiles.

WordPress n’a pas besoin que Nginx affiche son doigt. Vous pouvez désactiver certains en-têtes, contrôler la gestion des erreurs, et imposer des règles strictes de cache. Par exemple, pour des pages dynamiques, vous ne voulez pas que des erreurs 404 ou 500 soient mises en cache de façon agressive par un navigateur ou par un proxy intermédiaire.

Côté méthodes HTTP, WordPress utilise majoritairement GET, HEAD, POST. Accept er des méthodes comme TRACE ou des comportements étranges augmente les risques sans bénéfice. Dans les environnements où Nginx est devant un WAF ou un reverse proxy, on adapte ces règles, mais dans la plupart des cas un filtrage simple aide.

Je fais aussi attention au “trop de sécurité” qui casse. Bloquer des chemins sans réfléchir peut empêcher des fonctionnalités attendues, comme l’accès aux médias, aux flux, ou aux endpoints d’API. La sécurité utile se construit en ciblant les chemins et les comportements, pas en durcissant à l’aveugle.

Séparer les fichiers sensibles: accès, listes de répertoires, et chemins à surveiller

WordPress stocke des éléments qui doivent rester inaccessibles depuis l’extérieur, même s’ils “existent”.

Typiquement, je traite trois catégories de chemins.

1) Les fichiers de configuration et d’installation, par exemple les fichiers de type .env, .htaccess (même si Apache), et les fichiers internes qui ne devraient pas être servis au public.

2) Les répertoires qui ne doivent pas être listés, avec autoindex désactivé. 3) Les fichiers “admin” ou endpoints internes, qui doivent être accessibles uniquement aux bonnes routes et avec des garde-fous.

Nginx a une force particulière ici: il sait refuser avant de laisser WordPress entrer en jeu. Et c’est souvent le bon choix, parce que réduire la charge applicative aide aussi la sécurité (moins de logs WordPress remplis par du bruit, moins de charge sur l’application).

Journalisation: sécurité et maintenance se gagnent à l’équilibre

Une config pro ne s’arrête pas aux directives qui “bloquent”. Elle inclut aussi la façon dont vous observez.

Je recommande de journaliser intelligemment: accès avec un format adapté, erreurs séparées. Mais je mets un frein sur l’excès. Sur des sites ciblés, un flux d’attaques peut générer des milliers de lignes par minute. Si vous journalisez tout au millimètre, vous transformez la sécurité en problème d’exploitation, rotation de logs, consommation disque, et difficulté à remonter des événements utiles.

Sur des setups Nginx bien tenus, on peut aussi filtrer ce qui alimente les logs. Sans tomber dans l’aveuglement, le but est d’éviter que les tentatives automatisées noient ce qui compte: erreurs applicatives réelles, refus d’accès pertinents, et incidents.

La règle d’or côté WordPress: Nginx doit servir proprement les médias, puis laisser WordPress gérer le reste

Le pattern classique est: servir les fichiers statiques tels quels, puis envoyer les routes dynamiques à WordPress.

En pratique, ça veut dire que /wp-content/ doit fonctionner comme attendu (images, thèmes, extensions), que les requêtes vers /wp-admin/ vont au front contrôleur (PHP), et que les autres chemins peuvent être traités par WordPress selon les règles de permaliens.

image

Le piège fréquent, ce sont les règles trop agressives sur les location Nginx. Un try_files mal configuré peut envoyer des routes statiques à PHP, ou à l’inverse empêcher l’accès aux médias. Ça a un impact direct sur la sécurité: si des erreurs inattendues sont générées, WordPress logge et parfois tente des choses supplémentaires. Un serveur stable réduit aussi les comportements imprévus.

Exemple de durcissement Nginx: configuration cible pour WordPress

Je décris ci-dessous les objectifs et les logiques. La configuration exacte dépend du chemin de WordPress, du socket PHP-FPM, et de l’architecture (reverse proxy ou non). Mais les principes restent constants.

Rappels utiles sur la structure Nginx

En environnement pro, je sépare souvent:

    un fichier de site (vhost) un fichier “include” partagé pour les règles génériques un fichier “PHP” si j’ai plusieurs stacks

Comme ça, vous durcissez une fois, vous réutilisez.

Directives de sécurité et gestion des chemins

Vous voulez:

image

    masquer la signature Nginx quand c’est possible, éviter l’indexing, bloquer des extensions et fichiers non destinés au web, refuser les requêtes qui tentent de lire des fichiers “cachés”.

Nginx ne comprend pas WordPress comme application, donc vous devez lui donner les bonnes routes, et lui interdire le reste. Un exemple simple: les fichiers commençant par un point dans le projet WordPress ne devraient pas être servis, sauf exceptions à justifier.

Je fais aussi attention aux options qui ressemblent à du hardening mais qui cassent des fonctionnalités. Par exemple, selon la manière dont votre site génère des fichiers, bloquer tout accès aux fichiers .xml ou .json peut casser des endpoints attendus. Pour un site WordPress standard, je privilégie le ciblage par type de fichier réellement sensible plutôt que par “tout ce qui finit par X”.

image

Contrôler la surface des requêtes: taille, limites, et méthodes

Un serveur exposé à Internet subit des tentatives de chargement: scripts lents, payloads énormes, requêtes répétées. Une partie de la sécurité consiste à fixer des bornes.

La limitation de taille de corps (client_max_body_size) est importante. WordPress gère des uploads, donc vous devez dimensionner la limite en fonction des besoins réels. Sur un site pro, les images font rarement plusieurs centaines de Mo, donc une limite raisonnable limite l’impact des tentatives abusives.

Ensuite, j’impose une gestion cohérente des méthodes. L’objectif n’est pas d’être “pur”, mais de réduire les possibilités inutiles. GET et POST sont les piliers. HEAD est utile pour les contrôles. Les autres méthodes peuvent être refusées selon votre contexte.

Endpoint de sécurité: durcir l’accès à wp-admin et wp-login sans casser l’usage

Wp-admin et wp-login sont des zones sensibles. Mais sur WordPress pro, vous avez des contraintes: des accès doivent être possibles pour des équipes, et parfois des intégrations (SSO, automatisations, tests) existent.

La bonne approche, selon mon expérience, est d’utiliser Nginx pour faire une première vérification de trajectoire, pas pour reproduire tout un système d’authentification dans le serveur.

Cela dit, Nginx peut aider:

    en refusant certains chemins à faible valeur, en appliquant des restrictions supplémentaires sur wp-login.php si votre architecture le permet, en ajoutant une limitation de débit (rate limiting) sur les tentatives répétées.

Le rate limiting est utile, mais il faut le calibrer. Sinon vous bloquez des utilisateurs légitimes lors d’un bug, ou vous rendez la connexion pénible depuis des réseaux instables.

Rate limiting: efficace contre le bruit, à calibrer pour le trafic réel

Le rate limiting Nginx fonctionne bien contre le bruteforce et le spam de login. Le point délicat est le dosage: trop strict, vous pénalisez les humains. Trop large, vous laissez passer le bruit.

Dans un contexte WordPress pro, je commence souvent par des valeurs modestes, puis j’ajuste sur la base des logs et du comportement réel. Par exemple, limiter le nombre de requêtes sur des endpoints comme wp-login.php et xmlrpc.php réduit fortement les attaques automatisées. Et comme ces endpoints sont ciblés, la règle devient très rentable.

Sur la plupart des sites, il y a aussi une réflexion à mener sur xmlrpc.php. Si votre entreprise n’utilise pas l’API XML-RPC, bloquer l’accès est une mesure de bon sens. Si vous l’utilisez, vous devez durcir autrement, par exemple via règles applicatives et filtrage.

Sécurité headers: utile, mais attention à l’effet de bord

Les en-têtes de sécurité améliorent le comportement du navigateur, mais ils ne sont pas une baguette magique. Je les traite comme un complément.

Quelques en-têtes importants:

    Content-Security-Policy pour réduire les risques d’injection de scripts. X-Frame-Options (ou son équivalent CSP frame-ancestors) pour éviter le clickjacking. Referrer-Policy pour limiter la fuite de contexte. X-Content-Type-Options pour éviter certaines confusions.

Le piège classique concerne CSP: un thème WordPress peut charger des scripts, polices, trackers, ou assets depuis des domaines multiples. Mettre une CSP trop stricte sans inventaire casse le rendu, ou casse des fonctionnalités. Je préfère une approche progressive, en observant d’abord les sources réellement utilisées.

Si vous n’avez pas la discipline nécessaire, commencez par les en-têtes moins intrusifs, puis migrez vers CSP avec des ajustements.

Une check-list pratique de durcissement Nginx pour WordPress

Voici le genre de vérification que je fais avant de valider une config sur un serveur WordPress pro. C’est court, mais ça évite les erreurs qui reviennent tout le temps.

    Désactiver autoindex et vérifier que les fichiers sensibles (dotfiles, fichiers de config, etc.) Ne sont pas servis. Refuser des méthodes inutiles, garder GET, HEAD, POST, et adapter aux usages spécifiques. Mettre des limites réalistes sur la taille de requête et vérifier les uploads WordPress. Encadrer les endpoints à risque avec un rate limiting, surtout wp-login.php et selon votre cas xmlrpc.php. Ajouter des headers de sécurité adaptés, sans casser thèmes, plugins et éventuels scripts tiers.

Cette check-list ne remplace pas une analyse, mais elle capture les axes qui font souvent la différence.

Rate limiting et vrais sites WordPress: les cas qui piègent

Pour rester concret, voici les pièges que j’ai rencontrés.

Premier piège: le login légitime depuis un VPN ou un réseau https://gardewp.fr/securite-wordpress/ d’entreprise. En entreprise, tous les employés peuvent sortir par quelques IP. Si vous imposez une limite trop dure, vous créez un blocage collectif. La solution n’est pas forcément d’augmenter la limite à l’infini, vous pouvez aussi associer la règle à des identifiants plus fins, ou mettre une fenêtre plus large.

Deuxième piège: un plugin qui fait des appels répétés. Certains plugins de cache ou de synchronisation peuvent provoquer des pics vers admin-ajax.php ou des endpoints qui finissent classés “à risque” dans votre logique. Vous devez donc lire vos logs, comprendre ce qui est attendu, puis ajuster.

Troisième piège: le reverse proxy et les adresses réelles. Si Nginx est derrière un load balancer, sans headers corrects (X-Forwarded-For), le rate limiting peut appliquer la limite à la mauvaise IP. Résultat, c’est aléatoire, et les utilisateurs se plaignent. Sur du pro, la correction à ce niveau doit être faite au bon endroit dans la chaîne.

Limiter l’accès aux routes inutiles: où Nginx a un avantage réel

WordPress a beaucoup d’URLs possibles. Pourtant, un site pro n’utilise pas toutes les fonctionnalités au même niveau, et souvent certaines routes devraient être quasi inaccessibles.

Nginx peut:

    refuser des chemins qui ne devraient jamais être exposés, empêcher certaines extensions de s’exécuter ou d’être servies, réduire la surface de scan.

Le point important est de respecter l’existant. Si votre site a besoin de sitemap.xml, vous ne bloquez pas les .xml. Si vous utilisez des webhooks ou des endpoints spécifiques, vous ne refusez pas les méthodes ou formats au hasard.

C’est là que la configuration “au feeling” se révèle dangereuse. Un durcissement pro est une conversation entre ce que WordPress attend, ce que votre équipe utilise, et ce que les attaques tentent.

Mettre les bonnes protections autour de PHP-FPM

Dans un serveur WordPress, PHP-FPM est l’exécutant. Nginx doit donc:

    router correctement les requêtes PHP, empêcher l’accès à des fichiers PHP non destinés, transmettre les paramètres fastcgi de façon cohérente.

Un mauvais fastcgi_param SCRIPT_FILENAME est une cause classique de comportement inattendu, parfois exploité dans des scénarios de contournement. Ce n’est pas spécifique à WordPress, mais dans WordPress, il suffit qu’un chemin se résolve de façon étrange pour créer une surface.

Je vérifie aussi l’isolation de PHP: user, group, socket, et droits sur le filesystem. Trop souvent, le PHP tourne avec plus de privilèges que nécessaire. Cela dépasse Nginx, mais Nginx influence directement l’exposition.

Une approche par étapes pour déployer sans casser

Quand vous changez Nginx sur un site WordPress pro, vous ne voulez pas découvrir le problème à 9h. Voilà une méthode simple, que j’utilise pour minimiser le risque.

Tester la configuration sur un environnement de préproduction, ou au minimum valider la syntaxe Nginx puis faire un rollback prêt à l’emploi. Activer progressivement les protections non intrusives (dotfiles, autoindex, headers légers) avant d’attaquer les endpoints sensibles. Ajouter ensuite le rate limiting sur une cible limitée (login) et observer les logs pendant quelques jours. Durcir xmlrpc.php ou d’autres zones uniquement si vous êtes certain que personne ne s’en sert. Documenter la configuration, pour que la maintenance et les prochains changements ne soient pas des devinettes.

Cette démarche réduit fortement le risque de panne, tout en améliorant la sécurité de façon continue.

Edge cases WordPress: permaliens, cache, et formulaires d’admin

WordPress utilise des permaliens. Une règle Nginx mal calibrée peut renvoyer 404 là où WordPress devrait router vers le bon fichier PHP. Le résultat est souvent subtil: un formulaire d’administration peut fonctionner, mais un autre chemin casse, ou inversement.

Côté formulaires, je fais attention aux endpoints d’upload et de sauvegarde. WordPress peut faire des requêtes POST en arrière-plan. Si vous limitez trop les tailles, ou si vous refusez certaines méthodes, des actions normales deviennent impossibles. Et quand ça échoue, certains plugins retentent, ce qui augmente la charge et peut déclencher du rate limiting.

Enfin, cache: si vous mettez en place du caching Nginx ou via un reverse proxy, vous devez distinguer ce qui doit être mis en cache et ce qui ne doit jamais l’être. Un cache mal géré peut exposer des pages privées. Même si Nginx “sert seulement des statiques”, une mauvaise règle de try_files peut faire basculer des réponses dynamiques dans un cache.

Vérification sur le terrain: quoi regarder après changement

Après avoir durci Nginx, je ne me contente pas d’un test manuel. Je regarde des indicateurs simples, mais utiles.

D’abord, la différence de volume vers des endpoints sensibles. Si le rate limiting fonctionne, vous devriez voir une baisse des requêtes répétitives, et des logs d’erreurs qui cessent d’être inondés.

Ensuite, je vérifie les erreurs 4xx. Un pic de 404 peut indiquer un mauvais routage des permaliens. Un pic de 403 peut indiquer une règle trop stricte sur un chemin utilisé par le thème ou un plugin.

Enfin, je surveille les erreurs applicatives. Si des règles Nginx provoquent des comportements inattendus, WordPress peut générer plus d’erreurs PHP. Dans un site pro, ces signaux doivent être corrélés, même sans “système de détection magique”.

Ce que je ferais en priorité sur un WordPress pro

Si je devais prioriser sans tout réécrire, je choisirais:

    masquer ce qui n’apporte aucune valeur et réduire la surface de fichiers sensibles, encadrer les méthodes et limiter la taille de requête, sécuriser wp-login.php et, si c’est inutilisé, bloquer xmlrpc.php, mettre des headers de sécurité adaptés sans casser le rendu, valider le routage WordPress avec des permaliens et des flux réels.

Cette approche est pragmatique. Elle évite de “se perdre” dans des configurations complexes que personne ne saura maintenir, et elle apporte un niveau de sécurité mesurable.

Limites et bon sens: Nginx seul ne suffit pas

Il faut le dire clairement: la sécurité d’un site WordPress professionnel ne repose pas sur Nginx uniquement. Si une application est vulnérable, une requête malveillante peut passer. Si un plugin a une faille, le serveur ne la “répare” pas.

En revanche, Nginx fait très bien ce pour quoi il est fait: réduire le bruit, empêcher certains types d’accès, contrôler le trafic, et donner à WordPress un environnement plus propre.

Le bon équilibre consiste à associer:

    une configuration Nginx robuste, une hygiène WordPress (mises à jour, plugins minimaux), des sauvegardes testées, et une observabilité réaliste.

Pour aller plus loin: adapter à votre architecture (et éviter les “recettes”)

Chaque environnement WordPress pro a ses nuances: reverse proxy en amont, CDN, règles de firewall, gestion des IP réelles, taille d’upload, endpoints d’entreprise, et intégrations SSO.

Si vous me décrivez votre architecture (WordPress en racine ou en sous-dossier), votre méthode PHP-FPM (socket ou TCP), et si vous utilisez un reverse proxy ou un CDN, je peux vous proposer une configuration Nginx plus précise, avec les bonnes zones location, les règles de dotfiles adaptées, et un calibrage de rate limiting cohérent avec votre trafic.