# Docker - Doc Technique
Groupe : xxx / xxx
## I - Définition
#### La virtualisation
La virtualisation est une technologie utilisable dans le but de créer des représentations virtuelles de serveurs, de stockage, de réseaux et d'autres machines physiques.
#### La conteneurisation
La conteneurisation consiste à rassembler le code du logiciel et tous ses composants, bibliothèques, frameworks et autres dépendances, de manière à les isoler dans leur propre conteneur.
#### Docker
Docker est un système d'exploitation pour l'éxécution de conteneurs. Il fournit un ensemble de commandes simples pour concevoir, démarrer ou arrêter des conteneurs.
#### LoadBalancing
Le LoadBalancing désigne le processus de répartition d'un ensemble de tâches sur un ensemble de ressources, dans le but d'en rendre le traitement global plus efficace.
## II - Pré-requis
- Un ordinateur ou une machine virtuelle sous Ubuntu 22.02
- Un compte administrateur ou root
- Un accès à internet
#### Schéma de l'architecture souhaitée :

## III - Installation
Mettre à jour la machine
```bash
sudo apt update && sudo apt full-upgrade
```
Installer docker
```bash
apt install docker docker.io docker-compose
usermod -aG docker $USER
chmod 666 /run/docker.sock
```
## IV - Fonctionnalités
1) Fais une liste des images docker.
```bash
docker image ls
```
2) Créer un conteneur docker a partir d'une image nginx, l'execute en arrière plan et lui attribue un nom.
```bash
docker run -dit --name NAME --net=bridge nginx
```
3) Permet d'inspecter les propriétés d'un conteneur.
```bash
docker inspect NAME
```
4) Démarrer un conteneur.
```bash!
docker start NAME
```
5) Permet d'ouvrir un terminal sur le conteneur.
```bash
docker exec -it NAME /bin/bash
```
6) Fais une liste des réseaux virtuels.
```bash
docker network ls
```
7) Créer un nouveau réseau en mode bridge.
```bash
docker network create -d bridge NETWORK_NAME
```
8) Créer un nouveau réseau, avec une adresse réseau précise.
```bash
docker network create -d bridge --subnet 172.123.0.0/16 NETWORK_NAME
```
9) Créer un conteneur docker a partir d'une image nginx, l'éxécute en arrière plan et lui attribue un réseau virtuelle.
```bash
docker run -dit --name NAME --network=NETWORK_NAME nginx
```
10) Permet de connecter un conteneur à un réseau.
```bash
docker network connect NETWORK_NAME NAME
```
11) Permet de déconnecter un conteneur d'un réseau.
```bash
docker network disconnect NETWORK_NAME NAME
```
12) Connecte le conteneur a un réseau avec adresse ip donnée.
```bash
docker network connect NETWORK_NAME --ip IP NAME
```
13) Permet d'afficher les logs d'un conteneur.
```bash
docker logs NAME
```
14) Effectuer ce raccourcis pour quitter le container sans le fermer.
```bash
Ctrl+PQ
```
## V - Fonctionnement
### A - Création des réseaux
1) Pour mettre en place l'architecture réseau, nous allons commencer par créer nos 3 réseaux virtuelles (wan, dmz1 et dmz2).
```bash
docker network create --subnet 172.16.0.0/24 wan
docker network create --subnet 172.16.10.0/24 dmz1
docker network create --subnet 172.16.20.0/24 dmz2
```
***
### B - Création des conteneurs
1) Nous allons maintenant créer les 4 premiers conteneurs de notre site web, en respectant l'architecture réseau.
```bash
docker run -dit --name serverProxy --hostname serverProxy --network=dmz1 --ip=172.16.10.30 -p 80:80 nginx
docker network connect wan --ip=172.16.0.30 serverProxy
docker run -dit --name server1 --hostname server1 --network=dmz1 --ip=172.16.10.10 nginx
docker network connect dmz2 --ip=172.16.20.10 server1
docker run -dit --name server2 --hostname server2 --network=dmz1 --ip=172.16.10.20 nginx
docker network connect dmz2 --ip=172.16.20.20 server2
docker run -dit --name serverBackup --hostname serverBackup --network=dmz2 --ip=172.16.20.40 debian
```
***
### C - Configuration du server reverse proxy
1) Nous allons désormais configurer notre serveur proxy. On commencera donc par se connecter à notre conteneur.
```bash
docker exec -it serverProxy /bin/bash
```
2) Comme aucun éditeur n'est présent sur la machine, nous commencerons par installer l'éditeur `nano`.
```bash
apt update && apt install nano -y
```
3) Nous allons maintenant pouvoir ouvir le fichier de configuration de nginx.
```bash
nano /etc/nginx/conf.d/default.conf
```
4) En premier lieu, nous ajouterons un bloc `upstream` en haut de notre fichier pour rédiriger vers nos deux serveurs. Par défault la configuration du proxy est `roundrobin` nous n'avons donc rien besoin d'indiquer en plus.
```txt
upstream rproxy {
server server1;
server server2;
}
```
5) Nous modifierons également le bloc `location /` dans le bloc `server` tel que ci-dessous pour indiquer de rediriger tout notre domaine vers le proxy.
```txt
server {
# ...
location / {
proxy_pass http://rproxy;
}
# ...
}
```
6) Enfin nous allons redémarrer nginx pour appliquer la configuration
```bash
service nginx restart
```
7) Comme nous utilisons un conteneur docker, celui-ci s'est coupé après l'arrêt de nginx. Nous allons donc devoir redémarrer le conteneur serverProxy
```bash
docker start serverProxy
```
8) Nous allons désormais vérifier la configuration du server proxy, pour cela nous allons modifier le contenu des deux fichiers webs pour vérifier le load balancing
```bash
docker exec server1 bash -c "echo server1 > /var/www/html/index.html"
docker exec server2 bash -c "echo server2 > /var/www/html/index.html"
curl 172.16.0.30 # x4
```

