968 lines
22 KiB
Markdown
968 lines
22 KiB
Markdown
<style>pre, table { font-size: 0.6em !important; }</style>
|
||
|
||
# Sécurité des applications Web
|
||
## William Petit - S.C.O.P. Cadoles
|
||
|
||
---
|
||
<!-- page_number: true -->
|
||
|
||
## La fondation OWASP
|
||
|
||
> Open Web Application Security Project
|
||
|
||
- Fondé en 2001
|
||
- Organisation internationale à but non lucratif
|
||
|
||
---
|
||
|
||
## Quelques projets en particulier
|
||
|
||
- [OWASP Top Ten](https://www.owasp.org/index.php/Category:OWASP_Top_Ten_Project) - Top 10 des failles impactant les applications Web
|
||
- [OWASP Code Review Guide](https://www.owasp.org/index.php/Category:OWASP_Code_Review_Project) - Guide de la revue de code appliquée à la sécurité
|
||
- [OWASP ASVS](https://www.owasp.org/index.php/Category:OWASP_Application_Security_Verification_Standard_Project) - Standard des vérifications de sécurité des applications Web
|
||
- [OWASP Webgoat](https://www.owasp.org/index.php/Category:OWASP_WebGoat_Project) - Application(s) volontairement faillible(s) illustrant les principales failles de sécurité actuelles.
|
||
|
||
---
|
||
|
||
## Les principales failles
|
||
|
||
---
|
||
|
||
## Epicfaild
|
||
|
||
https://forge.cadoles.com/wpetit/epicfaild
|
||
|
||
### Lancer avec Docker
|
||
```
|
||
docker run -it --rm -p 8888:8080 bornholm/epicfaild
|
||
|
||
# Puis ouvrir l'URL http://localhost:8888/
|
||
# dans votre navigateur
|
||
```
|
||
---
|
||
|
||
## OWASP WebGoat
|
||
|
||
https://github.com/WebGoat/WebGoat
|
||
|
||
### Lancer avec Docker
|
||
```
|
||
docker run -p 8080:8080 -it --rm webgoat/webgoat-8.0 /home/webgoat/start.sh
|
||
|
||
# Puis ouvrir l'URL http://localhost:8080/WebGoat/
|
||
# dans votre navigateur
|
||
```
|
||
---
|
||
|
||
## Injections SQL (SQLI)
|
||
|
||
### Pratique
|
||
|
||
> Epicfaild: Gate 3 et 4
|
||
> WebGoat: Injection Flaws (- XEE)
|
||
|
||
---
|
||
|
||
## Risques
|
||
|
||
- Vol de données
|
||
- Altération de données
|
||
- Prise de contrôle du serveur
|
||
|
||
---
|
||
|
||
## Mitigation
|
||
|
||
- Exécuter le moteur de base de données avec un utilisateur dédié.
|
||
- Valider TOUTES les entrées utilisateur.
|
||
- Utiliser des requêtes préparées.
|
||
- Installer un NIDS au niveau du serveur HTTP
|
||
|
||
---
|
||
|
||
## Contournement de la session
|
||
|
||
### Pratique
|
||
|
||
> Epicfaild: Gate 3
|
||
> WebGoat: Authentication Bypass
|
||
|
||
---
|
||
|
||
## Risques
|
||
|
||
- Vol de session
|
||
- Vol de données
|
||
- Prise de contrôle de l'application
|
||
|
||
---
|
||
|
||
## Mitigation
|
||
|
||
- Valider TOUTES les entrées utilisateurs
|
||
- Journaliser les origines des connexions
|
||
|
||
---
|
||
|
||
## Cross Site Scripting (XSS)
|
||
|
||
### Pratique
|
||
|
||
> Epicfaild: Gate 1
|
||
> WebGoat: Cross Site Scripting
|
||
|
||
---
|
||
|
||
## Risques
|
||
|
||
- Vol de sessions
|
||
- Hameçonnage
|
||
|
||
---
|
||
|
||
## Mitigation
|
||
|
||
- Valider TOUTES les entrées utilisateurs
|
||
- Assainir les données avant de faire leur rendu
|
||
|
||
---
|
||
|
||
## Mauvais contrôle des accès
|
||
|
||
### Pratique
|
||
|
||
> WebGoat: Access Control Flaws
|
||
|
||
---
|
||
|
||
## Risques
|
||
|
||
- Accès non autorisés à des fonctionnalités critiques
|
||
- Vol de données
|
||
- Prise de contrôle de l'application
|
||
|
||
---
|
||
|
||
## Mitigation
|
||
|
||
- Journaliser tous les accès à des ressources critiques (qui, quoi, quand, quel contexte ?)
|
||
- Utiliser une double authentification pour l'accès aux ressources critiques
|
||
|
||
> **Attention** L'obfuscation des accès n'est pas une méthode de sécurisation des points d'entrée.
|
||
|
||
---
|
||
|
||
## Fuite d'informations sensibles
|
||
|
||
### Pratique
|
||
|
||
```
|
||
Epicfaild: Gate 4/5
|
||
WebGoat: Insecure communication, Client Side/Client side filtering
|
||
```
|
||
|
||
---
|
||
|
||
## Risques
|
||
|
||
- Vol de données
|
||
|
||
---
|
||
|
||
## Mitigation
|
||
|
||
- Ne retourner à l'utilisateur que les données dont il a besoin (approche "frugale").
|
||
- Limiter la zone d'action de l'utilisateur à ses seuls besoins.
|
||
|
||
---
|
||
|
||
## Cross Site Request Forgery (CSRF)
|
||
|
||
### Pratique
|
||
|
||
> WebGoat: Request Forgeries
|
||
|
||
---
|
||
|
||
## Risques
|
||
|
||
- Hameçonnage
|
||
- Vol de session
|
||
- Vol d'identité
|
||
|
||
---
|
||
|
||
## Mitigation
|
||
|
||
- Utilisation de `nonce` (aussi appelé CSRF Token)
|
||
- Utilisation de requêtes `POST|PUT|DELETE` pour toutes les actions autres que la "consultation"
|
||
- S'assurer que les mécanismes de type "HTTP Method Override" ne sont pas activés en production ([Exemple pour Symfony3](http://symfony.com/doc/2.6/cookbook/routing/method_parameters.html#faking-the-method-with-method))
|
||
|
||
---
|
||
|
||
## Mauvaise politique de maintenance
|
||
|
||
### Pratique
|
||
|
||
> WebGoat: Vulnerable components
|
||
|
||
---
|
||
|
||
## Risques
|
||
|
||
Les risques dépendent du composant faillible...
|
||
|
||
---
|
||
|
||
## Mitigation
|
||
|
||
- Activer les mécanismes de mise à jour automatique
|
||
- Vérifier les mises à jour des librairies de manière automatisée.
|
||
- Suivre la publication des [CVE](https://cve.mitre.org/)/[NVD](https://nvd.nist.gov/)
|
||
|
||
---
|
||
|
||
## Métrologie applicative appliquée à la sécurité
|
||
|
||
### Méthodologie générale
|
||
### Modélisation de menace
|
||
### Identification des flux de données
|
||
### Les facteurs d'une bonne métrique
|
||
### Exemple d'outil: Prometheus
|
||
|
||
---
|
||
|
||
## Méthodologie générale
|
||
|
||
1. Définir le modèle de menace
|
||
2. Identifier et isoler les scénarios d'attaque pour les différentes menaces
|
||
3. Trouver les indicateurs "clés" pour ces scénarios i.e. identifier les métriques pertinentes pour la détection des comportements suspects
|
||
4. Mettre en place les sondes pour les métriques
|
||
5. Définir les seuils d'alerte et les réponses à apporter
|
||
|
||
---
|
||
|
||
## La modélisation de menace
|
||
|
||
- Identification des **dépendances externes**.
|
||
Exemple: _serveur GNU/Linux, base de données_
|
||
- Identification des **points d'entrées**
|
||
Exemple: _formulaire de contact, port de la base de données_
|
||
- Identification des **assets**
|
||
Exemple: _Comptes utilisateurs de l'application, données personnelles, droits d'accès_
|
||
- Identification des **niveaux de confiance**
|
||
Exemple: _Utilisateur anonyme, administrateur_
|
||
|
||
---
|
||
|
||
### Identification des flux de données
|
||
|
||
![center](./img/Data_flow2.jpg?)
|
||
|
||
---
|
||
|
||
## Les facteurs d'une bonne métrique
|
||
|
||
- **Concision** _Le domaine de mesure est il correctement défini ? La métrique n'essaye t-elle pas de mesurer trop de choses ?_
|
||
- **Fidélité** _La mesure est elle reproductible ? Mesure t-elle toujours la même chose ?_
|
||
- **Intégrité** _Le processus de mesure est il vulnérable à la falsification ?_
|
||
- **Utilité** _La métrique apporte elle une information utile au processus décisionnel ?_
|
||
|
||
---
|
||
|
||
## Exemple d'outil: Prometheus
|
||
|
||
### Téléchargement
|
||
|
||
https://prometheus.io/download/#prometheus
|
||
|
||
---
|
||
|
||
## Configuration générale
|
||
|
||
---
|
||
|
||
## Instrumentation de l'application
|
||
|
||
### Modèle de données
|
||
### Les différents types de métriques
|
||
### Les requêtes
|
||
|
||
---
|
||
|
||
## Modèle de données
|
||
|
||
Prometheus stocke des échantillons (mesures) sous la forme de **séries temporelles**. Il créait une nouvelle série pour chaque association **(nom_métrique, label1=value, label2=value, ...)**.
|
||
|
||
Chaque couple **(label, valeur)** est appelée **dimension** de la métrique.
|
||
|
||
|
||
**Représentation**
|
||
```
|
||
http_total_requests{ method="POST", path="/test" }
|
||
| name | labels |
|
||
```
|
||
---
|
||
|
||
## Les différents types de métriques
|
||
|
||
---
|
||
|
||
## Compteur (1)
|
||
|
||
Un compteur est une métrique dont la valeur ne peut faire qu'augmenter au cours du temps.
|
||
|
||
> **Exemple** Nombre total de connexions d'un compte sur un site
|
||
|
||
---
|
||
|
||
## Jauge
|
||
|
||
Une jauge est une métrique dont la valeur peut augmenter ou diminuer au cours du temps.
|
||
|
||
![center 50%](../img/jauge.jpg)
|
||
|
||
> **Exemple** La température d'une pièce
|
||
|
||
---
|
||
|
||
## Histogramme (1)
|
||
|
||
Un histogramme est une métrique répartissant les données dans des "seaux" (ou "buckets" en anglais) configurables et comptant le nombre total et par "paquet" d'échantillons ainsi que leur somme.
|
||
|
||
![center 70%](../img/histogram.png)
|
||
|
||
> **Exemple** Le temps de réponse des requêtes HTTP
|
||
|
||
---
|
||
|
||
## Histogramme (2)
|
||
|
||
### Scénario d'exemple
|
||
|
||
Soit la métrique `http_request_duration_seconds` un histogramme avec les "buckets" suivants: 0.5, 1, 2, 3, 5.
|
||
|
||
3 requêtes sont effectuées sur l'application avec des temps de 1s, 2s et 3s respectivements.
|
||
|
||
On aura sur `/metrics`:
|
||
|
||
```
|
||
http_request_duration_seconds_bucket{le="0.5"} 0
|
||
http_request_duration_seconds_bucket{le="1"} 1
|
||
http_request_duration_seconds_bucket{le="2"} 2
|
||
http_request_duration_seconds_bucket{le="3"} 3
|
||
http_request_duration_seconds_bucket{le="5"} 3
|
||
http_request_duration_seconds_bucket{le="+Inf"} 3
|
||
http_request_duration_seconds_sum 6
|
||
http_request_duration_seconds_count 3
|
||
```
|
||
---
|
||
|
||
## Les requêtes
|
||
|
||
---
|
||
|
||
## Types de données
|
||
|
||
- `scalar` _Un nombre à virgule flottante_
|
||
Exemple: `5.1`
|
||
|
||
- `instant vector` _Un ensemble de séries temporelles contenant un seul échantillon pour chaque série temporelle, toutes partageant le même horodatage._
|
||
Exemple: `http_request_duration_seconds`
|
||
|
||
- `range vector` _Un ensemble de séries temporelles contenant une gamme de points de données au fil du temps pour chaque série temporelle._
|
||
Exemple: `http_request_duration_seconds[5m]`
|
||
|
||
- `string` _Une chaine de caratères._
|
||
Exemple: `"hello world"`
|
||
---
|
||
|
||
## Les opérateurs
|
||
|
||
### Opérateurs arithmétiques
|
||
|
||
`+`, `-`, `*`, `/`, `%` (modulo), `^` (puissance)
|
||
|
||
### Opérateurs de comparaison
|
||
|
||
`==`, `!=`, `>`, `>=`, `<`, `<=`
|
||
|
||
### Opérateurs d'aggrégation
|
||
|
||
`sum`, `min`, `max`, `avg`, `stddev`, `stdvar`, `count`, `count_values`, `bottomk`, `topk`, `quantile`
|
||
|
||
### Opérateurs logiques
|
||
|
||
`and`, `or`, `unless`
|
||
|
||
|
||
_[Voir la documentation du projet](https://prometheus.io/docs/prometheus/latest/querying/operators/)_
|
||
|
||
---
|
||
|
||
## Fonctions
|
||
|
||
### Quelques exemples
|
||
|
||
- `rate(range vector)` Retourne la fréquence moyenne d'augmentation par seconde de la série temporelle dans l'espace de temps donné. À utiliser uniquement avec les compteurs.
|
||
- `time()` Retourne le nombre de secondes depuis l'Epoch Unix.
|
||
- `increase(range vector)` Retourne l'augmentation de la série temporelle dans l'interval de temps donné. À utiliser uniquement avec les compteurs.
|
||
|
||
Et aussi [histogram_quantile()](https://prometheus.io/docs/prometheus/latest/querying/functions/#histogram_quantile), [predict_linear()](https://prometheus.io/docs/prometheus/latest/querying/functions/#predict_linear()),...
|
||
|
||
_[Voir la documentation du projet](https://prometheus.io/docs/prometheus/latest/querying/functions/)_
|
||
|
||
|
||
---
|
||
|
||
## Configuration de l'`alertmanager`
|
||
|
||
### Téléchargement
|
||
|
||
https://prometheus.io/download/#alertmanager
|
||
|
||
---
|
||
|
||
## Écriture de règles d'alertes
|
||
|
||
---
|
||
|
||
## Exercice: métrologie orientée sécurité d'une application Symfony3
|
||
|
||
1. Créer une nouvelle application Symfony3 et configure une authentification de type "Basic Auth" sur une route.
|
||
2. Implémenter une `Listener` pour l'évènement `security.authentication.failure` ([voir ce tutoriel](https://www.brainvire.com/create-authentication-listener-symfony2/))
|
||
3. Installer et configurer le bundle [tweedegolf/prometheus-bundle](https://github.com/tweedegolf/prometheus-bundle)
|
||
4. Mettre en place une sonde pour détecter les tentatives répétées d'authentification échouées pour une adresse IP donnée.
|
||
5. Mettre en place une alerte lorsque le nombre d'authentifications échouées dépasse un certain seuil dans un espace de temps donné.
|
||
|
||
---
|
||
|
||
## Sécurité de l'infrastructure pour l'hébergement Web
|
||
|
||
### Sécurité et configuration du serveur GNU/Linux
|
||
### Configuration du serveur HTTP
|
||
### Monitoring
|
||
|
||
---
|
||
|
||
## Sécurité et configuration du serveur GNU/Linux
|
||
|
||
### Installation du serveur
|
||
### Politique d'accès et configuration SSH
|
||
### Règles de pare-feu
|
||
### Politique de sauvegarde
|
||
|
||
---
|
||
|
||
## Installation du serveur
|
||
|
||
---
|
||
|
||
## Règles générales de partitionnement (1)
|
||
|
||
- Utiliser [LVM](https://wiki.ubuntu.com/Lvm)
|
||
- ~300/500M pour `/boot`
|
||
- Partition séparée pour `/var` ( via un volume logique)
|
||
- Partition séparée pour `/home` (via un volume logique)
|
||
- Partition séparée pour `/` (via un volume logique)
|
||
- Garder de l'espace pour pouvoir agrandir au besoin une partition LVM
|
||
|
||
---
|
||
|
||
|
||
### Règles générales de partitionnement (2)
|
||
|
||
**Exemple** Pour 10G de disque
|
||
|
||
|Point de montage|Système de fichier|Taille|
|
||
|:-|:-|:-|
|
||
|`/boot`|ext4 (Primaire)|500M
|
||
|`/`|ext4 (LVM)|4G (~30/40%)
|
||
|`/home`|ext4 (LVM)|1G (10%)|
|
||
|`/var`|ext4 (LVM)|3G (~30/40%)|
|
||
|`swap`|swap (LVM)| round(sqrt(RAM) < swap < 2*RAM |
|
||
|
||
Et garder ~10% d'espace libre pour pouvoir agrandir un volume logique au besoin.
|
||
|
||
---
|
||
|
||
## Activation des mises à jour automatiques
|
||
|
||
Si à l'installation l'option n'est pas proposée (sur Debian et dérivées)
|
||
|
||
```bash
|
||
apt-get install unattended-upgrades apt-listchanges
|
||
```
|
||
[Voir la documentation Debian pour plus d'informations](https://wiki.debian.org/UnattendedUpgrades)
|
||
|
||
---
|
||
|
||
## Politique d'accès et configuration SSH
|
||
|
||
---
|
||
|
||
## Installation du serveur OpenSSH
|
||
|
||
```bash
|
||
apt install openssh-server
|
||
```
|
||
---
|
||
|
||
## Désactivation de l'authentification SSH avec l'utilisateur `root`
|
||
|
||
```bash
|
||
vim /etc/ssh/sshd_config
|
||
# ...
|
||
# PermitRootLogin no
|
||
# ...
|
||
systemctl restart ssh
|
||
```
|
||
---
|
||
|
||
## Désactivation de la connexion SSH avec un mot de passe
|
||
|
||
```bash
|
||
vim /etc/ssh/sshd_config
|
||
# ...
|
||
# PasswordAuthentication no
|
||
# ...
|
||
systemctl restart ssh
|
||
```
|
||
---
|
||
|
||
## Restreindre les utilisateurs et/ou groupes autorisés à se connecter en SSH
|
||
|
||
```bash
|
||
vim /etc/ssh/sshd_config
|
||
# ...
|
||
# AllowUsers jdoe bob
|
||
# AllowGroups jdoe bob
|
||
# ...
|
||
systemctl restart ssh
|
||
```
|
||
---
|
||
|
||
## Augmenter la taille des clés SSH du serveur
|
||
|
||
```bash
|
||
vim /etc/ssh/sshd_config
|
||
# ...
|
||
# ServerKeyBits 2048
|
||
# ...
|
||
rm /etc/ssh/ssh_host_*
|
||
systemctl restart ssh
|
||
```
|
||
---
|
||
|
||
## Créer des comptes utilisateurs avec un mot de passe expiré (1)
|
||
|
||
```bash
|
||
adduser <uid>
|
||
chage -d 0 <uid>
|
||
```
|
||
Puis penser à copier la clé SSH publique de l'utilisateur dans `/home/<uid>/.ssh/authorized_keys`.
|
||
|
||
---
|
||
|
||
## Créer des comptes utilisateurs avec un mot de passe expiré (2)
|
||
|
||
Attention, OpenSSH est très "chatouilleux" avec les droits sur les répertoires `.ssh` et le fichier `.ssh/authorized_keys`. En cas de doute:
|
||
|
||
```bash
|
||
chmod go-w <uid> <uid>/.ssh
|
||
chmod 600 <uid>/.ssh/authorized_keys
|
||
chown <uid> $HOME/.ssh/authorized_keys
|
||
```
|
||
|
||
---
|
||
|
||
## Règles de pare-feu
|
||
|
||
---
|
||
|
||
## Installation d'UFW
|
||
|
||
> Uncomplicated Firewall
|
||
|
||
```bash
|
||
apt install ufw
|
||
```
|
||
---
|
||
|
||
## Activation du pare-feu
|
||
|
||
```bash
|
||
iptables -L # Afficher les règles iptables
|
||
ufw allow 22/tcp # Pour éviter de perdre la connexion SSH actuelle
|
||
ufw enable # Activer le pare-feu
|
||
iptables -L # Vérifier l'application des règles
|
||
```
|
||
---
|
||
|
||
## Vérifier le statut des règles
|
||
|
||
```bash
|
||
ufw status verbose
|
||
```
|
||
---
|
||
|
||
## Gestion des règles par défaut
|
||
|
||
```bash
|
||
ufw default deny # Refuser tous les paquets par défaut
|
||
ufw default allow # Accepter tous les paquets par défaut
|
||
ufw default allow outgoing # Accepter les connexions sortantes par défaut
|
||
ufw default allow ingoing # Accepter les connexions entrantes par défaut
|
||
```
|
||
|
||
---
|
||
|
||
## Ajouter des règles
|
||
|
||
```bash
|
||
# Connexions entrantes
|
||
|
||
# Autoriser toutes les connexions depuis 192.168.0.4 sur le port 22
|
||
ufw allow from 192.168.0.4 to any port 22
|
||
# Refuser toutes les connexions depuis 207.46.232.182
|
||
ufw deny from 207.46.232.182
|
||
|
||
# Connexions sortantes
|
||
|
||
# Autoriser les connexions UDP sur le port 53 (requêtes DNS)
|
||
ufw allow out 53/udp
|
||
# Autoriser les connexions MySQL (3306/tcp) vers l'adresse 192.168.0.43
|
||
ufw allow out to 192.168.0.43 port mysql
|
||
```
|
||
|
||
---
|
||
|
||
## Supprimer une règle
|
||
|
||
```bash
|
||
ufw status numbered # Afficher les identifiants des règles
|
||
ufw delete <id> # Supprimer une règle par son identifiant
|
||
```
|
||
---
|
||
|
||
## Exercice
|
||
|
||
Avec UFW, configurer votre serveur pour:
|
||
|
||
- Refuser toutes les connexions entrantes/sortantes par défaut
|
||
- Autoriser la connexion SSH uniquement depuis l'IP de votre poste de travail et celle d'un de vos collègues présent à la formation.
|
||
- Autoriser les connexions sortantes HTTP/HTTPS vers l'adresse 192.168.0.30 (i.e. un serveur fournissant une API REST utilisée par votre application)
|
||
- Autoriser les connexions sortantes MongoDB vers l'adresse 192.168.0.45 (i.e. une base de données MongoDB utilisée par votre application)
|
||
|
||
---
|
||
|
||
## Politique de sauvegarde
|
||
|
||
---
|
||
|
||
## Installation de rsync/rsnapshot
|
||
|
||
### Sur le serveur
|
||
|
||
```bash
|
||
apt install rsync
|
||
```
|
||
|
||
### Sur le client
|
||
|
||
```bash
|
||
apt install rsnapshot rsync
|
||
```
|
||
---
|
||
|
||
## Configuration de rsnapshot (1)
|
||
|
||
### Sur le serveur
|
||
|
||
- Créer un utilisateur dédié à la sauvegarde
|
||
- S'assurer que le compte de sauvegarde a les droits de lecture sur les répertoires à sauvegarder
|
||
- Déployer une clé SSH pour le compte de sauvegarde (à utiliser sur le client)
|
||
|
||
---
|
||
|
||
## Configuration de rsnapshot (2)
|
||
|
||
### Sur le client
|
||
|
||
```bash
|
||
# Éditer la configuration
|
||
vim /etc/rsnapshot.conf
|
||
|
||
# Définition de la rotation des sauvegardes
|
||
#
|
||
# retain hourly 24 # Une sauvegarde par heure hourly.0 -> hourly.23
|
||
# retain daily 7 # Si le rép. existe, copie hourly.23 vers daily.0
|
||
# retain weekly 4 # Si le rép. existe, copie daily.6 vers weekly.0
|
||
# retain monthly 12 # Si le rép. existe, copie weekly.3 vers monthly.0
|
||
|
||
# Vérifier la configuration
|
||
rsnapshot configtest
|
||
|
||
# Exécuter un "dry-run"
|
||
rsnapshot -t hourly # Ou daily/weekly/monthly
|
||
|
||
# Configurer les tâches CRON
|
||
crontab -e
|
||
|
||
# @hourly rsnapshot hourly
|
||
# @daily rsnapshot daily
|
||
# @weekly rsnapshot weekly
|
||
# @monthly rsnapshot monthly
|
||
|
||
```
|
||
---
|
||
|
||
## Restaurer une sauvegarde
|
||
|
||
```bash
|
||
rsync -av \
|
||
/var/cache/rsnapshot/<level>.<iteration> \
|
||
user@server-host:/path/to/dest
|
||
```
|
||
|
||
---
|
||
|
||
## Configuration du serveur HTTP
|
||
|
||
### Apache2
|
||
### Certificats TLS/SSL
|
||
|
||
---
|
||
|
||
## Apache2
|
||
|
||
---
|
||
|
||
## Installation
|
||
|
||
```bash
|
||
apt install apache2
|
||
```
|
||
---
|
||
|
||
## Désactivation des entêtes d'informations
|
||
|
||
```bash
|
||
vim /etc/apache2/apache2.conf
|
||
# ...
|
||
ServerSignature Off
|
||
ServerTokens Prod
|
||
# ...
|
||
systemctl reload apache2
|
||
```
|
||
---
|
||
|
||
## Désactivation de l'indexation automatique des dossiers
|
||
|
||
```bash
|
||
vim /etc/apache2/apache2.conf
|
||
# ...
|
||
<Directory /var/www/html>
|
||
Options -Indexes
|
||
</Directory>
|
||
# ...
|
||
systemctl reload apache2
|
||
```
|
||
|
||
---
|
||
|
||
## Désactivation des modules inexploités
|
||
|
||
```bash
|
||
# Afficher les directives de chargement des modules
|
||
grep LoadModule /etc/apache2/mods-enabled/*.load
|
||
|
||
# Désactiver un module
|
||
rm /etc/apache2/mods-enabled/<module>.load
|
||
|
||
# Recharger la configuration Apache2
|
||
systemctl reload apache2
|
||
```
|
||
|
||
Modules souvent inclus mais peu utilisés: _mod_imap, mod_include, mod_info, mod_userdir, mod_autoindex_
|
||
|
||
---
|
||
|
||
## Activation du module `mod_evasive`
|
||
|
||
```bash
|
||
# Installation du module
|
||
apt install apache2-mod-evasive
|
||
# Activer le module (si non activé par défaut)
|
||
a2enmod evasive
|
||
# Configurer le module
|
||
vim /etc/apache2/mods-enabled/evasive.conf
|
||
# Recharcher la configuration Apache2
|
||
systemctl reload apache2
|
||
```
|
||
---
|
||
|
||
## Activation du module `mod_security`
|
||
|
||
```bash
|
||
# Installation du module
|
||
apt install libapache2-mod-security2
|
||
|
||
# Activer le module (si non activé par défaut)
|
||
a2enmod security2
|
||
|
||
# Configurer le module
|
||
vim /etc/modsecurity/modsecurity.conf-recommended
|
||
|
||
# Activer la configuration recommandée
|
||
mv /etc/modsecurity/modsecurity.conf-recommended \
|
||
/etc/modsecurity/modsecurity.conf
|
||
|
||
# Recharcher la configuration Apache2
|
||
systemctl reload apache2
|
||
```
|
||
---
|
||
|
||
## SSL/TLS
|
||
|
||
---
|
||
|
||
## Générer un certificat autosigné
|
||
|
||
```bash
|
||
openssl req \
|
||
-x509 \
|
||
-newkey rsa:4096 \
|
||
-keyout key.pem \
|
||
-out cert.pem \
|
||
-days 365 \
|
||
-nodes
|
||
```
|
||
|
||
---
|
||
|
||
## Utilisation du certificat avec Apache2
|
||
|
||
```apache
|
||
# /etc/apache2/sites-enabled/my-site.conf
|
||
|
||
NameVirtualHost *:80
|
||
<VirtualHost *:80>
|
||
ServerName www.example.com
|
||
Redirect / https://secure.example.com/
|
||
</VirtualHost>
|
||
|
||
<VirtualHost _default_:443>
|
||
ServerName secure.example.com
|
||
DocumentRoot /var/www/html
|
||
SSLEngine On
|
||
SSLCertificateFile /path/to/cert.pem
|
||
SSLCertificateKeyFile /path/to/key.pem
|
||
# etc...
|
||
</VirtualHost>
|
||
```
|
||
|
||
---
|
||
|
||
## Tester la configuration TLS/SSL
|
||
|
||
Avec le projet [TestSSL](https://testssl.sh/)
|
||
|
||
```bash
|
||
# Récupération du script
|
||
wget -O- https://testssl.sh/ > testssl.sh
|
||
|
||
# Rendre exécutable le script
|
||
chmod +x ./testssl.sh
|
||
|
||
# Tester une URL
|
||
./testssl.sh <URL>
|
||
```
|
||
---
|
||
|
||
## Supervision du système
|
||
|
||
### Installation, configuration et usage de fail2ban (NIDS)
|
||
### Supervision du système avec Prometheus
|
||
|
||
---
|
||
|
||
## Installation de fail2ban
|
||
|
||
```bash
|
||
apt install fail2ban
|
||
```
|
||
---
|
||
|
||
## Configuration
|
||
|
||
### Principaux fichiers et répertoires
|
||
|
||
- `/etc/fail2ban/fail2ban.conf` - Fichier de configuration général
|
||
- `/etc/fail2ban/jail.conf` - Définition des "jails" par défaut
|
||
- `/etc/fail2ban/jail.d` - Définitions de "jails" additionnelles
|
||
- `/etc/fail2ban/filter.d` - Filtres d'activation des "jails"
|
||
- `/etc/fail2ban/action.d` - Définition des actions potentielles à exécuter en cas d'activation d'une "jail".
|
||
|
||
_La personnalisation de la configuration se fait en créant des fichiers `<nom_fichier>.local`._
|
||
|
||
---
|
||
|
||
## Exercice
|
||
|
||
Configurer fail2ban pour bannir les IP à l'origine de tentatives de connexion échouées sur un site Wordpress.
|
||
|
||
1. Installer et configurer Wordpress sur votre serveur (voir page suivante)
|
||
2. Créer une `failregex` pour détecter les tentatives échouées de connexion à votre Wordpress. Quelle est la différence dans les logs entre un échec et un succès ?
|
||
3. Créer votre filtre `/etc/fail2ban/filter.d/wordpress.conf` avec votre expression régulière. Pour tester:
|
||
```
|
||
fail2ban-regex --print-all-match <logfile> \
|
||
/etc/fail2ban/filter.d/<filter>.conf
|
||
```
|
||
4. Créer votre propre section "wordpress" dans le fichier `/etc/fail2ban/jail.local` en vous inspirant des exemples déjà présents.
|
||
|
||
|
||
---
|
||
|
||
## Préparation
|
||
|
||
- Sur votre machine virtuelle, installer Wordpress et MySQL
|
||
```bash
|
||
apt install wordpress mysql-server
|
||
```
|
||
- Activer Wordpress
|
||
```bash
|
||
ln -s /usr/share/wordpress /var/www/html/wordpress
|
||
```
|
||
- Copier la configuration Wordpress par défaut
|
||
```bash
|
||
cp /usr/share/wordpress/wp-config-sample.php \
|
||
/etc/wordpress/config-<votre_ip>.php
|
||
```
|
||
- Créer un compte utilisateur dans la base de données MySQL
|
||
```bash
|
||
mysql -u root -p
|
||
mysql> CREATE DATABASE wordpress;
|
||
mysql> GRANT ALL PRIVILEGES ON wordpress.* TO 'wordpress'@'localhost'
|
||
IDENTIFIED BY '<password>';
|
||
mysql> quit
|
||
```
|
||
- Modifier la configuration pour que Wordpress utilise sa base de données (fichier `/etc/wordpress/config-<votre_ip>.php`)
|
||
---
|
||
|
||
## Supervision du système avec Prometheus
|
||
|
||
## Exercice
|
||
|
||
- Sur votre machine virtuelle, installer l'exporteur de métriques [`Node Exporter`](https://github.com/prometheus/node_exporter/) et créer un nouveau service [`systemd`](https://doc.ubuntu-fr.org/creer_un_service_avec_systemd) pour celui ci.
|
||
- Installer et configurer un serveur Apache2 avec un VirtualHost exposant via la directive `ProxyPass` du module [`mod_proxy`](https://httpd.apache.org/docs/current/mod/mod_proxy.html).
|
||
- Mettre en place une règle d'alerte sur votre instance Prometheus locale afin de prévenir le remplissage du disque de votre serveur via la fonction [`predict_linear()`](https://prometheus.io/docs/prometheus/latest/querying/functions/#predict_linear()) (par exemple 4 heures ?)
|
||
|
||
---
|
||
|
||
# Licence
|
||
|
||
## CC BY-NC-SA 3.0 FR
|
||
|
||
[Creative Commons - Attribution - Pas d’Utilisation Commerciale - Partage dans les Mêmes Conditions 3.0 France](https://creativecommons.org/licenses/by-nc-sa/3.0/fr/)
|