15. Durcissement de la sécurité WordPress
15.1. Introduction à la sécurité WordPress
Section intitulée « 15.1. Introduction à la sécurité WordPress »WordPress alimente plus de 40 % de tous les sites web sur Internet, ce qui en fait une cible privilégiée pour les attaquants. Cette section couvre les mesures de sécurité essentielles pour protéger votre installation WordPress contre les menaces courantes.
Les mesures de sécurité de ce guide suivent une approche de défense en profondeur, implémentant plusieurs couches de protection :
- Isolation : Séparer les sites WordPress en utilisant des utilisateurs dédiés et des pools PHP-FPM
- Contrôle d’accès : Restreindre l’accès au système de fichiers et définir les permissions appropriées
- Chiffrement : Implémenter SSL/TLS avec des paramètres de sécurité optimaux
- Filtrage des requêtes : Bloquer les requêtes malveillantes avant qu’elles n’atteignent WordPress
- Durcissement de l’application : Limiter les fonctionnalités WordPress qui pourraient être exploitées
En implémentant ces mesures, vous réduirez significativement la surface d’attaque de votre installation WordPress et rendrez beaucoup plus difficile la compromission de votre site par les attaquants.
15.2. Surveillance de la sécurité avec les journaux
Section intitulée « 15.2. Surveillance de la sécurité avec les journaux »Avant d’implémenter des mesures de sécurité, il est important de comprendre comment surveiller votre serveur pour détecter les activités suspectes.
15.2.1. Vérification des journaux Nginx
Section intitulée « 15.2.1. Vérification des journaux Nginx »Les journaux Nginx fournissent des informations précieuses sur les requêtes vers votre site web, y compris les tentatives d’attaque potentielles :
# Naviguer vers le répertoire des journaux Nginxcd /var/log/nginx
# Lister les fichiers journaux disponiblesls
# Afficher le contenu d'un fichier journal spécifiquesudo cat access_example.com.log
# Afficher les journaux avec pagination pour les gros fichierssudo less error_example.com.logRecherchez des schémas comme des tentatives de connexion échouées répétées, des méthodes HTTP inhabituelles ou des requêtes vers des fichiers PHP inexistants, qui pourraient indiquer des tentatives d’attaque.
15.3. Séparation des sites avec des pools PHP - Partie 1
Section intitulée « 15.3. Séparation des sites avec des pools PHP - Partie 1 »15.3.1. Création d’un utilisateur dédié pour WordPress
Section intitulée « 15.3.1. Création d’un utilisateur dédié pour WordPress »Un principe de sécurité clé est d’exécuter WordPress sous un compte utilisateur dédié plutôt que l’utilisateur www-data par défaut. Cela offre une meilleure isolation et un meilleur contrôle.
Commencez par créer un utilisateur dédié pour votre site WordPress :
# Créer un nouvel utilisateur pour votre site WordPresssudo useradd wordpress_user15.3.2. Configuration des permissions de groupe utilisateur
Section intitulée « 15.3.2. Configuration des permissions de groupe utilisateur »Configurez les relations de groupe appropriées pour permettre au serveur web et à votre utilisateur spécifique au site d’accéder aux fichiers nécessaires :
# Ajouter www-data au groupe de l'utilisateur WordPresssudo usermod -a -G wordpress_user www-data
# Ajouter l'utilisateur WordPress au groupe www-datasudo usermod -a -G www-data wordpress_user
# Si nécessaire, ajouter votre utilisateur admin au groupe de l'utilisateur WordPresssudo usermod -a -G wordpress_user admin_usernameCette configuration crée une isolation appropriée tout en maintenant les permissions d’accès nécessaires.
15.4. Séparation des sites avec des pools PHP - Partie 2
Section intitulée « 15.4. Séparation des sites avec des pools PHP - Partie 2 »Par défaut, tout le traitement PHP passe par un seul pool PHP-FPM. La création d’un pool dédié pour chaque site WordPress offre une meilleure isolation de sécurité et un meilleur contrôle des ressources.
15.4.1. Création d’un pool PHP-FPM spécifique au site
Section intitulée « 15.4.1. Création d’un pool PHP-FPM spécifique au site »# Naviguer vers le répertoire de configuration des pools PHP-FPMcd /etc/php/8.3/fpm/pool.d/
# Créer une nouvelle configuration de pool en copiant celle par défautsudo cp www.conf example.com.conf
# Modifier la nouvelle configuration de poolsudo vim example.com.conf15.4.2. Configuration du pool PHP-FPM
Section intitulée « 15.4.2. Configuration du pool PHP-FPM »Modifiez le fichier de configuration du pool avec ces paramètres orientés sécurité :
; Changer le nom du pool de 'www' au nom de votre site[example]
; Définir l'utilisateur et le groupe à votre utilisateur spécifique au siteuser = wordpress_usergroup = wordpress_user
; Utiliser un fichier socket spécifique au sitelisten = /run/php/php8.3-fpm-example.com.sock
; Définir les limites de ressourcesrlimit_files = 15000rlimit_core = 100
; Désactiver l'affichage des erreurs mais activer la journalisationphp_flag[display_errors] = offphp_admin_flag[log_errors] = onphp_admin_value[error_log] = /var/log/fpm-php.example.com.log15.4.3. Durcissement des permissions du socket
Section intitulée « 15.4.3. Durcissement des permissions du socket »Ajoutez ces directives pour sécuriser davantage le socket PHP-FPM :
; Définir la propriété et les permissions du socketlisten.owner = www-datalisten.group = www-datalisten.mode = 0600Ces paramètres :
- Restreignent l’accès au socket uniquement à l’utilisateur du serveur web
- Empêchent les autres utilisateurs du système de se connecter à votre pool PHP-FPM
15.4.4. Création du fichier journal PHP-FPM
Section intitulée « 15.4.4. Création du fichier journal PHP-FPM »# Créer le fichier journalsudo touch /var/log/fpm-php.example.com.log
# Définir la propriété appropriéesudo chown wordpress_user:www-data /var/log/fpm-php.example.com.log
# Définir les permissions appropriéessudo chmod 660 /var/log/fpm-php.example.com.log15.4.5. Application de la configuration PHP-FPM
Section intitulée « 15.4.5. Application de la configuration PHP-FPM »# Recharger PHP-FPM pour appliquer les modificationssudo systemctl reload php8.3-fpm
# Vérifier le chemin du socket dans votre configurationsudo grep "listen = /" example.com.conf15.4.6. Mise à jour de Nginx pour utiliser le nouveau pool PHP-FPM
Section intitulée « 15.4.6. Mise à jour de Nginx pour utiliser le nouveau pool PHP-FPM »Modifiez votre bloc serveur Nginx pour utiliser le nouveau socket PHP-FPM :
# Modifier la configuration Nginx de votre sitesudo vim /etc/nginx/sites-available/example.com.confTrouvez la section de traitement PHP et mettez à jour la directive fastcgi_pass :
location ~ \.php$ { include snippets/fastcgi-php.conf; fastcgi_pass unix:/run/php/php8.3-fpm-example.com.sock; include /etc/nginx/includes/fastcgi_optimize.conf;}Appliquez les modifications :
# Tester la configuration Nginxsudo nginx -t
# Recharger Nginx si le test est réussisudo systemctl reload nginx15.5. Propriété et permissions WordPress
Section intitulée « 15.5. Propriété et permissions WordPress »La propriété et les permissions des fichiers sont critiques pour la sécurité de WordPress. L’objectif est de permettre à WordPress de fonctionner normalement tout en restreignant l’accès aux fichiers sensibles.
15.5.1. Configuration standard des permissions
Section intitulée « 15.5.1. Configuration standard des permissions »Pour un équilibre entre sécurité et fonctionnalité, utilisez ces permissions :
# Définir la propriété à l'utilisateur WordPresssudo chown -R wordpress_user:wordpress_user /var/www/example.com/public_html/
# Définir les permissions des répertoires à 770 (propriétaire et groupe : lecture, écriture, exécution)sudo find /var/www/example.com/public_html/ -type d -exec chmod 770 {} \;
# Définir les permissions des fichiers à 660 (propriétaire et groupe : lecture et écriture)sudo find /var/www/example.com/public_html/ -type f -exec chmod 660 {} \;
# Définir wp-config.php en lecture seule pour le propriétairesudo chmod 400 /var/www/example.com/public_html/wp-config.php15.5.2. Configuration renforcée des permissions
Section intitulée « 15.5.2. Configuration renforcée des permissions »Pour une sécurité maximale (peut nécessiter des ajustements pour certaines extensions) :
# Définir la propriété à l'utilisateur WordPresssudo chown -R wordpress_user:wordpress_user /var/www/example.com/public_html/
# Définir les permissions des répertoires à 550 (propriétaire et groupe : lecture et exécution)sudo find /var/www/example.com/public_html/ -type d -exec chmod 550 {} \;
# Définir les permissions des fichiers à 440 (propriétaire et groupe : lecture)sudo find /var/www/example.com/public_html/ -type f -exec chmod 440 {} \;
# Autoriser l'écriture dans le répertoire wp-content pour les mises à jour et les téléchargementssudo find /var/www/example.com/public_html/wp-content/ -type d -exec chmod 770 {} \;sudo find /var/www/example.com/public_html/wp-content/ -type f -exec chmod 660 {} \;15.6. Limiter l’accès au système de fichiers avec PHP open_basedir
Section intitulée « 15.6. Limiter l’accès au système de fichiers avec PHP open_basedir »La directive open_basedir restreint les fichiers auxquels PHP peut accéder, empêchant les attaquants d’accéder aux fichiers en dehors de votre installation WordPress.
15.6.1. Configuration des répertoires temporaires PHP
Section intitulée « 15.6.1. Configuration des répertoires temporaires PHP »Commencez par créer un répertoire temporaire dédié pour votre site WordPress :
# Créer un répertoire temporairecd /var/www/example.com/sudo mkdir tmp/
# Définir la propriété et les permissions appropriéessudo chown wordpress_user:wordpress_user tmp/sudo chmod 770 tmp/15.6.2. Configuration de la restriction open_basedir
Section intitulée « 15.6.2. Configuration de la restriction open_basedir »Modifiez la configuration de votre pool PHP-FPM pour ajouter la directive open_basedir :
# Modifier la configuration du pool PHP-FPMsudo vim /etc/php/8.3/fpm/pool.d/example.com.confAjoutez ces lignes à la configuration :
; Définir des répertoires temporaires personnalisésphp_admin_value[upload_tmp_dir] = /var/www/example.com/tmp/php_admin_value[sys_temp_dir] = /var/www/example.com/tmp/
; Restreindre l'accès aux fichiers PHP à des répertoires spécifiquesphp_admin_value[open_basedir] = /var/www/example.com/public_html/:/var/www/example.com/tmp/Appliquez les modifications :
# Recharger PHP-FPMsudo systemctl reload php8.3-fpm15.6.3. Désactivation des fonctions PHP dangereuses
Section intitulée « 15.6.3. Désactivation des fonctions PHP dangereuses »Restreignez les fonctions PHP qui pourraient être utilisées à des fins malveillantes :
; Désactiver les fonctions PHP potentiellement dangereusesphp_admin_value[disable_functions] = shell_exec, opcache_get_configuration, opcache_get_status, disk_total_space, diskfreespace, dl, exec, passthru, pclose, pcntl_alarm, pcntl_exec, pcntl_fork, pcntl_get_last_error, pcntl_getpriority, pcntl_setpriority, pcntl_signal, pcntl_signal_dispatch, pcntl_sigprocmask, pcntl_sigtimedwait, pcntl_sigwaitinfo, pcntl_strerror, pcntl_waitpid, pcntl_wait, pcntl_wexitstatus, pcntl_wifcontinued, pcntl_wifexited, pcntl_wifsignaled, pcntl_wifstopped, pcntl_wstopsig, pcntl_wtermsig, popen, posix_getpwuid, posix_kill, posix_mkfifo, posix_setpgid, posix_setsid, posix_setuid, posix_uname, proc_close, proc_get_status, proc_nice, proc_open, proc_terminate, show_source, system15.7. Installer et configurer des certificats SSL GRATUITS - Partie 1
Section intitulée « 15.7. Installer et configurer des certificats SSL GRATUITS - Partie 1 »Le chiffrement HTTPS est essentiel pour la sécurité de WordPress. Let’s Encrypt fournit des certificats SSL gratuits qui sont reconnus par tous les navigateurs majeurs.
15.7.1. Installation de Certbot
Section intitulée « 15.7.1. Installation de Certbot »Certbot est un outil qui automatise le processus d’obtention et de renouvellement des certificats Let’s Encrypt :
# Mettre à jour les listes de paquetssudo apt update
# Installer Certbot et le plugin Nginxsudo apt install certbot python3-certbot-nginx15.7.2. Obtention d’un certificat
Section intitulée « 15.7.2. Obtention d’un certificat »Utilisez le plugin webroot pour obtenir un certificat sans interrompre votre site web :
# Obtenir un certificat pour votre domainesudo certbot certonly --webroot -w /var/www/example.com/public_html/ -d example.com -d www.example.comSuivez les invites pour terminer le processus d’émission du certificat.
15.8. Installer et configurer des certificats SSL GRATUITS - Partie 2
Section intitulée « 15.8. Installer et configurer des certificats SSL GRATUITS - Partie 2 »15.8.1. Création de paramètres DH forts
Section intitulée « 15.8.1. Création de paramètres DH forts »Pour renforcer la sécurité de votre implémentation SSL/TLS, créez un fichier de paramètres Diffie-Hellman fort :
# Créer le répertoire SSLcd /etc/nginx/sudo mkdir ssl/cd ssl/
# Générer les paramètres DH (cela peut prendre quelques minutes)sudo openssl dhparam -out dhparam.pem 204815.8.2. Création de la configuration SSL spécifique au site
Section intitulée « 15.8.2. Création de la configuration SSL spécifique au site »Créez un fichier de configuration pour les certificats SSL de votre site :
# Créer le fichier de configuration des certificats SSLsudo vim /etc/nginx/ssl/ssl_certs_example.com.confAjoutez le contenu suivant :
# Chemins des certificatsssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
# Certificat de stapling SSLssl_trusted_certificate /etc/letsencrypt/live/example.com/chain.pem;15.9. Installer et configurer des certificats SSL GRATUITS - Partie 3
Section intitulée « 15.9. Installer et configurer des certificats SSL GRATUITS - Partie 3 »15.9.1. Création de la configuration SSL globale
Section intitulée « 15.9.1. Création de la configuration SSL globale »Créez un fichier de configuration SSL global avec des paramètres de sécurité optimaux :
# Créer le fichier de configuration SSL globalsudo vim /etc/nginx/ssl/ssl_all_sites.confAjoutez le contenu suivant :
# CONFIGURATION RESULTAT EN NOTE A+ SUR SSLLABS.COM# MISE A JOUR DES DIRECTIVES POUR MAINTENIR LA NOTE A+ - VERIFIER LA DATE# DATE: OCTOBER 2024
# CACHE SSL ET PROTOCOLESssl_session_cache shared:SSL:20m;ssl_session_timeout 180m;ssl_protocols TLSv1.2 TLSv1.3;ssl_prefer_server_ciphers on;# ssl_ciphers doit etre sur une seule ligne, ne pas repartir sur plusieurs lignesssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-CHACHA20-POLY1305;ssl_dhparam /etc/nginx/ssl/dhparam.pem;ssl_stapling on;ssl_stapling_verify on;# resolver defini sur Cloudflare# timeout peut etre defini jusqu'a 30sresolver 1.1.1.1 1.0.0.1;resolver_timeout 15s;ssl_session_tickets off;# EN-TETES HSTSadd_header Strict-Transport-Security "max-age=31536000;" always;# Apres avoir configure TOUS vos sous-domaines - commentez la ligne ci-dessus et decommentez la directive ci-dessous# add_header Strict-Transport-Security "max-age=31536000; includeSubDomains;" always;# Activer QUIC et HTTP/3ssl_early_data on;add_header Alt-Svc 'h3=":$server_port"; ma=86400';add_header x-quic 'H3';quic_retry on;15.9.2. Configuration de Nginx pour HTTPS
Section intitulée « 15.9.2. Configuration de Nginx pour HTTPS »Mettez à jour votre bloc serveur Nginx pour utiliser HTTPS :
# Modifier la configuration Nginx de votre sitesudo vim /etc/nginx/sites-available/example.com.confAjoutez un bloc serveur pour rediriger HTTP vers HTTPS :
# Redirection HTTP vers HTTPSserver { listen 80; server_name example.com www.example.com;
# Redirection permanente 301 return 301 https://example.com$request_uri;}Configurez le bloc serveur HTTPS :
# Bloc serveur HTTPSserver { # Activer SSL, HTTP/2 et HTTP/3 listen 443 ssl; http2 on;
# Support HTTP/3 listen 443 quic reuseport; http3 on;
server_name example.com www.example.com;
# Inclure les fichiers de configuration SSL include /etc/nginx/ssl/ssl_certs_example.com.conf; include /etc/nginx/ssl/ssl_all_sites.conf;
# Reste de votre configuration serveur...}Appliquez les modifications :
# Tester la configuration Nginxsudo nginx -t
# Recharger Nginx si le test est réussisudo systemctl reload nginx15.9.3. Test de la configuration SSL
Section intitulée « 15.9.3. Test de la configuration SSL »Vérifiez que votre configuration SSL fonctionne correctement :
# Tester la redirection HTTP vers HTTPScurl -I http://example.com
# Tester la connexion HTTPScurl -I https://example.comVous pouvez également tester votre configuration SSL avec des outils en ligne :
- SSL Labs - Pour un test SSL/TLS complet
- HTTP3 Check - Pour vérifier le support HTTP/3
15.9.4. Configuration du renouvellement automatique des certificats
Section intitulée « 15.9.4. Configuration du renouvellement automatique des certificats »Les certificats Let’s Encrypt expirent après 90 jours, le renouvellement automatique est donc essentiel :
# Modifier le crontab rootsudo crontab -eAjoutez les lignes suivantes :
# Renouveler les certificats deux fois par mois et recharger Nginx00 1 14,28 * * certbot renew --force-renewal --deploy-hook "systemctl reload nginx" >> /var/log/certbot-renew.log 2>&1Définissez les permissions appropriées pour le fichier journal :
# Créer le fichier journal s'il n'existe passudo touch /var/log/certbot-renew.log
# Définir les permissions appropriéessudo chmod 644 /var/log/certbot-renew.log15.10. Durcissement des en-têtes de réponse HTTP
Section intitulée « 15.10. Durcissement des en-têtes de réponse HTTP »Les en-têtes de sécurité HTTP aident à protéger votre site contre diverses attaques comme le XSS, le clickjacking et le reniflage de type de contenu.
15.10.1. Création d’une configuration d’en-têtes de sécurité
Section intitulée « 15.10.1. Création d’une configuration d’en-têtes de sécurité »Créez un fichier de configuration pour les en-têtes de sécurité :
# Créer le fichier de configuration des en-têtes de sécuritécd /etc/nginx/includes/sudo vim http_headers.confAjoutez le contenu suivant :
# Politique de référent# Contrôle la quantité d'informations de référent incluse dans les requêtesadd_header Referrer-Policy "strict-origin-when-cross-origin" always;
# Options de type de contenu# Empêche les navigateurs de deviner le type MIME d'une réponseadd_header X-Content-Type-Options "nosniff" always;
# Options de cadre# Protège contre le clickjacking en empêchant votre page d'être affichée dans un cadreadd_header X-Frame-Options "sameorigin" always;
# Protection XSS# Active le filtre de script intersite (XSS) dans les navigateursadd_header X-XSS-Protection "1; mode=block" always;
# Politique de permissions# Contrôle quelles fonctionnalités et API du navigateur peuvent être utiliséesadd_header Permissions-Policy "geolocation=(),midi=(),sync-xhr=(),microphone=(),camera=(),magnetometer=(),gyroscope=(),fullscreen=self,payment=()" always;15.10.2. Création d’une configuration d’en-têtes de mise en cache et de sécurité
Section intitulée « 15.10.2. Création d’une configuration d’en-têtes de mise en cache et de sécurité »Pour le contenu statique, créez une configuration combinant mise en cache et en-têtes de sécurité :
# Créer le fichier de configuration des en-têtes de mise en cache et de sécuritésudo vim /etc/nginx/includes/browser_caching_security_headers.confAjoutez le contenu suivant :
# Activer la mise en cache du navigateurexpires 30d;etag on;if_modified_since exact;add_header Pragma "public" always;add_header Cache-Control "public, no-transform" always;
# Inclure les en-têtes de sécuritéinclude /etc/nginx/includes/http_headers.conf;
# Désactiver la journalisation d'accès pour le contenu statiqueaccess_log off;15.10.3. Implémentation des en-têtes de sécurité
Section intitulée « 15.10.3. Implémentation des en-têtes de sécurité »Ajoutez les en-têtes de sécurité à votre bloc serveur Nginx :
# Modifier la configuration Nginx de votre sitesudo vim /etc/nginx/sites-available/example.com.confAjoutez la directive d’inclusion au-dessus du bloc location de traitement PHP :
# Inclure les en-têtes de sécuritéinclude /etc/nginx/includes/http_headers.conf;Appliquez les modifications :
# Tester la configuration Nginxsudo nginx -t
# Recharger Nginx si le test est réussisudo systemctl reload nginx15.11. Utilisation des directives Nginx pour protéger WordPress
Section intitulée « 15.11. Utilisation des directives Nginx pour protéger WordPress »Nginx peut être configuré pour bloquer l’accès aux fichiers WordPress sensibles et prévenir les vecteurs d’attaque courants.
15.11.1. Création des directives de sécurité WordPress
Section intitulée « 15.11.1. Création des directives de sécurité WordPress »Créez un fichier de configuration pour les directives de sécurité WordPress :
# Créer le fichier de directives de sécurité WordPresscd /etc/nginx/includes/sudo vim nginx_security_directives.confAjoutez le contenu suivant :
# Refuser l'accès aux fichiers WordPress sensibleslocation = /wp-config.php { deny all; }location = /wp-admin/install.php { deny all; }location ~* /readme\.html$ { deny all; }location ~* /readme\.txt$ { deny all; }location ~* /licence\.txt$ { deny all; }location ~* /license\.txt$ { deny all; }location ~ ^/wp-admin/includes/ { deny all; }location ~ ^/wp-includes/[^/]+\.php$ { deny all; }location ~ ^/wp-includes/js/tinymce/langs/.+\.php$ { deny all; }location ~ ^/wp-includes/theme-compat/ { deny all; }
# Désactiver l'exécution PHP dans les répertoires potentiellement dangereuxlocation ~* ^/wp\-content/uploads/.*\.(?:php[1-7]?|pht|phtml?|phps)$ { deny all; }location ~* ^/wp\-content/plugins/.*\.(?:php[1-7]?|pht|phtml?|phps)$ { deny all; }location ~* ^/wp\-content/themes/.*\.(?:php[1-7]?|pht|phtml?|phps)$ { deny all; }
# Désactiver l'accès au fichier de surcharge PHP du sitelocation = /.user.ini { deny all; }
# Filtrer les méthodes de requête suspectesif ( $request_method ~* ^(TRACE|DELETE|TRACK)$ ) { return 403; }
# Filtrer les chaînes de requête suspectes dans l'URLset $susquery 0;if ( $args ~* "\.\./" ) { set $susquery 1; }if ( $args ~* "\.(bash|git|hg|log|svn|swp|cvs)" ) { set $susquery 1; }if ( $args ~* "etc/passwd" ) { set $susquery 1; }if ( $args ~* "boot\.ini" ) { set $susquery 1; }if ( $args ~* "ftp:" ) { set $susquery 1; }if ( $args ~* "(<|%3C)script(>|%3E)" ) { set $susquery 1; }if ( $args ~* "mosConfig_[a-zA-Z_]{1,21}(=|%3D)" ) { set $susquery 1; }if ( $args ~* "base64_decode\(" ) { set $susquery 1; }if ( $args ~* "%24&x" ) { set $susquery 1; }if ( $args ~* "127\.0" ) { set $susquery 1; }if ( $args ~* "(globals|encode|request|localhost|loopback|request|insert|concat|union|declare)" ) { set $susquery 1; }if ( $args ~* "%[01][0-9A-F]" ) { set $susquery 1; }# Exceptions pour les fonctionnalités WordPress légitimesif ( $args ~ "^loggedout=true" ) { set $susquery 0; }if ( $args ~ "^action=jetpack-sso" ) { set $susquery 0; }if ( $args ~ "^action=rp" ) { set $susquery 0; }if ( $http_cookie ~ "wordpress_logged_in_" ) { set $susquery 0; }if ( $http_referer ~* "^https?://maps\.googleapis\.com/" ) { set $susquery 0; }if ( $susquery = 1 ) { return 403; }
# Bloquer les injections SQL courantesset $block_sql_injections 0;if ($query_string ~ "union.*select.*\(") { set $block_sql_injections 1; }if ($query_string ~ "union.*all.*select.*") { set $block_sql_injections 1; }if ($query_string ~ "concat.*\(") { set $block_sql_injections 1; }if ($block_sql_injections = 1) { return 403; }
# Bloquer les injections de fichiersset $block_file_injections 0;if ($query_string ~ "[a-zA-Z0-9_]=http://") { set $block_file_injections 1; }if ($query_string ~ "[a-zA-Z0-9_]=(\.\.//?)+") { set $block_file_injections 1; }if ($query_string ~ "[a-zA-Z0-9_]=/([a-z0-9_.]//?)+") { set $block_file_injections 1; }if ($block_file_injections = 1) { return 403; }
# Bloquer les exploits courantsset $block_common_exploits 0;if ($query_string ~ "(<|%3C).*script.*(>|%3E)") { set $block_common_exploits 1; }if ($query_string ~ "GLOBALS(=|\[|\%[0-9A-Z]{0,2})") { set $block_common_exploits 1; }if ($query_string ~ "_REQUEST(=|\[|\%[0-9A-Z]{0,2})") { set $block_common_exploits 1; }if ($query_string ~ "proc/self/environ") { set $block_common_exploits 1; }if ($query_string ~ "mosConfig_[a-zA-Z_]{1,21}(=|\%3D)") { set $block_common_exploits 1; }if ($query_string ~ "base64_(en|de)code\(.*\)") { set $block_common_exploits 1; }if ($block_common_exploits = 1) { return 403; }
# Bloquer le spamset $block_spam 0;if ($query_string ~ "\b(ultram|unicauca|valium|viagra|vicodin|xanax|ypxaieo)\b") { set $block_spam 1; }if ($query_string ~ "\b(erections|hoodia|huronriveracres|impotence|levitra|libido)\b") { set $block_spam 1; }if ($query_string ~ "\b(ambien|blue\spill|cialis|cocaine|ejaculation|erectile)\b") { set $block_spam 1; }if ($query_string ~ "\b(lipitor|phentermin|pro[sz]ac|sandyauer|tramadol|troyhamby)\b") { set $block_spam 1; }if ($block_spam = 1) { return 403; }
# Bloquer les agents utilisateurs malveillantsset $block_user_agents 0;if ($http_user_agent ~ "Indy Library") { set $block_user_agents 1; }if ($http_user_agent ~ "libwww-perl") { set $block_user_agents 1; }if ($http_user_agent ~ "GetRight") { set $block_user_agents 1; }if ($http_user_agent ~ "GetWeb!") { set $block_user_agents 1; }if ($http_user_agent ~ "Go!Zilla") { set $block_user_agents 1; }if ($http_user_agent ~ "Download Demon") { set $block_user_agents 1; }if ($http_user_agent ~ "Go-Ahead-Got-It") { set $block_user_agents 1; }if ($http_user_agent ~ "TurnitinBot") { set $block_user_agents 1; }if ($http_user_agent ~ "GrabNet") { set $block_user_agents 1; }# Bloquer les outils de scan de sécurité courantsif ($http_user_agent ~ "dirbuster") { set $block_user_agents 1; }if ($http_user_agent ~ "nikto") { set $block_user_agents 1; }if ($http_user_agent ~ "sqlmap") { set $block_user_agents 1; }if ($http_user_agent ~ "fimap") { set $block_user_agents 1; }if ($http_user_agent ~ "nessus") { set $block_user_agents 1; }if ($http_user_agent ~ "whatweb") { set $block_user_agents 1; }if ($http_user_agent ~ "Openvas") { set $block_user_agents 1; }if ($http_user_agent ~ "jbrofuzz") { set $block_user_agents 1; }if ($http_user_agent ~ "libwhisker") { set $block_user_agents 1; }if ($http_user_agent ~ "webshag") { set $block_user_agents 1; }if ($http_user_agent ~ "Acunetix") { set $block_user_agents 1; }if ($block_user_agents = 1) { return 403; }15.11.2. Implémentation des directives de sécurité WordPress
Section intitulée « 15.11.2. Implémentation des directives de sécurité WordPress »Ajoutez les directives de sécurité à votre bloc serveur Nginx :
# Modifier la configuration Nginx de votre sitesudo vim /etc/nginx/sites-available/example.com.confAjoutez la directive d’inclusion au-dessus du bloc location de traitement PHP :
# Inclure les directives de sécurité WordPressinclude /etc/nginx/includes/nginx_security_directives.conf;Appliquez les modifications :
# Tester la configuration Nginxsudo nginx -t
# Recharger Nginx si le test est réussisudo systemctl reload nginx15.11.3. Autoriser l’exécution PHP pour des fichiers d’extensions spécifiques
Section intitulée « 15.11.3. Autoriser l’exécution PHP pour des fichiers d’extensions spécifiques »Certaines extensions nécessitent l’exécution PHP dans le répertoire des extensions. Puisque nous avons bloqué l’exécution PHP dans ce répertoire pour des raisons de sécurité, nous devons l’autoriser sélectivement pour les fichiers d’extensions légitimes.
Test du blocage de l’exécution PHP
Section intitulée « Test du blocage de l’exécution PHP »Vérifiez d’abord que l’exécution PHP est bloquée dans le répertoire des extensions :
# Créer un fichier PHP de test dans le répertoire des extensionscd /var/www/example.com/sudo vim public_html/wp-content/plugins/test.phpAjoutez ce contenu au fichier de test :
<?phpphpinfo();?>Lorsque vous essayez d’accéder à ce fichier dans votre navigateur (https://example.com/wp-content/plugins/test.php), vous devriez recevoir une erreur 403 Forbidden, confirmant que l’exécution PHP est bloquée.
Autoriser des fichiers d’extensions spécifiques
Section intitulée « Autoriser des fichiers d’extensions spécifiques »Pour autoriser l’exécution PHP pour des fichiers d’extensions spécifiques, ajoutez un bloc location pour chaque fichier :
# Modifier la configuration Nginx de votre sitesudo vim /etc/nginx/sites-available/example.com.confAjoutez un bloc location pour chaque fichier d’extension nécessitant l’exécution PHP :
# Autoriser l'exécution PHP pour des fichiers d'extensions spécifiqueslocation = /wp-content/plugins/specific-plugin/file.php { allow all; include snippets/fastcgi-php.conf; fastcgi_param HTTP_HOST $host; fastcgi_pass unix:/run/php/php8.3-fpm-example.com.sock; include /etc/nginx/includes/fastcgi_optimize.conf;}Appliquez les modifications :
# Tester la configuration Nginxsudo nginx -t
# Recharger Nginx et redémarrer PHP-FPMsudo systemctl reload nginx && sudo systemctl restart php8.3-fpmN’oubliez pas de supprimer le fichier de test :
# Supprimer le fichier PHP de testsudo rm /var/www/example.com/public_html/wp-content/plugins/test.php15.12. Protection DDoS Nginx et WordPress
Section intitulée « 15.12. Protection DDoS Nginx et WordPress »15.12.1. Protection contre le hotlinking
Section intitulée « 15.12.1. Protection contre le hotlinking »Le hotlinking se produit lorsque d’autres sites web créent des liens directs vers vos images ou fichiers, consommant votre bande passante. Empêchez cela avec Nginx :
# Modifier la configuration Nginx de votre sitesudo vim /etc/nginx/sites-available/example.com.confAjoutez ce qui suit à votre bloc serveur :
# Empêcher le hotlinking des imageslocation ~* \.(jpg|jpeg|png|gif|webp|svg)$ { valid_referers none blocked server_names *.example.com example.com; if ($invalid_referer) { return 403; }
# Inclure la mise en cache du navigateur pour les images include /etc/nginx/includes/browser_caching_security_headers.conf;}15.13. Stopper les attaques par force brute - Limitation de débit Nginx
Section intitulée « 15.13. Stopper les attaques par force brute - Limitation de débit Nginx »La limitation de débit aide à prévenir les attaques par force brute en limitant le nombre de requêtes qu’un client peut effectuer dans une période donnée.
15.13.1. Configuration de la limitation de débit
Section intitulée « 15.13.1. Configuration de la limitation de débit »Commencez par ajouter la zone de limitation de débit à votre configuration Nginx principale :
# Modifier la configuration Nginx principalecd /etc/nginx/sudo vim nginx.confAjoutez ce qui suit au contexte http :
# Zone de limitation de débit pour WordPresslimit_req_zone $binary_remote_addr zone=wp:10m rate=30r/m;Cela crée une zone de 10 Mo nommée “wp” qui limite les clients à 30 requêtes par minute.
15.13.2. Création d’une configuration de limitation de débit
Section intitulée « 15.13.2. Création d’une configuration de limitation de débit »Créez un fichier de configuration pour la limitation de débit du login WordPress et XML-RPC :
# Créer le fichier de configuration de limitation de débitcd /etc/nginx/includes/sudo vim rate_limiting.confAjoutez le contenu suivant :
# Limiter le débit de la page de connexion WordPresslocation = /wp-login.php { limit_req zone=wp burst=20 nodelay; limit_req_status 444; include snippets/fastcgi-php.conf; fastcgi_param HTTP_HOST $host; fastcgi_pass unix:/run/php/php8.3-fpm-example.com.sock; include /etc/nginx/includes/fastcgi_optimize.conf;}
# Limiter le débit du XML-RPC WordPress (souvent utilisé dans les attaques par force brute)location = /xmlrpc.php { limit_req zone=wp burst=20 nodelay; limit_req_status 444; include snippets/fastcgi-php.conf; fastcgi_param HTTP_HOST $host; fastcgi_pass unix:/run/php/php8.3-fpm-example.com.sock; include /etc/nginx/includes/fastcgi_optimize.conf;}15.13.3. Implémentation de la limitation de débit
Section intitulée « 15.13.3. Implémentation de la limitation de débit »Ajoutez la configuration de limitation de débit à votre bloc serveur Nginx :
# Modifier la configuration Nginx de votre sitesudo vim /etc/nginx/sites-available/example.com.confAjoutez la directive d’inclusion :
# Inclure la configuration de limitation de débitinclude /etc/nginx/includes/rate_limiting.conf;Appliquez les modifications :
# Tester la configuration Nginxsudo nginx -t
# Recharger Nginx si le test est réussisudo systemctl reload nginx15.14. Interdire les modifications de fichiers
Section intitulée « 15.14. Interdire les modifications de fichiers »WordPress permet aux administrateurs de modifier les fichiers de thèmes et d’extensions directement depuis le tableau de bord d’administration. Cela peut être un risque de sécurité si un attaquant obtient l’accès à votre compte administrateur.
15.14.1. Désactivation des modifications de fichiers dans wp-config.php
Section intitulée « 15.14.1. Désactivation des modifications de fichiers dans wp-config.php »Modifiez votre fichier wp-config.php pour désactiver les modifications de fichiers :
# Modifier wp-config.phpsudo vim /var/www/example.com/public_html/wp-config.phpAjoutez la ligne suivante avant le commentaire “That’s all, stop editing!” :
/* Désactiver les modifications de fichiers */define('DISALLOW_FILE_MODS', true);Appliquez les modifications :
# Recharger PHP-FPMsudo systemctl reload php8.3-fpm15.15. Restriction des privilèges utilisateur de la base de données
Section intitulée « 15.15. Restriction des privilèges utilisateur de la base de données »L’utilisateur de la base de données WordPress ne devrait avoir que les privilèges nécessaires à son fonctionnement, et non un accès complet à la base de données.
15.15.1. Limitation des privilèges utilisateur de la base de données
Section intitulée « 15.15.1. Limitation des privilèges utilisateur de la base de données »Connectez-vous à votre serveur MariaDB et restreignez les privilèges de l’utilisateur de la base de données WordPress :
# Se connecter à MariaDBsudo mysql -u root -pExécutez ces commandes SQL :
-- Révoquer tous les privilègesREVOKE ALL PRIVILEGES ON wordpress_db.* FROM 'wordpress_user'@'localhost';
-- Accorder uniquement les privilèges nécessairesGRANT SELECT, INSERT, UPDATE, DELETE ON wordpress_db.* TO 'wordpress_user'@'localhost';
-- Appliquer les modificationsFLUSH PRIVILEGES;Quittez la console MariaDB :
EXIT;15.16. Durcissement de l’API REST WP
Section intitulée « 15.16. Durcissement de l’API REST WP »L’API REST WordPress peut être une cible pour les attaquants. Par défaut, elle est accessible à tous, mais nous pouvons restreindre l’accès aux utilisateurs authentifiés uniquement.
15.16.1. Restriction de l’accès à l’API REST
Section intitulée « 15.16.1. Restriction de l’accès à l’API REST »Ajoutez le code suivant au fichier functions.php de votre thème ou à une extension personnalisée :
/** * Restreindre l'API REST aux utilisateurs authentifiés */function restrict_rest_api_to_authenticated_users($access) { // Si non authentifié, bloquer l'accès if (!is_user_logged_in()) { return new WP_Error('rest_api_restricted', 'REST API access is restricted to authenticated users.', array('status' => 401)); }
// Sinon, autoriser l'accès return $access;}add_filter('rest_authentication_errors', 'restrict_rest_api_to_authenticated_users');15.16.2. Restriction de l’API REST avec Nginx
Section intitulée « 15.16.2. Restriction de l’API REST avec Nginx »Pour une couche de sécurité supplémentaire, vous pouvez également restreindre l’accès à l’API REST au niveau Nginx :
# Modifier la configuration Nginx de votre sitesudo vim /etc/nginx/sites-available/example.com.confAjoutez le bloc location suivant :
# Restreindre l'API REST WPlocation /wp-json/ { # Autoriser l'accès uniquement si connecté ou depuis des IP spécifiques if ($http_cookie !~* "wordpress_logged_in_") { # Autoriser des IP spécifiques (remplacez par votre IP) allow 192.168.1.1; # Bloquer tous les autres deny all; }
# Continuer le traitement de la requête try_files $uri $uri/ /index.php?$args;}Appliquez les modifications :
# Tester la configuration Nginxsudo nginx -t
# Recharger Nginx si le test est réussisudo systemctl reload nginx15.17. Utilisation d’un pare-feu applicatif web
Section intitulée « 15.17. Utilisation d’un pare-feu applicatif web »Un pare-feu applicatif web (WAF) fournit une couche de sécurité supplémentaire en filtrant et surveillant le trafic HTTP entre une application web et Internet.
15.17.1. Installation de ModSecurity avec Nginx
Section intitulée « 15.17.1. Installation de ModSecurity avec Nginx »ModSecurity est un WAF open source qui peut être intégré à Nginx :
# Installer ModSecurity et les dépendancessudo apt updatesudo apt install -y libmodsecurity3 libmodsecurity-dev nginx-module-security15.17.2. Configuration de ModSecurity
Section intitulée « 15.17.2. Configuration de ModSecurity »Créez une configuration de base ModSecurity :
# Créer le répertoire de configuration ModSecuritysudo mkdir -p /etc/nginx/modsec
# Télécharger le jeu de règles OWASP Core Rule Setsudo git clone https://github.com/coreruleset/coreruleset /etc/nginx/modsec/coreruleset
# Créer le fichier de configuration ModSecuritysudo vim /etc/nginx/modsec/modsec.confAjoutez le contenu suivant :
# Configuration de base ModSecuritySecRuleEngine OnSecRequestBodyAccess OnSecResponseBodyAccess OnSecResponseBodyMimeType text/plain text/html text/xml application/jsonSecResponseBodyLimit 1024
# Inclure le jeu de règles OWASP Core Rule SetInclude /etc/nginx/modsec/coreruleset/crs-setup.confInclude /etc/nginx/modsec/coreruleset/rules/*.conf15.17.3. Activation de ModSecurity dans Nginx
Section intitulée « 15.17.3. Activation de ModSecurity dans Nginx »Modifiez votre configuration Nginx pour activer ModSecurity :
# Modifier la configuration Nginx principalesudo vim /etc/nginx/nginx.confAjoutez ce qui suit au contexte http :
# Charger le module ModSecurityload_module modules/ngx_http_modsecurity_module.so;Modifiez le bloc serveur de votre site :
# Modifier la configuration Nginx de votre sitesudo vim /etc/nginx/sites-available/example.com.confAjoutez les directives ModSecurity à votre bloc serveur :
# Activer ModSecuritymodsecurity on;modsecurity_rules_file /etc/nginx/modsec/modsec.conf;Appliquez les modifications :
# Tester la configuration Nginxsudo nginx -t
# Recharger Nginx si le test est réussisudo systemctl reload nginx15.18. Conclusion
Section intitulée « 15.18. Conclusion »En implémentant ces mesures de sécurité, vous avez considérablement durci votre installation WordPress contre les menaces courantes. N’oubliez pas que la sécurité est un processus continu et que vous devez :
- Mettre régulièrement à jour le noyau WordPress, les thèmes et les extensions
- Surveiller vos journaux pour détecter les activités suspectes
- Effectuer des audits de sécurité réguliers
- Conserver des sauvegardes de votre site et de votre base de données
- Rester informé des nouvelles menaces de sécurité et des bonnes pratiques