TP6 : Sécurisation du service web public - Durionleponey/AdminII GitHub Wiki
[WIP] utilisation de gtp4o pour la relecture et la correction
Auteurs
- De Henau Dudley
- Gendebien Jonas
- Clarembaux Robin
Date de réalisation : 27/03/25
2. Sécurisation du serveur
- Conteneurisation : Nginx, PHP, MariaDB dans Docker, isolation des services.
- Ports exposés : uniquement le port 80 (HTTP).
- Accès DB : uniquement en interne, pas d’exposition directe.
- SSL manquant : trafic HTTP visible par tout le monde.
3. Sécurisation des données
3.1. Isolation de la base de données
- Création d'un autre réseau dans le docker-compose pour isoler la DB.
- Nginx est uniquement connecté au réseau principal (ex: monreseau).
- PHP est connecté aux deux réseaux : monreseau (avec Nginx) et monreseau2 (avec MariaDB).
- MariaDB n'est connecté qu'au réseau monreseau2.
- Ainsi, Nginx peut communiquer avec PHP, PHP peut communiquer avec MariaDB, mais Nginx ne peut pas accéder directement à la base de données.
- En cas de compromission de Nginx, cela limite l'attaque à PHP et empêche l'accès direct à MariaDB.
Procédure de validation de l'isolation
-
Depuis le conteneur
php
, pingmariadb
: docker exec -it php ping mariadb -
Depuis le conteneur
web
, pingmariadb
: docker exec -it web ping mariadb
3.2. Configuration d'un utilisateur non privilégié
Validation de l’isolation des droits entre services
Objectif
S'assurer que le serveur web (Nginx) ne peut pas effectuer d’opérations dangereuses (ex: INSERT, DELETE, DROP) sur la base de données MariaDB.
Contexte
- Un utilisateur
wt-user@php
est créé via un script au démarrage de MariaDB. - Il a uniquement le droit
SELECT
sur la basewoodytoys
.
Procédure de validation
-
Depuis le conteneur
php
, se connecter à MariaDB avecwt-user
: docker exec -it php mysql -u wt-user -p -h mariadb woodytoys -
Tester une requête
SELECT
(doit réussir) :SELECT * FROM products;
-
Tester une requête
INSERT
(doit échouer) :INSERT INTO products (product_name, product_price) VALUES ('loooool', 999);
Résultat attendu
- Les requêtes
INSERT
etDROP
doivent échouer avec une erreurAccess denied
. - Seules les requêtes
SELECT
doivent être autorisées pour cet utilisateur depuis le conteneurphp
.
3.3. Backup de la DB
- Le répertoire
/var/lib/mysql
du conteneur MariaDB contient toutes les données. - Ce dossier est monté via un bind mount, ce qui garantit que les données sont stockées sur l’hôte.
(volumes: - mariadb_data:/var/lib/mysql)
3.4. Logs de la DB
Docker logs -f mariadb
ou en interne
docker exec -it mariadb bash cd /var/log ls
4. Sécurisation des communications avec HTTPS
4.1. HTTPS via un certificat auto-signé
4.1.1. Génération du certificat auto-signé avec OpenSSL
sudo openssl req -x509 -nodes -days 365 \
-newkey rsa:4096 \
-keyout certificate/nginx-selfsigned.key \
-out certificate/nginx-selfsigned.crt
{: .question }
Que pense votre navigateur du certificat utilisé ? Pourquoi ? Expliquez la problématique qui est ici mise en évidence.
Le navigateur affiche un avertissement indiquant que la connexion n’est pas sécurisée.
Cela est dû au fait que le certificat est auto-signé, c’est-à-dire qu’il n’a pas été émis par une autorité de certification reconnue.
La communication est bien chiffrée, mais le navigateur ne fait pas confiance à l'identité du serveur.
www
4.1.2. Configuration de Nginx en HTTPS pour le virtualhost Extrait du nginx.conf
:
events {}
http {
# 🔹 Définir le format de log personnalisé
log_format log_per_virtualhost '[$host] $remote_addr [$time_local] $status '
'"$request" $body_bytes_sent';
# 🔹 Logs globaux (utilisé aussi dans les server blocks)
access_log /dev/stdout log_per_virtualhost;
error_log /dev/stderr;
server {
if ($host = www.crash.greenvault.eu) {
return 301 https://$host$request_uri;
} # managed by Certbot
listen 80;
server_name www.crash.greenvault.eu;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl;
server_name www.crash.greenvault.eu;
ssl_certificate /etc/letsencrypt/live/www.crash.greenvault.eu/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/www.crash.greenvault.eu/privkey.pem; # managed by Certbot
root /var/www/crash;
index index.php index.html;
access_log /dev/stdout log_per_virtualhost;
location ~* \.php$ {
fastcgi_pass php:9000;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
}
}
www
4.2. Obtention d’un certificat Let’s Encrypt pour le site Certificat généré via certbot :
sudo certbot --nginx -d www.crash.greenvault.eu
{: .question }
/var/log/letsencrypt/letsencrypt.log
1. Examinez les logs dans nginx
: qu’est-ce qui a changé ?
2. Vérifiez votre configuration Nginx a maintenant :
ssl_certificate /etc/letsencrypt/live/www.crash.greenvault.eu/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/www.crash.greenvault.eu/privkey.pem;
3. Vérifiez si votre site possède à présent un certificat signé par Let's Encrypt
4. Examinez le certificat reçu avec OpenSSL
openssl x509 -in /etc/letsencrypt/live/www.crash.greenvault.eu/fullchain.pem -text -noout
test.crash.greenvault.eu
5. Statut HTTPS du second Virtual Host : Si ce vhost n’a pas de certificat, il retournera une erreur HTTPS.
- Ajouter le vhost dans
certbot
:
sudo certbot --nginx -d test.crash.greenvault.eu