La première chose à faire pour réaliser cette infrastructure, c’est de mettre en place un serveur web. En pratique, n’importe quelle offre de base suffira : comme les seuls utilisateurs du site sous WordPress seront ses administrateurs (car la version publique utilisera le CDN de Netlify), pas besoin d’opter pour une offre proposant d’énormes ressources. Pour mes tests, j’ai opté pour l’offre « Kimsufi » proposée par OVH à 5€ / mois, mais n’importe quelle offre proposant un accès SSH au serveur web devrait faire l’affaire.
Voilà une proposition de configuration pour déployer le serveur avec un minimum de sécurité.
Montage du serveur web
- Mise à jour du système Debian
- Installation de Nginx
- Installation de MariaDB (système de gestion de base de données)
- Installation de PHP
- Création d’une base de données pour WordPress
- Téléchargement et installation de WordPress
- Configuration de WordPress
- Configuration du domaine
- Sécurisation du serveur
1. Mise à jour de Debian
sudo apt update
sudo apt upgrade
2. Installation de Nginx
sudo apt install nginx
3. Installation de MariaDB
sudo apt install mariadb-server
4. Installation de PHP et des dépendances nécessaires au fonctionnement du plugin de génération de fichiers statiques
sudo apt install php-fpm php-mysql php-xml curl
5. Création d’une base de données
Evidemment à cette étape, mettez un mot de passe sécurisé 😉
sudo mysql -u root -p
----
CREATE DATABASE wordpress;
CREATE USER 'wordpressuser'@'localhost' IDENTIFIED BY 'password';
GRANT ALL PRIVILEGES ON wordpress.* TO 'wordpressuser'@'localhost';
FLUSH PRIVILEGES;
EXIT;
6. Téléchargement et dépôt de WordPress dans son répertoire
cd /tmp
wget <https://wordpress.org/latest.tar.gz>
tar xzvf latest.tar.gz
sudo cp -a /tmp/wordpress/. /var/www/html/wordpress
rm latest.tar.gz
7. Configuration de Nginx pour WordPress
sudo nano /etc/nginx/sites-available/wordpress
Ajoutez la configuration Nginx appropriée, en indiquant le nom de domaine que vous souhaitez utiliser pour accéder à votre serveur privé.
N’oubliez pas de vérifier les chemins vers les bons fichiers de configurations (notamment pour localiser PHP)
server {
listen 80;
server_name nomdedomaineduserveurprive.com;
root /var/www/html/wordpress;
index index.php index.html index.htm;
location / {
try_files $uri $uri/ /index.php$is_args$args;
}
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/var/run/php/php8.2-fpm.sock;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
}
Activez le fichier en créant un lien symbolique :
sudo ln -s /etc/nginx/sites-available/wordpress /etc/nginx/sites-enabled/
Vérifiez la configuration de Nginx et redémarrez le service :
sudo nginx -t
sudo systemctl restart nginx
Configuration de WordPress
Configurez les permissions et finalisez l’installation de WordPress :
sudo chown -R www-data:www-data /var/www/html
cd /var/www/html
sudo mv wp-config-sample.php wp-config.php
sudo nano wp-config.php
Modifiez les lignes de la base de données avec vos informations.
8. Configuration du domaine
Configurez votre domaine pour pointer vers l’adresse IP de votre serveur Debian (DNS de type A vers IP).
La mise en place de HTTPS avec Let’s Encrypt :
Une fois le pointage des DNS effectué, installez Certbot pour mettre en place un certificat SSL afin de chiffrer les données (même si le serveur est privé, on n’est jamais trop prudents !)
sudo apt install certbot python3-certbot-nginx
Configuration de Nginx
Avant de lancer Certbot, assurez-vous que votre configuration Nginx a un server_name
correctement défini avec votre nom de domaine.
Ouvrez le fichier de configuration de votre site :
sudo nano /etc/nginx/sites-available/wordpress
Assurez-vous que la ligne server_name
est correctement définie :
server_name votredomaine.fr www.votredomaine.fr;
Remplacez votredomaine.fr
par votre nom de domaine réel.
Testez la configuration Nginx pour les erreurs :
sudo nginx -t
Rechargez Nginx pour appliquer les changements :
sudo systemctl reload nginx
Obtenir et Installer le Certificat SSL
Exécutez Certbot :
sudo certbot --nginx -d votredomaine.fr -d www.votredomaine.fr
Remplacez votredomaine.fr
et www.votredomaine.fr
par votre nom de domaine et sous-domaine.
Suivez les instructions : Certbot vous demandera de fournir une adresse e-mail pour les notifications de renouvellement et de consentir aux conditions d’utilisation.
Choisissez si vous voulez rediriger tout le trafic HTTP vers HTTPS : Certbot vous demandera si vous souhaitez rediriger automatiquement tout le trafic HTTP vers HTTPS. Il est recommandé de choisir cette option pour une meilleure sécurité.
Vérification Automatique du Renouvellement
Les certificats Let’s Encrypt sont valides pour 90 jours. Certbot crée une tâche cron pour automatiser le processus de renouvellement.
- Vérifiez la tâche cron de Certbot :
sudo systemctl status certbot.timer
Pour tester le processus de renouvellement :
sudo certbot renew --dry-run
Vérification du Certificat
Après avoir installé le certificat, vous pouvez vérifier son fonctionnement en accédant à votre site via https://
. Vous devriez voir un cadenas dans la barre d’adresse de votre navigateur, indiquant une connexion sécurisée.
9. Sécurisation du serveur
Modification de la configuration de ssh
nano /etc/ssh/sshd_config
Contenu du fichier sshd_config (lignes à ajouter à la fin du fichier si vous voulez tester rapidement, ou à modifier là où c’est pertinent). Vous n’êtes pas obligés de recopier les commentaires, ils sont juste là à titre informatif / pédagogique 😉
# Config custom
# Modifie le port (mettez la valeur de votre choix)
Port 22001
# Cette ligne définit le port sur lequel le service SSH doit écouter.
# Ici, il est réglé sur 22001 au lieu du port par défaut 22.
# Cela peut ajouter une couche de sécurité en masquant le service SSH derrière un port non standard.
# Temps maximal pour se connecter
LoginGraceTime 30
# Spécifie le temps en secondes que le client a pour s'authentifier auprès du serveur SSH.
# Après 30 secondes, si l'authentification n'est pas réussie, la connexion sera automatiquement fermée.
# Interdit le login root
PermitRootLogin no
# Cette option empêche l'utilisateur root de se connecter directement au serveur via SSH.
# C'est une mesure de sécurité importante pour empêcher les accès non autorisés au compte administrateur.
# Whitelist des utilisateurs autorisés
AllowUsers nomdevotreutilisateur
# Cette ligne spécifie quels utilisateurs sont autorisés à se connecter via SSH.
# Remplacez 'nomdevotreutilisateur' par le nom réel de l'utilisateur autorisé.
# Seuls les utilisateurs listés ici pourront se connecter.
Match user nomdevotreutilisateur
# Cette directive commence une section conditionnelle.
# Les paramètres qui suivent cette ligne seront appliqués uniquement à l'utilisateur spécifié ici.
ChrootDirectory /srv/www
# Cette option restreint l'utilisateur à un sous-système chroot à partir du répertoire spécifié, ici '/srv/www'.
# L'utilisateur ne pourra pas accéder aux fichiers en dehors de ce répertoire.
ForceCommand internal-sftp
# Force l'exécution d'une commande spécifique au moment de la connexion SSH.
# Ici, elle force l'utilisation du sous-système SFTP et empêche l'accès au shell interactif.
# Désactivation des portforwarding
AllowTcpForwarding no
GatewayPorts no
X11Forwarding no
# Ces lignes désactivent plusieurs formes de redirection de ports :
# - 'AllowTcpForwarding no' désactive le transfert de port TCP.
# - 'GatewayPorts no' empêche les utilisateurs distants de transférer des ports TCP à travers le serveur.
# - 'X11Forwarding no' désactive le transfert du protocole graphique X11, ce qui est important pour la sécurité sur un serveur non graphique.
Redémarrer SSH
service ssh restart
En cas de problème de connexion s’assurer que cette ligne est présente et décommentée :
Subsystem sftp internal-sftp
Installation de Fail2Ban
Fail2ban est un soft qui permet de configurer le pare-feu iptables de Linux à la volée. Top pour se protégrer des attaques par force brute. Cf ce topo bien documenté : https://buzut.fr/installer-et-parametrer-fail2ban/
sudo apt install fail2ban
nano /etc/fail2ban/jail.local
Contenu de /etc/fail2ban/jail.local :
(ne pas oublier d’indiquer le port ssh précédemment renseigné)
[DEFAULT]
# Ban les IPs pour 10 heures
bantime = 36000
# Cherche les infractions dans les 10 dernières minutes
findtime = 600
# L'IP est bannie si elle a échoué 5 fois
maxretry = 5
# Action à exécuter après le ban
banaction = iptables-multiport
# Email pour les notifications
destemail = your-email@example.com
sendername = Fail2Ban
# Niveau d'information dans les logs
loglevel = INFO
# Chemin vers les logs
logtarget = /var/log/fail2ban.log
# Jail spécifique pour SSH sur le port personnalisé
[sshd]
enabled = true
port = 22001
filter = sshd
logpath = /var/log/auth.log
maxretry = 3
# Protection spécifique pour Nginx
[nginx-http-auth]
enabled = true
filter = nginx-http-auth
port = http,https
logpath = /var/log/nginx/error.log
maxretry = 5
[nginx-botsearch]
enabled = true
port = http,https
filter = nginx-botsearch
logpath = /var/log/nginx/access.log
maxretry = 2
Installation et configuration de ufw (firewall)
UFW est un firewall qui permet de gérer les iptables de façons + simple : pour en savoir plus -> https://doc.ubuntu-fr.org/ufw
sudo apt install ufw
Configuration des règles :
Ne pas oublier d’autoriser le port SSH que vous avez personnalisé au début !
ufw status verbose
ufw allow in 80/tcp
ufw allow in 443/tcp
ufw allow in 22001/tcp
ufw allow out 80/tcp
ufw allow out 443/tcp
ufw allow out 22001/tcp
ufw allow out 25/tcp
ufw allow out 53/udp
ufw enable
Pour vérifier la config, il suffit de tester un scan des ports : https://hackertarget.com/nmap-online-port-scanner/
10. Restreindre l’accès au serveur web
Dernière étape et non des moindres : empêcher n’importe qui de se connecter à votre site internet ; car oui, votre site est censé être privé, donc inaccessible aux personnes qui ne font pas partie de votre organisation.
Pour ce faire, 2 options simples sont possibles : une restriction par adresse IP et/ou une authentifaction HTTP basic.
Restriction par Adresse IP
Si vous avez une adresse IP statique, vous pouvez configurer votre serveur web (Nginx ou Apache) pour n’autoriser l’accès qu’à cette adresse IP.
Pour Nginx :
Ouvrez le fichier de configuration de votre site. Par exemple :
sudo nano /etc/nginx/sites-available/wordpress
Ajoutez une directive allow
et deny
:
location / {
allow votre_adresse_ip;
deny all;
# Les autres directives...
}
Remplacez votre_adresse_ip
par votre adresse IP statique.
Vérifiez la configuration et redémarrez Nginx :
sudo nginx -t
sudo systemctl restart nginx
Authentification HTTP Basic
Une autre méthode consiste à utiliser l’authentification HTTP Basic pour protéger votre site.
Créez un fichier de mot de passe :
sudo htpasswd -c /etc/nginx/.htpasswd utilisateur
Remplacez utilisateur
par le nom d’utilisateur que vous souhaitez utiliser.
Modifiez le fichier de configuration de Nginx :
Ajoutez les lignes suivantes à la configuration de votre site :
sudo nano /etc/nginx/sites-available/wordpress
Modifier les lignes suivantes dans le fichier :
location / {
try_files $uri $uri/ /index.php$is_args$args;
auth_basic "Zone protégée";
auth_basic_user_file /etc/nginx/.htpasswd;
}
Enfin, redémarrez Nginx.
sudo systemctl restart nginx
Les autres solutions (que je ne développerai pas ici)
Utiliser un VPN
Si vous souhaitez un niveau de sécurité plus élevé, envisagez de configurer un VPN. Vous pouvez configurer votre serveur pour n’accepter les connexions qu’à partir d’un réseau VPN auquel vous êtes connecté.
Maintenance Mode ou Plugin de Restriction
Pour une solution basée sur WordPress, vous pouvez utiliser un plugin pour mettre votre site en mode maintenance ou pour restreindre l’accès à certains utilisateurs ou rôles. Des plugins comme « WP Maintenance Mode » ou « Restricted Site Access » peuvent être utiles.
Et voilà, c’est tout pour l’instant.
Prochaine étape : Installer et configurer WordPress sur votre domaine privé.