<center>
# Cryptographie - Travaux pratiques Passerelle IPSec
</center>
## Configuration de VirtualBox
Ping depuis les machines au `Routeur`.



On obtient ainsi la vidéo d’un coffre fort.

Finalement sur la machine `IPSec` il faut ajouter une default gateway vers l'addresse locale de la machine `Routeur`.
Dans `/etc/network/interfaces`:

## Mise en place d’un proxy IPSec
#### Création de l'IPsec CA
On commence par créer un répertoire pour les fichiers qui seront utilisés pour l'installation de la CA et du tunnel.
```bash
sudo su -
mkdir -p pki/{cacerts,certs,private}
chmod 700 pki
```
Puis on crée la clé privée de la CA
```bash
pki --gen --type rsa --size 4096 --outform pem > pki/private/ca-key.pem
```
Ce clé servira à la génération d'un certificat auto-signé de la CA
```bash
pki --self --ca \
--in pki/private/ca-key.pem \
--lifetime 3650 \
--dn "CN=IPSec CA" --outform pem > pki/cacerts/ca-cert.pem
```
Ce certificat sera copié sur les machines qui auront confiance à l'authorité `IPSec CA`. Quand la CA genère un certificat pour notre serveur `IPSec`, l'authenticité de ce dernier pourra être vérifiée.
#### Création du certificat du serveur IPSec
Comme toute à l'heure, on commence par la création de la clé du serveur.
```bash
pki --gen --type rsa --size 4096 --outform pem > pki/private/server-key.pem
```
Maintenant il faut créer un certificat pour ce serveur et le signé par la clé privée de notre CA.
```bash
pki --pub \
--in pki/private/server-key.pem \
--outform pem > pki/certs/server-cert-unsigned.pem
pki --issue \
--in pki/certs/server-cert-unsigned.pem \
--lifetime 365 \
--cacert pki/cacerts/ca-cert.pem --cakey pki/private/ca-key.pem \
--dn "CN=172.16.11.11" --san 172.16.11.11 \
--flag serverAuth --outform pem \
> pki/certs/server-cert.pem
rm pki/certs/server-cert-unsigned.pem
```
le flag `serverAuth` spécifie à `pki` que ce certificat sera utiliser pour l'authentification d'un serveur.
Finalement on copie les certificats à `/etc/ipsec.d`:
```bash
cp -r pki/* /etc/ipsec.d/
```
#### Configuration de `StrongSwan`
##### Configuration du serveur
Déplacons nous dans `/etc/ipsec.conf`.
On voit qu'il y a deux connection `psk-vpn` et `vpn-rsa`. On a besoin que d'une seule (J'ai effacé `psk-vpn`).
1. On besoin d'une communication entre `IPSec` (left) et `Visu` (right)
```
left=172.16.11.11
right=192.168.11.100 # %any
```
2. L'authentification de `IPSec` se fait par un certificat. Celle de `Visu` est de type `eap-mschapv2`
```
leftauth=pubkey
leftid=172.16.11.11
leftcert=server-cert.pem
leftsendcert=always
rightauth=eap-mschapv2
eap_identity=%identity # Demander les identifiant du client
```
3. Pour l'authentification de la machine `Visu` (et autres) on a besoin de créer des identifiants. Ceci se fait dans `/etc/ipsec.secrets`:
```
: RSA "server-key.pem"
Visu : EAP "VisuMDP"
```
4. Finalement, on doit relancer de daemon de `StrongSwan`
```bash
systemctl restart ipsec
```
##### Configuration du client
###### Installation de StrongSwan sur la machine `Visu`
Pour cette étape il faut activer l'interface réseau NAT. Ensuite on met à jour la base apt et installer les packets suivant.
```bash
sudo apt update && sudo apt upgrade
sudo apt install strongswan strongswan-starter strongswan-pki libcharon-extra-plugins libcharon-extauth-plugins libstrongswan-extra-plugins libtss2-tcti-tabrmd0 libcharon-extra-plugins package -y
```
###### Configuration IPSec
Dans le fichier de configuration on faut répéter ce qu'on a fait pour le serveur mais inveser left par right.
Donc dans `/etc/ipsec.conf`:
```
# Basic configuration
config setup
strictcrlpolicy=no
uniqueids = yes
# Add connections here.
conn rsa-vpn
left=192.168.11.100 # %any
leftauth=eap-mschapv2
eap_identity=Visu # Visu: Mon identifiant est Visu
right=172.16.11.11
rightid=172.16.11.11
rightauth=pubkey
auto=start
```
###### Authentification
On copie le certificat du serveur VPN vers `Visu`
Dans `IPSec`:
```bash
nc -l -p 3000 < pki/cacerts/ca-cert.pem
```
Dans `Visu`:
```bash
nc 172.16.11.11 3000 > /etc/ipsec.d/cacerts/ca-cert.pem
```
Maintenant on ajoute un identifiant et un mot de passe pour `Visu`. Dans `/etc/ipsec.secrets`:
```
Visu : EAP "VisuMDP"
```
Et on relance le daemon de `StrongSwan`:
```bash
sudo systemctl start strongswan-starter
```
###### It doesn't work
L'authentification échoue avec la notification suivante:
```
[IKE] loading EAP_MSCHAPV2 method failed
```
J'ai cherché les raisons en ligne et apparament, ceci se produit parce qu'il manquent quelques package qu'on peut installer avec apt.
```bash
sudo apt update && sudo apt upgrade
sudo apt install apt install libcharon-extra-plugins libstrongswan-extra-plugins
```
###### It works
Après l'installation, si on fait un ping on voit ces packets passer sur la machine `Routeur`.

### Configuration du proxy IPSec
L'idée est simple, il faut que Visu envoye tout ses packets à `IPSec`.
Sur `IPSec`, dans `/etc/ipsec.conf`:
```
leftsubnet=0.0.0.0/0 # Demande au client d'envoyer son traffic sur le VPN
```
Sur `Visu`, dans le fichier équivalent:
```
rightsubnet=0.0.0.0/0
```
###### It doesn't work well
Ceci ne marche pas bien: Quand on ping `Raspbian` depuis `Visu`:
Sur l'interface `enp0s3` (connecté à `IPSec`) on observe:

et sur l'interface `enp0s8` (connectée à `Visu`):

Le problème ici et que l'addresse ip source est celle de la machine `Visu` et la réponse ne va pas passer par `IPSec`.
###### Un fix
Une solution simple est de créer un nouveau bloc d'addresse IP (virtuelles) et de donner à `Visu` une addresse ip.
Sur `IPSec`, dans `/etc/ipsec.conf`:
```
rightsourceip=10.20.30.0/24
```
Et on utiliser `iptables` pour traduire ces addresses virtuelles à quelque chose que qui peut être routé par `Routeur`.
```bash
iptables -t nat -A POSTROUTING -s 10.20.30.0/24 -j MASQUERADE
```
Sur `Visu`, dans le fichier équivalent:
```
leftsourceip=%config # Demander une addresse IP privée
```
Sur `wireshark` on confirme l'implémentation;

<hr>
<div style="font-size: 0.75em">
C'est aussi possible d'ajouter une route sur `Routeur` pour transmettre le traffic sur `10.20.30.0/24` à `172.16.11.11` (j'ai testé et ça marche). Ceci est moins flexible parce elle depend de la plage virtuelle définie sur la machine `IPsec` mais elle offre moins de latence.
Il y a sans doute plusieurs solutions valides. ***J'aimerai savoir laquelle est "good practice" et pourquoi s'il vous plaît***.

</div>
<hr>
### Mise en place d’un proxy IPSec derrière un Firewall
Pour la configuration du Firewall je vais utiliser `iptables`.
La configuration sera sauvée sous `/root/iptables-vpn.sh`
```bash
#!/bin/sh
# Désactiver le forwarding par defaut
iptables -P FORWARD DROP
# Autoriser le traffic de toute sorte de source ou à destination de IPSec
iptables -A FORWARD -s 172.16.11.11 -j ACCEPT
iptables -A FORWARD -d 172.16.11.11 -j ACCEPT
# Si un traffic est établi, on continue à l'autoriser
iptables -A FORWARD -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
```
Ceci marche assez bien:
- Si `Visu` n'est pas connectée au VPN, quand on ping `Camera`
- Un packet ICMP arrive sur le routeur mais il est rejeté:


- Visu arrive à pinger `IPSec` et connecter au VPN
- Si `Visu` est connectée au VPN, alors elle communique avec le réseau avec une IP NATée derrière `172.16.11.11` et le routeur accepte son traffic
- 
### Closing Remarks
TP super intéressant. J'ai bien aimé la méthode `DIY` adoptée par ce TP parce que ça m'a donné la chance de contempler differentes solutions et évlauer les pros/cons.