***
### D - Mise en place de la synchronisation des fichiers
Nous allons maintenant mettre en place la synchronisation des fichiers sur nos deux serveurs web. Nous recommencerons donc les étapes 1, 4 et 5 avec `server1` et le `server2` à la place de $NAME.
1) Nous commencerons par installer un serveur SSH sur nos serveur web. Il sera également nécessaire de le démarrer car il ne démarrera pas automatiquement.
```bash
docker exec $NAME bash -c "apt update && apt install openssh-server -y"
docker exec $NAME service ssh start
```
2) Pour réaliser notre connexion SSH automatiquement, nous aurons besoin d'une paire de clés. Nous utiliserons donc le module `ssh-keygen` pour les créer. Nous créerons également au préalable le dossier `.ssh` qui contiendra notre clé car ce dernier n'existe pas par défaut.
```bash
docker exec serverBackup bash -c "apt update && apt install keychain -y"
docker exec serverBackup mkdir -m700 /root/.ssh
docker exec serverBackup ssh-keygen -t rsa -b 4096 -f /root/.ssh/id_rsa -N "" -q
```
3) Maintenant que nous avons nos clés, nous allons pouvoir ajouté la clé publique à chacun de nos serveurs web. Nous créerons également au préalable le dossier `.ssh` sur chacun des serveurs car ces derniers n'existent pas par défaut. Enfin nous attribuerons les droits 600 sur le fichier pour que celui puisse fonctionner correctement.
```bash
docker exec $NAME mkdir -m700 /root/.ssh
docker exec $NAME bash -c "echo $(docker exec serverBackup cat /root/.ssh/id_rsa.pub) >> /root/.ssh/authorized_keys"
docker exec $NAME chmod 600 /root/.ssh/authorized_keys
```
4) Maintenant que nous avons configurer la communication entre les machines, nous allons récupérer, nous récupérer le contenue d'un des sites web, qu'il pourra ensuite partager.
```bash
docker exec serverBackup bash -c "scp -o StrictHostKeyChecking=accept-new -pqr root@server1:/var/www/html /root/html"
```
5) Pour executer notre commande de synchronisation périodiquement, nous allons utiliser le module `cron`. Nous allons donc l'installer.
```bash
docker exec serverBackup apt install cron nano -y
```
6) Pour ajouter une nouvelle instruction cron, il faut exectuer la commande ci dessous. Cette dernière ouvre le fichier de configuration
```bash
docker exec -it serverBackup /bin/bash
crontab -e
```
7) Pour executer la synchronisation des deux serveur toutes les 5 minutes, nous ajouterons les deux lignes suivantes à la fin du fichier.
```crontab
*/5 * * * * scp -o StrictHostKeyChecking=accept-new -pqr /root/html/index.html root@server1:/usr/share/nginx/html/index.html
*/5 * * * * scp -o StrictHostKeyChecking=accept-new -pqr /root/html/index.html root@server2:/usr/share/nginx/html/index.html
```
8) Quitter le conteneur avec `Ctrl+PQ`
9) Pour verifier le bon fonctionnement, nous pouvons attendre 5 minutes et regarder de nouveau le contenu renvoyé par le serveur proxy. Le contenue devrait normalement être identique.

***
### E - Mise en place du serveur VSFTP
1) Nous allons créer un nouveau réseau `dmz3` pour mettre en place notre serveur vsftp.
```bash
docker network create --subnet 172.16.30.0/24 dmz3
```
2) Pour créer notre serveur vsftp, nous utilserons l'image de fauria pour simplifier la mise en place. Nous utiliserons les variables d'environnement `FTP_USER` et `FTP_PASS` pour créer les identifiants de connexions de notre serveur vsftp.
```bash
docker run -dit --name serverVsftp --hostname serverVsftp --network dmz3 --ip 172.16.30.50 -e FTP_USER=myuser -e FTP_PASS=mYp4sS fauria/vsftpd
```
3) Nous démarrons ensuite notre conteneur.
```bash
docker start serverVsftp
```
4) Nous pouvons désormais nous connecter à notre serveur vsftp avec la commande suivante
```bash
ftp ftp://myuser:mYp4sS@172.16.30.50
```
5) Nous pouvons également tester le serveur ftp directement depuis sont terminal en essayant les commandes suivantes, pour ajouter, affichier puis télécharger un fichier dans le serveur
```
ftp> put /etc/hostname hostname
ftp> ls
ftp> get hostname
```

