# VPN
       
       VPN signifie "Virtual Private Network" que l'on peut traduire par réseau virtuel privé. Comme son nom l'indique, cela permet de créer un réseau entre plusieurs machines qui sera "caché" au reste de l'internet mondial (d'où le "privé").
       
       En pratique, un VPN sert souvent à contourner les restrictions ou utilisations plus ou moins abusives qu'un fournisseur d'accès, d'un réseau WiFi public, ou un gouvernement peuvent mettre en place sur votre accès à internet. Vous retrouvez ainsi un accès sain. Ça peut aussi être utile pour réserver des services au sein du VPN uniquement : streaming de musique, partage de fichiers...
       
       Il existe plusieurs sortes de VPN, chacun présentant des avantages et inconvénients selon l'utilisation souhaitée.
       
       Nous présenterons donc plusieurs solutions dans cette partie : Wireguard, OpenIKED, et un tunnel SSH.
       
       Par la suite, nous appellerons :
       
       * Votre ordinateur ou l'appareil utilisant le VPN : client
       * Votre serveur : serveur (oui je sais, c'est brillant tant c'est original 😁).
       
       Nous configurerons principalement des "roadwarriors".
       
       > roadwarrior... c'est censé avoir du sens?
       
       Ce terme décrit une l'utilisation du tunnel VPN permettant à un client, peu importe son adresse IP, de faire passer tout ou partie de son trafic au travers du VPN pour le faire sortir par le serveur. De cette façon, pour les autres, tout semble venir du serveur, le client étant "caché" derrière la façade du serveur. Le serveur, quant à lui, ne fait qu'attendre qu'un client se connecte pour faire le relai.
       
       Un peu plus loin, nous proposerons aussi la possibilité d'utiliser un VPN pour proposer votre serveur derrière une nouvelle IP fixe, pratique pour les serveurs nomades ou si votre fournisseur d'accès à internet ne vous propose pas d'IP fixe ou bien une IP à mauvaise réputation. À ce moment-là, plus question de roadwarrior, la configuration du VPN sera même encore plus simple. On devra par contre détailler la configuration du pare-feu pour effectuer les bonnes redirections.
       
       ## Wireguard
       
       Wireguard est un VPN très pratique à mettre en place tout en restant sécurisé puisqu'il n'accepte que les dernières méthodes de chiffrement existantes. De plus, il fonctionne même si l'IP de votre appareil change (passage d'une connexion filaire à un réseau sans-fil par exemple). Il permet un accès tant en IPv4 qu'IPv6, ce qui peut permettre d'obtenir une IP fixe en IPv6 si votre FAI n'en donne pas. Il est supporté de base à partir d'OpenBSD 6.8. Avec les versions précédentes, il faudra installer un port (# pkg_add wireguard-go).
       
       Site officiel de Wireguard:
 (HTM) https://www.wireguard.com/
       
       Il existe des clients wireguard sur de multiples plateformes (android, MacOS...) ce qui facilite son utilisation.
       
       C'est certainement le choix le plus simple et utile si on veut mettre en place un VPN sur un serveur auto-hébergé.
       
       ### Principe de fonctionnement de Wireguard
       
       On retrouve les mêmes idées qui ont déjà fait leurs preuves pour chiffrer des mails ou encore publier les signatures DKIM : la paire de clés.
       
       * Chaque appareil du VPN dispose d'une paire de clés (publique et privée) ainsi qu'une adresse IP interne. Les clés vont notamment permettre d'identifier les appareils entre eux et sécuriser la première poignée de mains. (Méthode des clés pré-partagées : seul l'administrateur est censé en avoir eu connaissance).
       * Régulièrement, les appareils se font des "poignées de main" afin de s'assurer que tout le monde va bien. Par la même occasion, ils s'échangent le nécessaire pour chiffrer les communications (clés symétriques). Ces dernières clés changent de façon périodique.
       * Le flux entrant sur un appareil est déchiffré avec la clé échangée lors de la "poignée de mains" précédente.
       
       Pour faire simple, chaque morceau de données envoyé au travers du VPN est mis dans un coffre et fermé avec un cadenas qui ne peut s'ouvrir qu'avec la clé échangée pendant la poignée de mains. La poignée de main est quant à elle chiffrée avec les clés publiques la première fois.
       
       ### Mise en place d'un point de sortie ("roadwarrior")
       
       Je vous propose l'organisation suivante :
       
       * Le serveur servira de point de sortie pour les clients. C'est par son biais qu'ils accèderont à internet, et apparaîtront avec l'IP du serveur.
       * Le trafic des clients passera par défaut via la route 0 pour rejoindre le serveur (rdomain 0).
       * Les clients auront toujours leur accès à internet direct habituel que l'on basculera sur une route différente de celle par défaut : rdomain 1. Ainsi, on ne supprime pas cet accès, mais ce n'est pas celui privilégié.
       
       Dans cet exemple, nous utiliserons dans le VPN des IP situées dans le sous réseau 10.0.0.0/24 :
       
       * 10.0.0.1 sera l'IP du serveur;
       * 10.0.0.2, 10.0.0.3, ... seront les IP des clients.
       
       En savoir plus sur les adresses sous-réseau :
 (HTM) https://fr.wikipedia.org/wiki/Sous-r%C3%A9seau
       
       Voici à quoi cela va ressembler :
       
       ```
           +-------------+
           |   serveur   | wg0: 10.0.0.1 port 4545
           |             |---------------+
           +-------------+               |
                  | IP Publique          |
                  | 192.0.2.2            |
                  |                      |
                  |                      |
           /\/\/\/\/\/\/\                |WireGuard
           |  internet  |                |VPN
           \/\/\/\/\/\/\/                |
                  |                      |
                  |                      |
                  |rdomain 1             |
           +-------------+               |
           |   client    |---------------+
           +-------------+ wg0: 10.0.0.2
                           rdomain 0 (defaut)
       ```
       
       Par défaut, le trafic passera par 10.0.0.2 à moins que vous demandiez précisément à passer par une autre route. (ex : route -T1 exec ping openbsd.org)
       
       Le VPN se met en place par la création d'interfaces wgN, où "N" peut être un chiffre de 0 à 9 par exemple. Sous OpenBSD, une telle interface peut être obtenue en remplissant un fichier /etc/hostname.wgN.
       
       Le serveur écoutera sur le port 4545 en UDP. N'importe quel autre port peut-être utilisé. Vérifiez tout de même que celui choisi ne soit pas déjà réservé en consultant /etc/services.
       
       ### Création de clés pour Wireguard
       
       Pour créer une clé privée robuste, utilisez la commande suivante :
       
       ```
       openssl rand -base64 32
       ```
       
       Cela retourne par exemple : "uA1ggvRv66QslZ0ygorWvcLVTxzFauffqMigXTrmLVY="
       
       Ce n'est qu'une fois une clé privée attribuée à une interface que vous pourrez récupérer la clé publique correspondante avec la commande
       
       ```
       # ifconfig wgN
       ```
       
       Sur le serveur, on crée une clé privée :
       
       ```
       # openssl rand -base64 32
       r8uSGD6vyycE5n5/atU9/NX9JQPo4SJryNGpjbQG+rA=
       ```
       
       On crée l'interface en précisant la clé précédente
       
       ```
       # ifconfig wg0 create wgkey r8uSGD6vyycE5n5/atU9/NX9JQPo4SJryNGpjbQG+rA= wgport 4545
       ```
       
       Maintenant, vous pouvez récupérer la clé publique correspondant à cette nouvelle interface :
       
       ```
       # ifconfig wg0
       wg0: flags=8082<BROADCAST,NOARP,MULTICAST> mtu 1420
               index 5 priority 0 llprio 3
               wgport 4545
               wgpubkey x9VXlh4AMa2YRjTMRVE39pQRsFHRJHUYrATL6vkqFmU=
               groups: wg
       ```
       
       La ligne commençant par "wgpubkey" vous renseigne sur la clé publique utilisée par le serveur. Il faudra la préciser pour les clients, prenez-en note.
       
       Prenez-bien note aussi de la clé privée du serveur : on l'utilisera tout à l'heure dans un fichier pour automatiser toute la procédure en cours.
       
       Maintenant, sur un client, on fait la même chose que sur le serveur, c'est-à-dire créer une clé privée puis une interface wg0 associée (nul besoin de préciser le port):
       
       ```
       # openssl rand -base64 32
           q/7uIx6wBIRUIdxOi5D6OWEQRVUt2AXhMj7j29W/s3s=
       # ifconfig wg0 create wgkey q/7uIx6wBIRUIdxOi5D6OWEQRVUt2AXhMj7j29W/s3s=
       # ifconfig wg0 |grep wgpubkey
           wgpubkey V3pCAhxnRl0QEL8luB9D4EvTVxGT7QGDDCZ3O26kY3A=
       ```
       
       ### Redirection du trafic à travers le serveur
       
       Ici, on souhaite que le serveur se constitue comme une sorte de relai entre le client et le reste du réseau.
       
       On doit pour cela activer la redirection d'IP sur les paquets passant par le serveur :
       
       ```
       # sysctl net.inet.ip.forwarding=1
       ```
       
       Pour que ça soit automatique, ajoutez cette ligne dans /etc/sysctl.conf :
       
       ```
       net.inet.ip.forwarding=1
       ```
       
       Si vous voulez faire de même en IPv6, utilisez plutôt:
       
       ```
       net.inet6.ip6.forwarding=1
       ```
       
       De plus, il faudra ajouter une règle pour faire du nat avec le pare-feu :
       
       ```
       # Ouverture du port 4545 en UDP
       pass in proto udp to port 4545
       # ouverture de wg0 pour accéder au vpn
       pass in on wg0
       # Ce qui vient du VPN (wg0) est NATté vers 
       # l'interface "publique" du serveur
       pass out quick on egress from (wg0:network) to any nat-to (egress)
       ```
       
       ### Creusons le tunnel wireguard
       
       Maintenant qu'on dispose de tout le nécessaire pour identifier client et serveur, on peut creuser le tunnel. Pour ça, on va notamment ajouter les clés publiques des clients sur le serveur, et inversement. On va aussi indiquer les IP autorisées à utiliser le tunnel.
       
       Afin de gagner du temps pour la suite et rendre les choses plus simples, nous allons désormais directement éditer les fichiers /etc/hostname.wg0. Ainsi, lors d'un futur redémarrage, la configuration sera intacte.
       
       Prêtez bien attention aux clés utilisées, ce sont les mêmes que celles obtenues juste avant pour vous aider à vous repérer. 😉
       
       Sur le serveur : /etc/hostname.wg0 contient maintenant:
       
       ```
       inet 10.0.0.1/24
       wgkey r8uSGD6vyycE5n5/atU9/NX9JQPo4SJryNGpjbQG+rA=
       wgport 4545
       wgpeer V3pCAhxnRl0QEL8luB9D4EvTVxGT7QGDDCZ3O26kY3A= wgaip 10.0.0.2/32
       up
       ```
       
       Quelques explications :
       
       * wgkey : c'est la clé privée du serveur qui lui permettra de déchiffrer le trafic. Cette clé doit rester secrète. C'est celle qu'on a créé précédemment.
       * wgport : le port d'écoute, on avait choisi le 4545.
       * wgpeer : c'est la clé publique du client. Ça permettra au serveur de chiffrer le trafic à destination du client.
       * wgaip : Adresse IP pour le client autorisée à établie le VPN. Remarquez ici le "/32" pour pouvoir plus tard ajouter d'autres clients sans confusions.
       * inet : C'est l'adresse IP de l'interface dans le VPN.
       * up : l'interface est activée au démarrage.
       
       Vous pouvez ajouter autant de lignes "wgpeer" que vous voulez. C'est bon à savoir si vous souhaitez proposer un accès à plusieurs machines 😉. Cependant, chaque client disposera de sa propre IP. Par exemple :
       
       ```
       wgpeer V3pCAhxnRl0QEL8luB9D4EvTVxGT7QGDDCZ3O26kY3A= wgaip 10.0.0.2/32
       wgpeer m7K/gfmMPYRJx1IOP01zYrNbEuMnnZ29xN4OBgRoRXo= wgaip 10.0.0.3/32
       wgpeer qnuq5MgezCDHXsYYGmrcegPCNcJvz9EOIG3XyHp1DBk= wgaip 10.0.0.4/32
       ```
       
       Sur le client :
       
       Le fichier /etc/hostname.wg0 du client fonctionne comme pour le serveur, à ceci près qu'on doit notamment préciser où trouver le serveur ("wgendpoint") et modifier les routes par défaut pour que le trafic passe par le tunnel.
       
       ```
       wgkey q/7uIx6wBIRUIdxOi5D6OWEQRVUt2AXhMj7j29W/s3s=
       wgpeer x9VXlh4AMa2YRjTMRVE39pQRsFHRJHUYrATL6vkqFmU= wgendpoint chezmoi.tld 4545 wgaip 0.0.0.0/0
       inet 10.0.0.2/24
       wgrtable 1
       !route add -net default 10.0.0.1
       up
       ```
       
       * wgkey : clé privée du client.
       * wgpeer : clé publique du serveur.
       * wgendpoint : IP publique ou nom de domaine du serveur, suivi du port pour y accéder. Si vous choisissez comme dans l'exemple d'indiquer le nom de domaine, comprenez que votre machine doit être capable de résoudre les noms de domaine pour que le tunnel fonctionne. Dans le doute, préférez l'IP.
       * wgaip : En indiquant la valeur "0.0.0.0/0", on permet l'envoi des paquets vers n'importe quelle IP. Ça tombe bien, le tunnel doit pouvoir fonctionner peu importe l'IP du serveur.
       * inet : adresse IP du client dans le VPN
       * wgrtable : les échanges avec le serveur se font sur la table de routage 1. On s'en servira juste après
       * !route add -net default 10.0.0.1 : on modifie la route par défaut vers le bout du tunnel, c'est-à-dire l'IP du serveur.
       
       Ouvrez le tunnel avec la commande suivante sur le serveur et le client :
       
       ```
       # sh /etc/netstart wg0
       ```
       
       Modifiez la configuration correspondant à l'interface du client pour lui préciser de passer par la table de routage 1. Par exemple, dans /etc/hostname.em0 :
       
       ```
       autoconf
       rdomain 1
       up
       ```
       
       Vous pouvez désormais vérifier que lorsque vous naviguez sur internet, votre nouvelle IP est celle du serveur.
       
       ### Configuration de clients utilisant d'autres systèmes d'exploitation
       
       Comme je le disais plus haut, Wireguard est bien supporté par la plupart des systèmes. Cherchez "Client wireguard -nom-de-votre-plateforme-" pour trouver votre bonheur. Par exemple, pour Android, on peut trouver un client dans les dépôts F-droid.
       
       Systèmes supportés par Wiregard : 
 (HTM) https://www.wireguard.com/xplatform/
       
       Wireguard dans F-droid :
 (HTM) https://f-droid.org/en/packages/com.wireguard.android/
       
       Voici le minimum à préciser :
       
       Interface :
       
       * Générer clé privée et clé publique. Copier la clé publique dans /etc/hostname.wg0 sur le serveur de sortie.
       * Adresses : 10.0.0.5/24 par exemple, selon l'ip choisie dans /etc/hostname.wg0 sur le serveur
       * Choisir "Toutes les applications"
       
       Pair :
       
       * Clé publique du serveur de sortie
       * Adresses IP autorisées : 0.0.0.0/0
       * Point de terminaison : 192.0.2.2:4545 (ip.du.serveur.sortie:port)
       
       ### Pour aller plus vite
       
       On a précisé ici comment déployer le VPN avec les outils de base dans OpenBSD. Sachez que vous pouvez installer le port "wireguard-tools" qui pourra vous faire gagner du temps sur la gestion des clés.
       
       ### Ressources
       
       Ce tutoriel est très largement inspiré des liens suivants :
       
 (HTM) https://xosc.org/wireguard.html
 (HTM) https://lipidity.com/openbsd/wireguard/
 (HTM) https://man.openbsd.org/wg
 (HTM) https://codimd.laas.fr/s/NMc3qt5PQ
       
       Je souligne l'importance du travail de Solène qui a eu la judicieuse idée d'utiliser "rdomain" plutôt que modifier les routes par défaut.
 (HTM) https://dataswamp.org/~solene/2021-10-09-openbsd-wireguard-exit.html
       
       ## Un VPN avec OpenIKED
       
       OpenIKED est une implémentation libre du protocole IKEv2 qui permet de mettre en place des VPN de type IPSec.
 (HTM) https://www.openiked.org/
       
       Ce protocole permet, comme Wireguard, de s'assurer des éléments de sécurité suivants :
       
       * Confidentialité : Le type des données transférées reste inconnu.
       * Intégrité : Les données ne sont pas modifiées lors de leur transit.
       * Authenticité : On est sûr d'où viennent les données et qu'elles n'ont pas été altérées.
       * Protection contre la duplication et l'enregistrement par un tiers des échanges.
       
       Sous OpenBSD, le nom du démon qui gère les connexions IKEv2 s'appelle iked.
       
       Vous pouvez dores et déjà consulter la FAQ17 qui couvre officiellement le sujet, puisque cette partie en suit les grandes lignes en guise de traduction détaillée.
 (HTM) https://www.openbsd.org/faq/faq17.html
       
       ### Configuration des paires de clés pour iked
       
       Par défaut, iked utilise une identification par jeton de clés (publique/privée), un peu comme pour ssh. Vous pouvez les stocker dans des dossiers bien précis pour faciliter l'organisation (au format PEM), iked les prendra automatiquement en charge. Selon si les sources (srcid) et les destinations (dstid) sont écrites sous la forme d'adresses IP ou de noms de domaines, les clés publiques seront à enregistrer sous :
       
       * Identité IPv4 : /etc/iked/pubkeys/ipv4/A.B.C.D
       * Identité IPv6 : /etc/iked/pubkeys/ipv6/abcd:abcd::ab:bc
       * Identité en nom de domaine : /etc/iked/pubkeys/fqdn/foo.bar.org
       * Identité de type "adresse mail" : /etc/iked/pubkeys/ufqdn/user@foo.bar.org
       
       Ce qui est génial, c'est qu'iked saura les retrouver comme un grand.
       
       Dans le cadre de ce tutoriel, nous allons présenter la méthode la plus simple, à savoir se servir des clés publiques présentes par défaut sur une installation d'OpenBSD. Libre à vous de créer de nouvelles paires de clés avec la commande openssl si vous le souhaitez afin de changer l'algorithme de chiffrement. La partie privée des clés générées sera dans /etc/iked/private, mais vous l'auriez deviné tout seul 😉.
       
       Pour l'exemple, nous allons copier les clés déjà prêtes. C'est facile de les trouver, il s'agit du fichier /etc/iked/local.pub.
       
       * Copiez ce fichier du client vers le serveur et placez-le à cet emplacement : /etc/iked/pubkeys/ufqdn/batman@cacahuete.tld (vous pouvez mettre n'importe quelle adresse mail, du moment que vous utilisez la même dans la suite du tutoriel.
       * Ensuite, copiez le fichier local.pub qui est sur le serveur vers votre ordinateur pour le placer dans /etc/iked/pubkeys/fqdn/chezmoi.tld. Remplacez le nom de domaine, il doit correspondre à celui de votre serveur, identifié plus tard dans les configurations par srcid et dstid.
       
       ### Configuration réseau pour iked
       
       Sur le serveur et le client, activez l'interface enc0 :
       
       ```
       # echo up > /etc/hostname.enc0
       # sh /etc/netstart enc0
       ```
       
       Ensuite, insérez dans le fichier /etc/sysctl.conf les lignes suivantes, toujours sur le serveur et le client.
       
       ```
       net.inet.ip.forwarding=1
       net.inet6.ip6.forwarding=1
       ```
       
       Sur le serveur et le client, vous ajouterez :
       
       ```
       net.inet.ipcomp.enable=1
       ```
       
       Activez directement ces fonctionnalités sans avoir à redémarrer :
       
       ```
       # while read -r line; do sysctl $line; done < /etc/sysctl.conf
       ```
       
       ### Configuration du pare-feu pour iked
       
       Afin de pouvoir établir la liaison entre le client et le serveur, vous devez ouvrir et rediriger ports 500 (isakmp) et 4500 (ipsec-nat-t) sur le serveur.
       
       De plus, on redirige le trafic passant par le VPN en sortie pour qu'il apparaisse avec l'IP du serveur et non celle du client. Ce flux est repéré par l'étiquette "ROADW" définie plus loin dans la configuration d'OpenIKED. Le fichier /etc/pf.conf du serveur ressemblera à ceci (lisez les commentaires) :
       
       ```
       # On rassemble les paquets
       set reassemble yes
       # Petite precaution
       antispoof quick for enc0
       
       # On laisse entrer le trafic IKE et IKE NAT-Traversal pour l'authentification
       pass in on egress proto udp from any to <ip-du-serveur> port {isakmp, ipsec-nat-t} tag IKED
       pass in on egress proto esp from any to <ip-du-serveur> tag IKED
       # On laisse passer le trafic encapsulé avec l'etiquette ROADW
       pass on enc0 tagged ROADW
       # On redirige le trafic avec l'etiquette ROADW vers la sortie
       match out on egress inet tagged ROADW nat-to (egress)
       ```
       
       ### Configuration d'IKED
       
       Tous les fichiers iked.conf doivent avoir des droits bien choisis. Que ce soit sur le client ou le serveur, vous entrerez :
       
       ```
       # touch /etc/iked.conf
       # chmod 600 /etc/iked.conf
       ```
       
       ### Configuration d'IKED sur le serveur
       
       Voici le contenu du fichier /etc/iked.conf sur le serveur :
       
       ```
       ikev2 "warrior" passive ipcomp esp \
       from 0.0.0.0/0 to 10.0.5.0/24 \
       peer any local <ip.publique.du.serveur> \
       srcid "chezmoi.tld" \
       tag "ROADW"
       ```
       
       Ce dernier crée un flux à partir du trafic venant de n'importe où (0.0.0.0) et le redirige vers le réseau 10.0.5.0/24 auquel appartiendront les clients. Au passage, il donne l'étiquette "ROADW" à ce flux pour le repérer ensuite.
       
       Pensez à bien modifier l'IP publique du serveur et le nom de domaine. Le paramètre srcid servira à identifier le certificat à utiliser pour l'authentification (ça peut donc aussi être une adresse IP selon ce que vous avez préféré.
       
       > Tu crois t'en sortir comme ça ? Nous on veut savoir ce que ça veut
       > dire ces trucs bizarres dans la configuration.
       
       Et c'est parti pour des détails, ligne par ligne :
       
       * ikev2 "warrior" passive ipcomp esp : On définit une nouvelle politique qu'on appelle "warrior". Le serveur est passif : c'est lui qui reçoit les demande, il ne les envoie pas. Ensuite, on active la compression du trafic (ipcomp) avec le protocole esp.
       * from 0.0.0.0/0 to 192.168.0.0/16 : Les paquets venant de n'importe où vers une interface dont l'adresse est dans la plage 192.168.0.0/16 seront encapsulés.
       * peer any local <ip.publique.du.serveur> : On précise l'IP de sortie du tunnel, pour n'importe quel pair.
       * srcid "chezmoi.tld : très important, cela précise l'identifiant de la source : ici, c'est le nom du fichier de clé enregistré sur les clients.
       
       ### Configuration d'IKED sur le client
       
       La configuration est quasiment identique, mais inversée 😉
       
       ```
       ikev2 "warrior" active ipcomp esp \
       from 0.0.0.0/0 to 0.0.0.0/0 \
       peer "<ip.publique.du.serveur>" \
       srcid "batman@cacahuete.tld" \
       dstid "chezmoi.tld"
       ```
       
       Les paramètres auxquels vous devez être attentifs sont "srcid" et "dstid" :
       
       * srcid : Il s'agit du nom du fichier donné à la clé publique du client enregistré sur le serveur.
       * dstid : C'est le nom du fichier de la clé publique du serveur enregistré sur le client.
       
       Si vous êtes perdus, retournez lire la partie sur les clés un peu plus haut. 😉
       
       Le client doit aussi configurer son IP pour qu'elle appartienne au réseau 10.0.5.0/24. Vous pouvez le faire ainsi en éditant sur le client le fichier de configuration /etc/pf.conf :
       
       ```
       match out log on enc0 inet all nat-to 10.0.5.2
       ```
       
       Cela associe tout le flux sortant sur l'interface enc0 à l'adresse 10.0.5.2. Si vous utilisez plusieurs clients, vous devrez modifier cette adresse. N'oubliez pas de recharger le pare-feu.
       
       Attention : tout le flux du client passe désormais par le tunnel chiffré. Cela peut être embêtant notamment pour la résolution de domaine, ou si vous utilisez des démons locaux. Ajoutez seulement cette ligne au fichier /etc/ipsec.conf :
       
       ```
       flow from 127.0.0.1/32 to 127.0.0.1/32 type bypass
       ```
       
       Activez cette règle avec la commande :
       
       ```
       # ipsecctl -f /etc/ipsec.conf
       ```
       
       En cas d'erreur concernant les permissions, entrez :
       
       ```
       # chmod 600 /etc/ipsec.conf
       ```
       
       Afin de ne pas avoir à lancer cette commande lors d'un redémarrage, entrez :
       
       ```
       rcctl enable ipsec
       ```
       
       Attention 2 : La résolution de noms (DNS) ne pourra pas se faire en local. Idéalement, il faudrait indiquer dans le fichier /etc/resolv.conf un résolveur accessible via le VPN, et dans l'idéal le résolveur du serveur s'il en propose. Dans le doute, indiquez dans /etc/resolv.conf un résolveur public :
       
       ```
       nameserver 9.9.9.9
       ```
       
       ### Mise en route d'iked
       
       C'est parti ! 😊
       
       Sur le serveur, rechargez le pare-feu et activez/démarrez iked :
       
       ```
       # pfctl -f /etc/pf.conf
       # rcctl enable iked
       # rcctl start iked
       ```
       
       Sur le client, lancez pour commencer iked sans le mettre en arrière-plan :
       
       ```
       # iked -vvd
       ```
       
       Vous allez voir un tas de choses s'afficher. Si vous voyez une ligne qui ressemble à la suivante, c'est tout bon 😉 :
       
       ```
       sa_state: VALID -> ESTABLISHED from 46.23.92.147:4500 to 192.168.100.122:4500 policy 'warrior'
       ```
       
       Par la suite, vous pourrez activer iked sur le client avec rcctl.
       
       Pour vérifier que cela fonctionne, vous pouvez consulter un des sites permettant de connaître son IP publique. Si elle est différente et correspond à celle du serveur, c'est réussi 😊. Vous pouvez plus simplement le vérifier avec la commande suivante :
       
       ```
       # ipsecctl -sa
       FLOWS:
       flow esp in from 0.0.0.0/0 to 192.168.0.0/16 peer 46.23.92.147 srcid UFQDN/prx@moria.lan dstid FQDN/reiva.xyz type use
       flow esp out from 192.168.0.0/16 to 0.0.0.0/0 peer 46.23.92.147 srcid UFQDN/prx@moria.lan dstid FQDN/reiva.xyz type require
       flow esp out from ::/0 to ::/0 type deny
       
       SAD:
       esp tunnel from 46.23.92.147 to 192.168.100.122 spi 0x7958b1de auth hmac-sha2-256 enc aes-256
       esp tunnel from 192.168.100.122 to 46.23.92.147 spi 0xe7d244a8 auth hmac-sha2-256 enc aes-256
       ```
       
       En cas de problème, avant d'arrêter le processus iked, lancez la commande suivante pour fermer le tunnel :
       
       ```
       # ikectl decouple
       ```
       
       ### Gérer le VPN
       
       À partir du client :
       
       * # ikectl decouple : Arrête d'utiliser le tunnel
       * # ikectl couple : Recommence à utiliser le tunnel
       * # ikectl reset sa && rcctl stop iked : Arrête le tunnel et coupe tous les flux restants.
       
       ### Utilisation avec des clients n'utilisant pas OpenBSD
       
       Strongswan Sous Linux ou avec un smartphone android, vous aurez besoin d'utiliser l'application strongswan pour configurer la connexion à votre VPN.
 (HTM) https://www.strongswan.org/
       
       Il faudra toutefois configurer un accès par certificats :
 (HTM) https://www.openbsd.org/faq/faq17.html#clientandroid
       
       Sinon, MacOS et Windows peuvent le gérer nativement, mais il faudra demander à leurs experts.
       
       ### Ressources sur Openiked
       
 (HTM) FAQ 17
 (HTM) man iked.conf
 (HTM) man ikectl
       
       ## Avoir une IP fixe grâce à un VPN
       
       Si votre FAI ne vous fournit pas d'adresse IP fixe, alors vous pouvez mettre en place un tunnel VPN comme décrit dans cette partie. Votre serveur sera alors accessible au public via l'IP du VPN, l'IP de votre serveur étant "cachée" derrière.
       
       Cela s'avère particulièrement utile si :
       
       * Vous n'avez pas d'IP fixe fournie par votre FAI. Vous hébergerez alors votre VPN chez un intermédiaire. Ce dernier fera le relai vers votre serveur personnel.
       * Votre fournisseur d'accès vous propose une IP qui a mauvaise réputation, vos mails atterrissent toujours dans les spams.
       * Vous ne faites pas confiance à votre FAI, vous souhaitez cacher le trafic proposé par votre serveur dans un tunnel.
       * ...
       
       Voici schématiquement ce que l'on cherche à faire :
       
       ```
       +-~sniper~-+        +------~tank~-------+      +--------------+
       |          |        |                   |      |              |
       | Serveur  +<------>+     Serveur       +<-----+              |
       |  Perso   |  VPN   |  point de sortie  |      |   Visiteur   |
       |          |        |  avec IP fixe     |      |              |
       +----------+        +-------------------+      +--------------+
          IP cachée             IP Publique
       ```
       
       Peu importe l'IP de votre serveur perso, pour y accéder depuis internet, il suffira d'utiliser l'IP publique du serveur point de sortie.
       
       Pour mieux se comprendre ensuite, j'appellerai "sniper" le serveur caché derrière le VPN et "tank" le serveur dont on veut utiliser l'IP publique.
       
       ### Changement d'interface : avertissement pour le pare-feu
       
       ⚠ Pensez à adapter la configuration de votre pare-feu de votre serveur.
       
       Désormais, le trafic parviendra à votre serveur par l'interface du VPN, c'est-à-dire "wg0" si vous l'avez configuré avec Wireguard ou bien "enc0" si c'est avec Iked. Le plus simple reste de remplacer "egress" par une macro contenant toutes les interfaces à gérer, et y ajouter "wg0" à la liste. Par exemple:
       
       ```
       pass in quick on egress proto tcp to port $tcp_pass 
       ```
       
       devient
       
       ```
       ifaces = "{ em0 wg0 }"
       pass in quick on $ifaces proto tcp to port $tcp_pass 
       ```
       
       ou encore : ifaces = "{ egress wg0 }
       
       ### Prérequis : un tunnel VPN simple
       
       Notez que vous n'êtes dans ce cas plus du tout obligé de modifier les routes par défaut de votre serveur. Il est tout à fait possible que votre serveur garde un accès à internet par défaut avec son IP fournie par celle du FAI et soit joignable de l'extérieur par l'IP de tank. Je trouve même cette solution plus simple. Ainsi, pour un VPN wireguard, on pourrait trouver les extraits de configuration suivants.
       
       Sur tank :
       
       ```
       # cat /etc/hostname.wg0
       inet 10.0.0.1/24
       wgkey [..snip..]
       wgport 4545
       wgpeer [...snip...] wgaip 10.0.0.2/32
       up
       
       # cat /etc/sysctl.conf
       net.inet.ip.forwarding=1
       net.inet6.ip6.forwarding=1
       
       # cat /etc/pf.conf
       [...]
       # wireguard tunnel
       pass in proto udp to port 4545
       # no nat-to
       [...]
       ```
       
       Sur sniper :
       
       ```
       # cat /etc/hostname.wg0
       wgkey [..snip..]
       wgpeer [..snip..] wgendpoint chezmoi.tld 4545 wgaip 0.0.0.0/0
       inet 10.0.0.2/24
       up
       
       # cat /etc/pf.conf
       [...]
       # paranoid commented below
       #  pass in on wg0 from 10.0.0.1
       #  pass out on wg0
       # less paranoid:
       pass on wg0
       [...]
       ```
       
       ### Obtention de la nouvelle IP
       
       On suppose par la suite que sniper et tank sont reliés par un VPN Wireguard.
       
       * "sniper" a pour IP 10.0.0.2 dans le VPN.
       * "tank" a pour IP 10.0.0.1 dans le VPN et son IP publique est 192.0.2.2.
       
       Vous n'aurez qu'à éditer le pare-feu de tank pour ajouter quelques règles "nat-to" et "rdr-to". Voici à quoi le résultat final peut ressembler :
       
       Vous n'aurez qu'à éditer le pare-feu de tank pour ajouter quelques règles "nat-to" et "rdr-to" :
 (HTM) https://www.openbsd.org/faq/pf/nat.html
       
       ```
       serv_int = "10.0.0.2"
       serv_ext = "217.69.0.97"
       int_if = "wg0"
       ext_if = "egress" # change me maybe
       
       set skip on lo
       
       block
       
       # let vpn on
       pass in proto udp to port 4545
       pass in on wg0
       
       ### REDIRECT TO SNIPER
       pass in on $ext_if proto tcp from any to $serv_ext \
           rdr-to $serv_int
       
       match out on $ext_if from $serv_int to any \
              nat-to $serv_ext static-port
       # One can replace the two previous rules with :
       # match on $ext_if from $serv_int to any binat-to $serv_ext
       
       match out on $int_if from any to $serv_int \
               received-on $ext_if nat-to $int_if
       
       ###
       pass out
       ```
       
       Prenez bien soin de modifier les IP dans les variables serv_* et éventuellement $ext_if correspondant à l'interface publique.
       
       La règle rdr-to relie ce qui arrive de n'importe où (any) sur l'interface publique (ext_if) pour l'ip de tank ($serv_ext) vers sniper ($serv_int).
       
       Ensuite, la première règle "nat-to" relie ce qui arrive de sniper ($serv_int vers l'ip de tank $serv_ext) sans modifier le port utilisé (static-port).
       
       Ces deux instructions sont équivalentes à la règle binat-to donnée en exemple dans le commentaire. Cette dernière cependant ne permet par de préciser des ports, on en parlera ensuite 😉.
       
       Ensuite, on précise à nouveau une règle nat-to en sortie afin de bien relier cette fois-ci les interfaces (et non pas les IP).
       
       On termine par laisser passer en sortie.
       
       Remarquez qu'on utilise un match pour les règles sortantes. Cela permet de garder en mémoire la règle pour le paquet correspondant à cette dernière et ne pas l'écraser lorsqu'on autorise la sortie à la fin avec le pass out. On aurait pu utiliser des quick, mais je trouve cela moins pratique à la longue.
       
       Rechargez le pare-feu. Et voilà, c'est terminé 😊.
       
       Certains voudront peut-être plus finement paramétrer leur pare-feu. C'est pour ça que j'ai commenté la ligne binat-to pour l'exemple afin de conserver l'instruction rdr-to qui permet de définir quels ports rediriger:
       
       ```
       ports_tcp = "{ ssh www https smtp submission imaps domain }"
       ports_udp = "{ domain spamd-sync }" 
       
       # pass in on $ext_if from any to $serv_ext rdr-to $serv_int
       # previous line is replaced by 
       pass in on $ext_if proto tcp from any to $serv_ext port $ports_tcp rdr-to $serv_int
       pass in on $ext_if proto udp from any to $serv_ext port $ports_udp rdr-to $serv_int
       [...]
       ```
       
       ### Avertissement pour SSH sur l'hôte
       
       Si vous administrez vos serveurs via SSH, comprenez que vous ne pourrez plus accéder au point de sortie du VPN (l'hôte) par ce moyen si vous laissez les choses en l'état. En effet, tout est redirigé vers le client.
       
       Sur le serveur, vous devriez alors modifier le port d'écoute SSH par défaut (/etc/ssh/sshd_config) puis ajouter une règle quick dans le pare-feu. Vous aurez alors en haut du pf.conf, avant les redirections du VPN, une règle ressemblant à ceci :
       
       ```
       pass in quick on $ext_if proto tcp port 2222 # alternative ssh listening port
       ```
       
       ### Modification des DNS
       
       Désormais, dans votre zone DNS, votre nom de domaine doit pointer vers l'IP de tank.
       
       ## Obtenir une IPv6 grâce au VPN
       
       Malgré l'année dans laquelle nous vivons, certains fournisseurs d'accès ne proposent toujours pas de connectivité IPv6. Vous pouvez heureusement proposer vos services en IPv6 après avoir configuré un VPN vers un fournisseur qui en dispose : openbsd.amsterdam, vultr... (voir il y a quelques chapitres la partie "Quelqu'un peut-il héberger OpenBSD pour moi ?").
       
       On va pour cela mettre en place un VPN avec wireguard comme vu précédemment, en y ajoutant la connectivité ipv6 à un client qui n'en dispose pas.
       
       ### Prérequis à l'obtention de l'IPv6
       
       * Vous devez disposer d'un accès à un serveur distant disposant d'une ipv6. Une machine virtuelle par exemple.
       * Une rangée d'IPv6 privée. Dans cet exemple, on utilisera fd9c:f774:0bfa:acfc. Il pourrait s'agir plus simplement de fd42::1, fd42::2, ... Ça fonctionnera, mais ce n'est pas très rigoureux.
       
       Ce site vous aide à générer une rangée ipv6 privée :
 (HTM) https://simpledns.plus/private-IPv6
       
       ### Configuration sur le serveur distant
       
       Pensez à activer l'option d'ip forwarding pour l'ipv6 dans /etc/sysctl.conf:
       
       ```
       net.inet.ip.forwarding=1
       net.inet6.ip6.forwarding=1
       ```
       
       Le fichier /etc/hostname.wg0 servant à configurer wireguard doit désormais préciser l'ipv6 du point de sortie du VPN. Ici, c'est fd9c:f774:0bfa:acfc::1/64.
       
       Chaque client doit pouvoir disposer aussi de son ipv6. On ajoute tout simplement une nouvelle option wgaip en plus de l'ancienne. La configuration ressemble alors à ceci :
       
       ```
       # cat /etc/hostname.wg0
       inet 10.0.0.1/24
       inet6 fd9c:f774:0bfa:acfc::1/64
       wgkey [...snip...]
       wgport 4545
       # peer 1
       wgpeer [...snip...] wgaip 10.0.0.2/32 wgaip fd9c:f774:0bfa:acfc::2/128
       # peer 2
       wgpeer [...snip...] wgaip 10.0.0.3/32 wgaip fd9c:f774:0bfa:acfc::3/128
       # peer 3
       wgpeer [...snip...] wgaip 10.0.0.4/32 wgaip fd9c:f774:0bfa:acfc::4/128
       
       up
       ```
       
       ⚠ C'est important que chaque ipv6 des clients soit bien précisée avec à la fin "/128".
       
       ### Configuration sur la machine qui veut récupérer une ipv6
       
       Dans le fichier /etc/hostname.wg0, on doit ajouter quelques éléments par rapport à précédemment :
       
       * Dans la section wgpeer, il **FAUT** ajouter wgaip ::0/0 pour autoriser l'accès en ipv6.
       * On précise l'ipv6 de l'interface avec une ligne inet6 indiquant l'ip privée, c'est-à-dire celle à l'intérieur du tunnel qui a été définie dans la section précédente sur le serveur pour identifier ce client.
       * Ajouter une nouvelle route pour faire passer le trafic ipv6 par défaut par le point de sortie du VPN.
       
       La configuration de wireguard ressemble à ceci :
       
       ```
       # cat /etc/hostname.wg0
       wgkey [...snip...]
       wgpeer [...snip...] \
           wgendpoint <XX.XX.XX.XX> 4545 \
           wgaip 0.0.0.0/0 \ # <--- !
           wgaip ::0/0 \
           wgpka 25
       
       inet 10.0.0.3/24
       inet6 fd9c:f774:0bfa:acfc::3/64 # <--- !
       wgrtable 1
       up
       !route add -inet default 10.0.0.1
       !route add -inet6 default fd9c:f774:0bfa:acfc::1 # <--- !
       ```
       
       Et voilà, vous disposez désormais d'un accès ipv6 au travers du VPN.
       
       Vérifiez-le par exemple avec cette commande :
       
       ```
       curl -6 https://ifconfig.co
       ```
       
       ## Tunnel SSH : Proxy ou VPN
       
       SSH vous permettra de mettre en place un rapide PROXY pour encapsuler certaines connexions, voire de mettre en place un VPN rudimentaire.
       
       ### Proxy SOCKS
       
       Un tunnel SSH est très facile à mettre en place. Il permet d'apparaître avec l'IP du serveur sortant.
       
       On supposera que votre serveur dispose d'un accès SSH fonctionnel.
       
       Depuis une machine cliente (votre ordinateur de bureau par exemple), vous entrerez cette commande :
       
       ```
       ssh -D 9999 -NT batman@chezmoi.tld
       ```
       
       Quelques explications :
       
       * -D 9999 : quand une application passe par le port 9999, les données transiteront à travers le tunnel pour sortir vers le serveur.
       * -N : permet de ne pas lancer de commandes sur le serveur, juste pour rediriger les ports.
       * -T : ne réserve pas de terminal.
       * batman@chezmoi.tld : identifiant et nom de domaine du serveur SSH.
       
       Ensuite, toutes les applications peuvent être configurées pour utiliser un proxy de type SOCKS vers le port 9999.
       
       Par exemple, avec le navigateur Firefox, vous pouvez configurer le proxy dans les préférences "Paramètres réseau".
       
       ### VPN avec SSH
       
       Voir le man ssh(1) partie "SSH-BASED VIRTUAL PRIVATE NETWORKS" :
 (HTM) http://man.openbsd.org/ssh#SSH-BASED_VIRTUAL_PRIVATE_NETWORKS
       
       ---
       
 (DIR) Table des matières
 (BIN) Donate
       
       ---
 (DIR) /