Guide pas-à-pas : installation, durcissement, CrowdSec, Cloudflare — prêt pour la production.
HowTo — Installer & sécuriser WordPress sur Ubuntu (Apache2)
Résumé pas-à-pas prêt pour la production : Apache/PHP/MySQL, HTTPS, durcissement, CrowdSec, Cloudflare.
- Mise à jour système — 
sudo apt update && sudo apt upgrade -y. - Stack web — Installez Apache2, PHP-FPM et extensions, MariaDB. Activez
        
proxy_fcgi,http2,headers,rewrite. - Base de données — Créez la BDD/utilisateur (
utf8mb4), sécurisez MariaDB (mysql_secure_installation). - WordPress — Téléchargez, décompressez dans 
/var/www/html/wordpress, droitswww-data, dossiers755, fichiers644. - VirtualHost — Pointez le 
DocumentRoot, activez le site etrewrite, redémarrez Apache. - HTTPS — Certbot (Let’s Encrypt) en mode Apache, vérifiez le renouvellement auto.
 - Durcissement — Headers de sécurité, HSTS (après HTTPS partout),
        
DISALLOW_FILE_EDIT, permissions strictes, blocage exécution PHP dansuploads. - SSH & système — Port custom, interdiction root/password, 
UFW“Apache Full”, cron système pourwp-cron.php. - CrowdSec — Installez moteur + collection Apache, ajoutez un bouncer (iptables ou Cloudflare).
 - Cloudflare — Mode SSL Full (strict), règles de cache/admin,
        
mod_remoteippour IP cliente, WAF/Rate Limiting. - Backups & monitoring — Archive fichiers + dump SQL quotidiens, stockage off-site, logs Apache/MySQL/CrowdSec, staging pour tests.
 
Pré-requis
- Un serveur Ubuntu (22.04 LTS ou +)
 - Accès sudo
 - Un nom de domaine pointant vers le serveur
 
Mettez à jour le système :
sudo apt update && sudo apt upgrade -y
    
  1. Installer Apache2, PHP et MySQL/MariaDB
Installer Apache & PHP
sudo apt install apache2 php php-mysql libapache2-mod-php -y
    
    
    Installer MariaDB (ou MySQL)
sudo apt install mariadb-server mariadb-client -y
    
    
    Sécurisez MariaDB :
sudo mysql_secure_installation
    
  2. Créer la base de données WordPress
Se connecter à MariaDB/MySQL :
sudo mysql -u root -p
    
    
    Créer la BDD et l’utilisateur (adaptez MOT_DE_PASSE) :
CREATE DATABASE wordpress DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
CREATE USER 'wordpress'@'localhost' IDENTIFIED BY 'MOT_DE_PASSE';
GRANT ALL PRIVILEGES ON wordpress.* TO 'wordpress'@'localhost';
FLUSH PRIVILEGES;
EXIT;
    
  3. Télécharger et installer WordPress
cd /tmp
wget https://wordpress.org/latest.tar.gz
tar -xvzf latest.tar.gz
sudo mv wordpress /var/www/html/
    
    
    Permissions :
sudo chown -R www-data:www-data /var/www/html/wordpress
sudo find /var/www/html/wordpress/ -type d -exec chmod 755 {} \;
sudo find /var/www/html/wordpress/ -type f -exec chmod 644 {} \;
    
  4. Configurer Apache (VirtualHost)
Exemple de fichier : /etc/apache2/sites-available/example.com.conf
<VirtualHost *:80>
    ServerName example.com
    ServerAlias www.example.com
    DocumentRoot /var/www/html/wordpress
    <Directory /var/www/html/wordpress>
        AllowOverride All
        Require all granted
    </Directory>
    ErrorLog ${APACHE_LOG_DIR}/example.com-error.log
    CustomLog ${APACHE_LOG_DIR}/example.com-access.log combined
</VirtualHost>
    
    
    Activer le site et les modules :
sudo a2ensite example.com.conf
sudo a2enmod rewrite
sudo systemctl restart apache2
    
  5. Finaliser l’installation WordPress