6) On connectera également notre serveur proxy à notre nouveau réseau.
```bash
docker network connect dmz3 --ip 172.16.30.30/24 serverProxy
```
7) Celui-ci comprendra aussi un fail2ban. Voici la commande pour l'installer.
```bash=
docker exec $NAME bash -c "apt update && apt install fail2ban -y"
```
8) Modifier ensuite le fichier jail.conf.
```bash=
nano etc/fail2ban/jail.conf
```
9) Tout d’abord descender un peu dans le fichier jusqu’à trouver la ligne “backend” et modifiez-la comme-ci dessous. Cela permettra de résoudre les problèmes de démarrage lié aux logs.
```bash
backend = systemd
```
10) Remonter ensuite dans le fichier jusqu'à trouver la ligne "bantime" et modifiez-la comme-ci dessous pour appliquer un banissement d'ip d'une semaine.
```bash
bantime = 604800
```
11) Si l'on regarde un peu plus bas nous pouvons remarquer la ligne "maxretry" laisser la par défaut elle permettra de bannir une ip au bout de 5 essaie échoué de tentative de connexion.
```bash
maxretry = 5
```
12) Votre service fail2ban est désormais opérationnel.
***
### F - Mise en place du serveur Postfix
1) Nous allons désormais installer un serveur mail sur notre serveur proxy. On commencera donc par se connecter à notre conteneur.
```bash
docker exec -ti serverProxy bash
```
2) La première étape sera de vérifier que notre conteneur soit à jour
```bash
apt update
```
3) Nous allons pouvoir installer les paquets suivants pour notre serveur mail
```bash
apt install postfix mailutils libsasl2-2 ca-certificates libsasl2-modules
```
Pendant l'installation, il vous sera posez plusieurs questions. Répondez comme ci-dessous :
```bash
General type of mail configuration: 2
System mail name: ''
Ignore incorrect hostname entry? [yes/no] yes
```
4) Nous allons ajouter une ligne dans le fichier de configuration `/etc/postfix/main.cf` pour indiquer que nous utiliserons le SMTP de Gmail.
```bash
sed -i 's/relayhost = .*/relayhost = [smtp.gmail.com]:587/' /etc/postfix/main.cf
```
5) Nous ajouterons également les lignes suivantes au fichier de configuration pour : activer l’authentification, indiquer où se trouvera le fichier sasl_passwd que nous créerons plus tard, interdire le mode anonyme, indiquer où se trouve le certificat, ainsi que d'utiliser le TLS.
```bash
echo "
smtp_sasl_auth_enable = yes
smtp_sasl_password_maps = hash:/etc/postfix/sasl_passwd
smtp_sasl_security_options = noanonymous
smtp_tls_CAfile = /etc/postfix/cacert.pem
smtp_use_tls = yes
" >> /etc/postfix/main.cf
```
---
6) Pour connecter notre serveur mail à notre compte Gmail, il va falloir créer un mot de passe d'application.
- Naviguer vers l'URL suivante : <https://myaccount.google.com/apppasswords>
- Sélectionner `Autre` dans applications et donner lui un nom (ex: Postfix)

- Votre mot de passe composé de 16 caractères sera alors affiché à l'écran.
---
7) Nous allons maintenant copier la ligne suivante qui permettra la connexion à notre compte Gmail. (En remplaçant EMAIL par l'adresse mail de votre compte et PASSWORD par le mot de passe récupérer précédemment)
```bash
echo '[smtp.gmail.com]:587 EMAIL:PASSWORD' > /etc/postfix/sasl_passwd
```
8) On attribue maintenant les droits pour pouvoir utiliser ce fichier
```
chmod 400 /etc/postfix/sasl_passwd
```
9) On executera ensuite ce fichier pour le transformer en base de données
```bash
postmap /etc/postfix/sasl_passwd
```
10) Nous allons maintenant créer un certificat .pem par l'intermédiaire de cette commande pour pouvoir chiffrer nos messages (laisser tout les champs vides) :
```bash
openssl req -newkey rsa:2048 -new -nodes -x509 -days 3650 -keyout /etc/ssl/certs/key-for-smtp-gmail.pem -out /etc/ssl/certs/cert-for-smtp-gmail.pem
```
11) On redirige ensuite le certificat vers le répertoire indiqué dans le fichier de configuration :
```bash
cat /etc/ssl/certs/cert-for-smtp-gmail.pem | tee -a /etc/postfix/cacert.pem
```
12) Pour finir on redémarre le service postfix
```bash
postfix reload
```
13) Nous allons maintenant pouvoir tester le bon fonctionnement de notre serveur mail avec la commande suivante. (En remplacant DESTINATAIRE par l'adresse cible)
```bash
echo "Test mail from postfix" | mail -s "Test Postfix" DESTINATAIRE
```
