cd / ; apropos ;
Table des matières

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 :

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:

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.

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 :

Dans cet exemple, nous utiliserons dans le VPN des IP situées dans le sous réseau 10.0.0.0/24 :

En savoir plus sur les adresses sous-réseau :

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 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 :

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

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 :

https://www.wireguard.com/xplatform/

Wireguard dans F-droid :

https://f-droid.org/en/packages/com.wireguard.android/

Voici le minimum à préciser :

Interface :

Pair :

Voici un exemple :

../../wireguard-config.png

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 :

https://xosc.org/wireguard.html

https://lipidity.com/openbsd/wireguard/

https://man.openbsd.org/wg

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.

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.

https://www.openiked.org/

Ce protocole permet, comme Wireguard, de s'assurer des éléments de sécurité suivants :

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.

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 :

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.

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 :

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" :

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 :

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.

https://www.strongswan.org/

Il faudra toutefois configurer un accès par certificats :

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 #

FAQ 17

man iked.conf

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 :

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.

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" :

https://www.openbsd.org/faq/pf/nat.html

serv_int = "10.0.0.2"
serv_ext = "192.0.2.2"
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 #

Ce site vous aide à générer une rangée ipv6 privée :

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 :

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

Résolveur DNS par le VPN #

Pour faire la résolution DNS, vous pouvez utiliser un résolveur public. Ce n'est cependant pas très conseillé pour des raisons évidentes de confidentialité.

Le plus simple reste de configurer unboud sur votre serveur afin qu'il accepte de résoudre les noms de domaines pour les clients du VPN.

Sur une machine cliente, il suffira alors de préciser "10.0.0.1" dans /etc/resolv.conf pour utiliser votre résolveur.

Voici en quelques lignes comment cela se présente :

# cat << EOF > /var/unbound/etc/unbound.conf
server:
	# listen on VPN's IP
        interface: 10.0.0.1

        access-control: 0.0.0.0/0 refuse
        access-control: 127.0.0.0/8 allow
        access-control: ::0/0 refuse
        access-control: ::1 allow

	# accept requests from the VPN's clients
        access-control: 10.0.0.0/24 allow
        private-address: 10.0.0.0/24


        hide-identity: yes
        hide-version: yes

        auto-trust-anchor-file: "/var/unbound/db/root.key"
        val-log-level: 2

        aggressive-nsec: yes
EOF
# rcctl enable unbound
# rcctl start unbound

Notez que vous pouvez filtrer les pubs et ip malveillantes avec unbound ;). Voir pf-badhost et

/evils/

# unbound-control-setup
cat << EOF >> /var/unbound/etc/unbound.conf
module-config: "respip validator iterator"
rpz:
        name: "unbound-adblock"
        zonefile: "/var/unbound/db/unbound-adblock.rpz"
        rpz-log: yes
        rpz-log-name: "unbound-adblock"


remote-control:
        control-enable: yes
        control-interface: /var/run/unbound.sock
EOF

cat << EOF >> /etc/daily.local
ftp -o- "https://si3t.ch/pub/evils/unbound-adblock.rpz.gz" |\
        gzcat > /var/unbound/db/unbound-adblock.rpz && \
        unbound-control -q auth_zone_reload unbound-adblock && \
        unbound-control -q flush_zone unbound-adblock
EOF

Voir aussi:

https://www.geoghegan.ca/unbound-adblock.html

https://marcocetica.com/posts/wireguard_openbsd/

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 :

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" :

http://man.openbsd.org/ssh#SSH-BASED_VIRTUAL_PRIVATE_NETWORKS


Table des matières

Donate