Ouvrez votre navigateur sur http://example.com et suivez l’assistant d’installation (choisir le
      titre du site, admin, mot de passe).
6. Durcissement & Sécurité — Guide complet
Le durcissement minimal limite la surface d’attaque. Voici un guide détaillé de niveau « très bon ».
6.1 Système : mises à jour et utilisateur non-root
sudo apt update && sudo apt upgrade -y
sudo adduser monadmin
sudo usermod -aG sudo monadmin
    
    
    6.2 Sécuriser SSH
Éditez /etc/ssh/sshd_config :
Port 2222
PermitRootLogin no
PasswordAuthentication no
PubkeyAuthentication yes
    
    
    sudo systemctl restart ssh
    
    
    6.3 Apache — headers et protections
Créer /etc/apache2/conf-available/security-headers.conf :
<IfModule mod_headers.c>
  Header always set X-Content-Type-Options "nosniff"
  Header always set X-Frame-Options "SAMEORIGIN"
  Header always set X-XSS-Protection "1; mode=block"
  Header always set Referrer-Policy "strict-origin-when-cross-origin"
  Header always set Content-Security-Policy "default-src 'self';"
</IfModule>
    
    
    sudo a2dismod autoindex
sudo a2enmod headers rewrite ssl
sudo a2enconf security-headers
sudo systemctl reload apache2
    
    
    6.4 PHP — durcir php.ini
Editez le php.ini chargé par Apache (vérifier via phpinfo()) :
upload_max_filesize = 512M
post_max_size = 512M
memory_limit = 512M
max_execution_time = 600
max_input_time = 600
expose_php = Off
disable_functions = exec,passthru,shell_exec,system,proc_open,popen,curl_multi_exec,parse_ini_file,show_source
    
    
    sudo systemctl restart apache2
    
    
    6.5 MySQL — sécuriser
sudo mysql_secure_installation
    
    
    Et lier MySQL à 127.0.0.1 si besoin, interdire local_infile etc.
6.6 Permissions fichiers WordPress
sudo chown -R www-data:www-data /var/www/html/wordpress
sudo find /var/www/html/wordpress/ -type d -exec chmod 750 {} \;
sudo find /var/www/html/wordpress/ -type f -exec chmod 640 {} \;
sudo chmod 600 /var/www/html/wordpress/wp-config.php
    
    
    6.7 Restreindre exécution PHP dans uploads et wp-includes
<FilesMatch "\.php$">
    Require all denied
</FilesMatch>
    
    
    6.8 .htaccess sécurisé (extraits)
# BEGIN WordPress
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>
# END WordPress
# Bloquer fichiers sensibles
<FilesMatch "(\.htaccess|\.htpasswd|wp-config\.php|php.ini|readme\.html|license\.txt)">
    Require all denied
</FilesMatch>
# Interdire exécution PHP dans uploads
<Directory "/var/www/html/wordpress/wp-content/uploads">
    <FilesMatch "\.php$">
        Require all denied
    </FilesMatch>
</Directory>
    
    
    6.9 Désactiver l’édition de fichiers depuis l’admin WordPress
define('DISALLOW_FILE_EDIT', true);
define('FORCE_SSL_ADMIN', true);
define('WP_AUTO_UPDATE_CORE', true);
    
    
    6.10 UFW (pare-feu)
sudo apt install ufw -y
sudo ufw allow OpenSSH
sudo ufw allow "Apache Full"
sudo ufw enable
sudo ufw status
    
    
    6.11 Backups & monitoring
Exemple rapide :
tar -czf /backup/wordpress-files-$(date +%F).tar.gz /var/www/html/wordpress
mysqldump -u wordpress -p wordpress > /backup/wordpress-db-$(date +%F).sql
    
  7. Installer & configurer CrowdSec
CrowdSec est un moteur de détection collaboratif :
curl -s https://packagecloud.io/install/repositories/crowdsec/crowdsec/script.deb.sh | sudo bash
sudo apt install -y crowdsec crowdsec-firewall-bouncer-iptables
sudo systemctl enable --now crowdsec
sudo cscli hub update
sudo cscli collections install crowdsecurity/apache2
    
    
    Vérifier les décisions :
sudo cscli decisions list
    
  8. Intégration avec Cloudflare
Cloudflare agit comme proxy, WAF et CDN :
- Créez un compte Cloudflare et ajoutez votre domaine.
 - Changez vos DNS pour utiliser ceux de Cloudflare.
 - Activez SSL/TLS : Full (strict).
 - Activez le WAF, Rate Limiting pour 
/wp-login.phpet/xmlrpc.php. 
Autoriser les IP Cloudflare sur le serveur
for ip in $(curl -s https://www.cloudflare.com/ips-v4); do
  sudo ufw allow from $ip to any port 80,443 proto tcp
done
for ip in $(curl -s https://www.cloudflare.com/ips-v6); do
  sudo ufw allow from $ip to any port 80,443 proto tcp
done
    
    
    Cloudflare Bouncer (CrowdSec → Cloudflare)
sudo cscli bouncers add cloudflare-bouncer
sudo apt install -y crowdsec-cloudflare-bouncer
sudo nano /etc/crowdsec/bouncers/crowdsec-cloudflare-bouncer.yaml
    
    
    Exemple de configuration du bouncer :
api_key: "VOTRE_API_KEY_CROWDSEC"
cloudflare:
  api_token: "VOTRE_CLOUDFLARE_API_TOKEN"
  account_id: "VOTRE_ACCOUNT_ID"
  zone_id: "VOTRE_ZONE_ID"
default_action: "ban"
    
  9. Sauvegardes & monitoring
Bonnes pratiques :
- Planifier sauvegardes quotidiennes (base + fichiers).
 - Stocker les backups hors du serveur (S3, rclone, stockage distant).
 - Surveiller logs : 
/var/log/apache2/,/var/log/mysql/,/var/log/crowdsec/. 
Annexe — Script d’hardening automatisé (Bash)
Ce script automatise le durcissement d’Ubuntu, d’Apache, de MariaDB/MySQL, de PHP, l’installation de CrowdSec,
      l’intégration Cloudflare (IP réelles + UFW), ainsi que les permissions et protections minimales pour WordPress. À
      lancer en root (ou via sudo) sur Ubuntu 22.04+.
Exécution :nano harden-wp.sh → collez le code →
      chmod +x harden-wp.sh → sudo ./harden-wp.sh
    
#!/usr/bin/env bash
# Durcissement Ubuntu + Apache + MariaDB/MySQL + PHP + CrowdSec + Cloudflare + WordPress
set -euo pipefail
IFS=$'\n\t'
STEP="init"
trap 'echo "❌ Erreur à l’étape: ${STEP}" >&2' ERR
# ────────────────────────────────────────────────────────────────────────────────
# Vérifications préalables
# ────────────────────────────────────────────────────────────────────────────────
if [[ ${EUID} -ne 0 ]]; then
  echo "❌ Ce script doit être exécuté en root (sudo)." >&2
  exit 1
fi
if ! grep -qi "ubuntu" /etc/os-release; then
  echo "⚠️  Distribution non-ubuntu détectée ; poursuite à tes risques." >&2
fi
UBU_VER="$(. /etc/os-release && echo "$VERSION_ID")"
if [[ "${UBU_VER%.*}" -lt 22 ]]; then
  echo "⚠️  Ubuntu ${UBU_VER} détecté (< 22.04). Certaines étapes peuvent différer." >&2
fi
# ────────────────────────────────────────────────────────────────────────────────
# Entrées utilisateur
# ────────────────────────────────────────────────────────────────────────────────
read -rp "➡️  Chemin du site WordPress [/var/www/html/wordpress] : " WP_PATH
WP_PATH="${WP_PATH:-/var/www/html/wordpress}"
read -rp "➡️  Nom de la base de données WordPress [wordpress] : " WP_DB
WP_DB="${WP_DB:-wordpress}"
read -rp "➡️  Nom de l’utilisateur WordPress [wordpress] : " WP_USER
WP_USER="${WP_USER:-wordpress}"
read -rsp "➡️  Mot de passe de l’utilisateur WordPress : " WP_PASS
echo
# Compte SQL administrateur (si root en unix_socket)
read -rp "➡️  Créer un admin SQL dédié (recommandé) [oui/Non] : " CREATE_SQL_ADMIN
CREATE_SQL_ADMIN="${CREATE_SQL_ADMIN:-Non}"
if [[ "$CREATE_SQL_ADMIN" =~ ^[Oo]([Uu][Ii])?$ ]]; then
  read -rp "   ↳ Nom admin SQL [admin_local] : " SQL_ADMIN
  SQL_ADMIN="${SQL_ADMIN:-admin_local}"
  read -rsp "   ↳ Mot de passe admin SQL : " SQL_ADMIN_PASS
  echo
fi
# ────────────────────────────────────────────────────────────────────────────────
# Mise à jour & paquets
# ────────────────────────────────────────────────────────────────────────────────
STEP="apt update/upgrade + install"
export DEBIAN_FRONTEND=noninteractive
apt-get update -y
apt-get upgrade -y
apt-get install -y apache2 mariadb-server php libapache2-mod-php php-mysql \
  php-cli php-curl php-xml php-gd php-mbstring unzip curl ufw \
  software-properties-common git wget lsb-release ca-certificates
# ────────────────────────────────────────────────────────────────────────────────
# Apache — sécurité & en-têtes
# ────────────────────────────────────────────────────────────────────────────────
STEP="Apache headers & hardening"
a2dismod -f autoindex || true
a2enmod headers
SEC_HDR="/etc/apache2/conf-available/security-headers.conf"
if [[ -f "$SEC_HDR" ]]; then
  cp -a "$SEC_HDR" "${SEC_HDR}.bak-$(date +%F-%H%M%S)"
fi
cat > "$SEC_HDR" <<'EOF'
<IfModule mod_headers.c>
  # Baseline prudente (évite de casser l’admin WP ; ajuste selon besoins)
  Header always set X-Content-Type-Options "nosniff"
  Header always set X-Frame-Options "SAMEORIGIN"
  Header always set Referrer-Policy "strict-origin-when-cross-origin"
  Header always set Permissions-Policy "accelerometer=(), geolocation=(), microphone=(), camera=()"
  # X-XSS-Protection est obsolète mais parfois demandé par des scanners
  Header always set X-XSS-Protection "1; mode=block"
  # CSP légère (ne pas bloquer l’admin par défaut)
  # Ajuste si tu as des fontes/scripts externes (CSP strict sinon)
  Header always set Content-Security-Policy "default-src 'self'; img-src 'self' data: https:; style-src 'self' 'unsafe-inline' https:; script-src 'self' 'unsafe-inline' 'unsafe-eval' https:; font-src 'self' data: https:; frame-ancestors 'self';"
</IfModule>
EOF
SEC_TUNE="/etc/apache2/conf-available/security-tuning.conf"
if [[ -f "$SEC_TUNE" ]]; then
  cp -a "$SEC_TUNE" "${SEC_TUNE}.bak-$(date +%F-%H%M%S)"
fi
cat > "$SEC_TUNE" <<'EOF'
ServerTokens Prod
ServerSignature Off
EOF
a2enconf security-headers
a2enconf security-tuning
# ────────────────────────────────────────────────────────────────────────────────
# PHP — durcissement (sans casser WP)
# ────────────────────────────────────────────────────────────────────────────────
STEP="PHP hardening"
PHPINI="$(php -r 'echo php_ini_loaded_file();')"
if [[ -z "${PHPINI:-}" || ! -f "$PHPINI" ]]; then
  echo "❌ Impossible de localiser php.ini" >&2
  exit 1
fi
cp -a "$PHPINI" "${PHPINI}.bak-$(date +%F-%H%M%S)"
set_ini() {
  local key="$1"; shift
  local val="$*"
  if grep -Eiq "^\s*${key}\s*=" "$PHPINI"; then
    sed -i "s|^\s*${key}\s*=.*|${key} = ${val}|" "$PHPINI"
  else
    echo -e "\n${key} = ${val}" >> "$PHPINI"
  fi
}
set_ini upload_max_filesize 32M
set_ini post_max_size 34M
set_ini expose_php Off
# ⚠️ Liste conservatrice ; éviter de bloquer des extensions WP
set_ini disable_functions "exec,passthru,shell_exec,system,proc_open,popen,curl_multi_exec,parse_ini_file,show_source"
systemctl reload apache2
# ────────────────────────────────────────────────────────────────────────────────
# MariaDB/MySQL — sécurisation & BDD WordPress
# ────────────────────────────────────────────────────────────────────────────────
STEP="MySQL/MariaDB secure + DB"
# Détecter plugin root
ROOT_PLUGIN="$(mysql -NBe "SELECT plugin FROM mysql.user WHERE User='root' AND Host='localhost';" || true)"
# Renforcer config serveur (si MariaDB Debian layout)
MYSQLOPT="/etc/mysql/mariadb.conf.d/50-server.cnf"
if [[ -f "$MYSQLOPT" ]]; then
  cp -a "$MYSQLOPT" "${MYSQLOPT}.bak-$(date +%F-%H%M%S)"
  grep -q '^bind-address' "$MYSQLOPT" && sed -i "s/^bind-address.*/bind-address = 127.0.0.1/" "$MYSQLOPT" || echo "bind-address = 127.0.0.1" >> "$MYSQLOPT"
  grep -q '^local_infile' "$MYSQLOPT" || echo "local_infile = 0" >> "$MYSQLOPT"
  grep -q '^skip-symbolic-links' "$MYSQLOPT" || echo "skip-symbolic-links" >> "$MYSQLOPT"
  grep -q '^secure_file_priv' "$MYSQLOPT" || echo "secure_file_priv = /var/lib/mysql-files" >> "$MYSQLOPT"
  systemctl restart mariadb
fi
# Si root utilise unix_socket, on n’écrase pas son auth ; sinon, on renforce
if [[ "${ROOT_PLUGIN:-}" == "unix_socket" ]]; then
  echo "ℹ️ root@localhost utilise 'unix_socket' → pas de changement d’auth."
  if [[ "$CREATE_SQL_ADMIN" =~ ^[Oo]([Uu][Ii])?$ ]]; then
    mysql -uroot <<MYSQL
CREATE USER IF NOT EXISTS '${SQL_ADMIN}'@'localhost' IDENTIFIED BY '${SQL_ADMIN_PASS}';
GRANT ALL PRIVILEGES ON *.* TO '${SQL_ADMIN}'@'localhost' WITH GRANT OPTION;
FLUSH PRIVILEGES;
MYSQL
  fi
else
  echo "⚠️ root n’est pas en unix_socket ; laisse tel quel (pas de reset password par défaut)."
fi
# Créer BDD + user WP
if mysql -uroot -e "SELECT 1" >/dev/null 2>&1; then
  SQL_ROOT="mysql -uroot"
else
  # si root protégé par mot de passe, demander
  read -rsp "➡️  Mot de passe root MySQL/MariaDB (pour créer la BDD) : " MYSQL_ROOT_PASS
  echo
  SQL_ROOT="mysql -uroot -p${MYSQL_ROOT_PASS}"
fi
$SQL_ROOT <<MYSQL
CREATE DATABASE IF NOT EXISTS \`${WP_DB}\` CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
CREATE USER IF NOT EXISTS '${WP_USER}'@'localhost' IDENTIFIED BY '${WP_PASS}';
GRANT ALL PRIVILEGES ON \`${WP_DB}\`.* TO '${WP_USER}'@'localhost';
FLUSH PRIVILEGES;
MYSQL
# ────────────────────────────────────────────────────────────────────────────────
# UFW — politique défensive
# ────────────────────────────────────────────────────────────────────────────────
STEP="UFW"
ufw --force reset
ufw default deny incoming
ufw default allow outgoing
ufw allow OpenSSH
ufw allow "Apache Full"
# Limiter brute force SSH
ufw limit OpenSSH
ufw --force enable
# ────────────────────────────────────────────────────────────────────────────────
# CrowdSec — moteur + collections utiles
# ────────────────────────────────────────────────────────────────────────────────
STEP="CrowdSec"
curl -s https://packagecloud.io/install/repositories/crowdsec/crowdsec/script.deb.sh | bash
apt-get install -y crowdsec crowdsec-firewall-bouncer-iptables
systemctl enable --now crowdsec crowdsec-firewall-bouncer
# Collections pertinentes
cscli hub update || true
cscli collections install crowdsecurity/apache2 || true
cscli collections install crowdsecurity/ssh || true
cscli collections install crowdsecurity/linux || true
systemctl reload crowdsec || true
# ────────────────────────────────────────────────────────────────────────────────
# Cloudflare — UFW + IP réelle via mod_remoteip
# ────────────────────────────────────────────────────────────────────────────────
STEP="Cloudflare IPs + mod_remoteip"
CF_V4="$(curl -s https://www.cloudflare.com/ips-v4)"
CF_V6="$(curl -s https://www.cloudflare.com/ips-v6)"
# UFW allow depuis Cloudflare (HTTP/HTTPS)
while read -r ip; do [[ -n "$ip" ]] && ufw allow from "$ip" to any port 80,443 proto tcp || true; done <<< "$CF_V4"
while read -r ip; do [[ -n "$ip" ]] && ufw allow from "$ip" to any port 80,443 proto tcp || true; done <<< "$CF_V6"
# IP réelle dans Apache
a2enmod remoteip
REMOTEIP="/etc/apache2/conf-available/remoteip-cloudflare.conf"
if [[ -f "$REMOTEIP" ]]; then
  cp -a "$REMOTEIP" "${REMOTEIP}.bak-$(date +%F-%H%M%S)"
fi
{
  echo "RemoteIPHeader CF-Connecting-IP"
  while read -r ip; do [[ -n "$ip" ]] && echo "RemoteIPTrustedProxy ${ip}"; done <<< "$CF_V4"
  while read -r ip; do [[ -n "$ip" ]] && echo "RemoteIPTrustedProxy ${ip}"; done <<< "$CF_V6"
} > "$REMOTEIP"
a2enconf remoteip-cloudflare
# Utiliser l’IP client (%a) dans les logs (pas l’IP Cloudflare)
APACHE_ENV="/etc/apache2/apache2.conf"
cp -a "$APACHE_ENV" "${APACHE_ENV}.bak-$(date +%F-%H%M%S)"
if ! grep -q 'LogFormat .*%a' "$APACHE_ENV"; then
  sed -i "s/LogFormat \\"%h %l %u/LogFormat \\"%a %l %u/" "$APACHE_ENV"
fi
# ────────────────────────────────────────────────────────────────────────────────
# WordPress — restrictions uploads + permissions
# ────────────────────────────────────────────────────────────────────────────────
STEP="WordPress perms & uploads"
if [[ -d "$WP_PATH" ]]; then
  chown -R www-data:www-data "$WP_PATH"
  find "$WP_PATH" -type d -exec chmod 750 {} \;
  find "$WP_PATH" -type f -exec chmod 640 {} \;
  if [[ -f "$WP_PATH/wp-config.php" ]]; then chmod 600 "$WP_PATH/wp-config.php"; fi
  UPLOADS_DIR="$WP_PATH/wp-content/uploads"
  if [[ -d "$UPLOADS_DIR" ]]; then
    HTACCESS="$UPLOADS_DIR/.htaccess"
    if [[ -f "$HTACCESS" ]]; then cp -a "$HTACCESS" "${HTACCESS}.bak-$(date +%F-%H%M%S)"; fi
    cat > "$HTACCESS" <<'EOF'
# Interdire l’exécution de PHP dans uploads
<FilesMatch "\.php$">
  Require all denied
</FilesMatch>
EOF
  fi
else
  echo "⚠️  Chemin WordPress introuvable : ${WP_PATH} (étape WP ignorée)"
fi
# ────────────────────────────────────────────────────────────────────────────────
# Redémarrages finaux
# ────────────────────────────────────────────────────────────────────────────────
STEP="Restart services"
systemctl restart apache2
systemctl restart mariadb || true
echo
echo "✅ Durcissement terminé."
echo "   • WP path : ${WP_PATH}"
echo "   • DB      : ${WP_DB}"
echo "   • User    : ${WP_USER}"
echo "ℹ️ Pense à ajuster la CSP si tu ajoutes des fontes/CDN externes."
    
    
    Note : La CSP fournie est volontairement « légère » pour éviter de casser l’admin. Renforce-la si tu ajoutes des CDN (fonts, scripts) en déclarant les sources nécessaires.
FAQ
Quelle est la configuration minimale requise pour installer WordPress sur Ubuntu ?
Un serveur Ubuntu 22.04+ avec accès sudo, Apache2 (ou Nginx), PHP 7.4+ (idéalement PHP 8.x) avec les extensions PHP-MySQL, et une base de données MariaDB/MySQL. Assurez-vous d’avoir un nom de domaine pointant vers le serveur.
Comment créer la base de données et l’utilisateur WordPress ?
Connectez-vous à MySQL/MariaDB puis exécutez :
      CREATE DATABASE wordpress DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
      CREATE USER 'wordpress'@'localhost' IDENTIFIED BY 'MOT_DE_PASSE';
      GRANT ALL PRIVILEGES ON wordpress.* TO 'wordpress'@'localhost'; FLUSH PRIVILEGES;
    
Que mettre dans le fichier wp-config.php pour se connecter à la base ?
Dans wp-config.php renseignez : DB_NAME (nom BDD),
      DB_USER, DB_PASSWORD, et DB_HOST (généralement localhost).
      Vérifiez l’absence d’erreur de format (guillmets, points-anglès) et que le mot de passe n’inclut pas d’artefacts.
    
Pourquoi j’obtiens « Error establishing a database connection » malgré MySQL en cours d’exécution ?
Vérifiez : 1) identifiants dans wp-config.php (user/mdp/host), 2) que
      l’utilisateur a les privilèges sur la BDD, 3) que MySQL accepte les connexions depuis localhost et 4)
      pas d’erreurs de syntaxe dans wp-config. Testez avec mysql -u wordpress -p -h localhost wordpress.
    
Quelles permissions appliquer aux fichiers WordPress pour la sécurité ?
Recommander : propriétaire www-data:www-data, dossiers 750,
      fichiers 640, et wp-config.php en 600. Commandes :
      sudo chown -R www-data:www-data /var/www/html/wordpress + find pour chmod.
    
Comment empêcher l’exécution de fichiers PHP dans /wp-content/uploads ?
Ajoutez une règle Apache / .htaccess pour interdire les .php dans le dossier uploads,
      par exemple :
      <Directory "/var/www/html/wordpress/wp-content/uploads"> <FilesMatch "\.php$"> Require all denied </FilesMatch> </Directory>.
    
Que fait CrowdSec et comment l’intégrer à Apache ?
CrowdSec est un moteur de détection collaboratif qui identifie et partage des
      comportements malveillants. Installez le binaire + collection Apache
      (cscli collections install crowdsecurity/apache2) et ajoutez un bouncer (iptables ou Cloudflare) pour
      appliquer les décisions.
Dois-je activer Cloudflare et comment gérer les IPs ?
Oui, Cloudflare apporte CDN, WAF et SSL. Mettez le mode SSL sur Full
        (strict). Sur le serveur, autorisez uniquement les plages IP Cloudflare (ips-v4/ips-v6) dans le
      pare-feu pour 80/443, et configurez la réelle IP client via le module mod_remoteip si nécessaire.
Comment sauvegarder et restaurer rapidement WordPress ?
Sauvegarde simple : archive des fichiers + dump MySQL. Exemple :
      tar -czf /backup/wp-files-$(date +%F).tar.gz /var/www/html/wordpress et
      mysqldump -u wordpress -p wordpress > /backup/wp-db-$(date +%F).sql. Testez régulièrement la
      restauration sur un environnement de staging.
    
Conclusion
En suivant ce guide vous aurez installé WordPress sur Ubuntu et mis en place un niveau de sécurité robuste (mise à jour, permissions, PHP durci, pare-feu, CrowdSec et Cloudflare). N’oubliez pas de tester vos sauvegardes et de surveiller régulièrement les logs.












