Contexte de cet article
En plus de mes machines locales, je possède plusieurs serveurs virtuels (ou VPS), afin d'assurer une bonne redondance pour mes DNS et mes serveurs mails en cas de panne réseau. Pour autant, cela me demande d'effectuer de la surveillance sur ces machines et je n'avais pas envie d'exposer mes sondes directement sur Internet. J'ai donc choisi de mettre en place un VPN entre mes machines extérieures et mon routeur, afin que seul le trafic interne passe par une interface sécurisée. La technologie que j'ai retenue est Wireguard, par sa simplicité d'utilisation, sa compatibilité avec l'ensemble de mes systèmes et sa robustesse.
Je vais également en profiter pour me créer un deuxième accès VPN qui sera utilisé par plusieurs machines lors de mes déplacements, en l'occurrence mon PC portable et mon iPhone.
Réseaux à mettre en place
Ici, je vais mettre en place deux interfaces de VPN :
- un VPN d'infrastructure pour mon monitoring (préfixe en 172.16.10.0/24)
- un VPN de gestion, que j'utilise lorsque je suis en déplacement (préfixe en 172.16.0.0/24)
Vu le nombre de machines à connecter, un serveur DHCP ne sera pas nécessaire et les IP des clients seront définies à la main.
Prérequis
Pour cette installation, voici les éléments nécessaires :
- Un serveur Wireguard, ici mon routeur Mikrotik
- Plusieurs clients Wireguard : deux sous OpenBSD et un sous Debian GNU/Linux
- Des préfixes dédiés pour le VPN : 172.16.0.0/24 et 172.16.10.0/24 dans mon cas
Mise en place du serveur
Mikrotik fournit nativement un module pour utiliser Wireguard sous RouterOS. Il est activé par défaut et il peut se configurer via l'interface graphique ou via la console. Ici, nous allons nous concentrer sur l'usage de la console pour des raisons de simplicité.
On commence par créer deux interfaces réseaux dédiées à Wireguard et ajouter deux adresses IP pour définir les futurs préfixes de nos clients :
/interface wireguard add name=wg0 listen-port=60002
/interface wireguard add name=wg1 listen-port=60001
/ip address add address=172.16.0.1/24 interface=wg0
/ip address add address=172.16.10.1/24 interface=wg1
On affiche ensuite les informations des interfaces avec la commande print
pour récupérer la clé publique du serveur. Cela nous servira par la suite pour préparer la configuration de nos clients :
[vinishor@mikrotik] /interface/wireguard> /interface/wireguard print
Flags: X - disabled; R - running
0 R name="wg0" mtu=1492 listen-port=60002 private-key="cleprivee="
public-key="masuperclepublique="
1 R name="wg1" mtu=1492 listen-port=60001 private-key="cleprivee2e="
public-key="ma2esuperclepublique="
On passe maintenant à la partie pare-feu. Le but est alors d'ouvrir les ports dédiés à Wireguard et autoriser le passage du trafic du VPN. Je vais aussi en profiter pour autoriser le VLAN 10, réservé à mes serveurs maison, à aller vers les machines du VPN d'infrastructure, pour que la machine de monitoring puisse aller interroger les sondes de surveillance.
Les adresses IP des serveurs externes étant fixes, on peut aussi mettre en place une liste pour limiter l'accès au VPN d'infra à ces seules adresses.
Cela donne donc les commandes suivantes :
/ip/firewall/address-list
add list=wg-infra address=172.16.10.0/24
add list=wireguard address=172.16.0.0/24
add list=allowed-servers address=45.xx.xx.xx/32
add list=allowed-servers address=46.xx.xx.xx/32
add list=allowed-servers address=89.xx.xx.xx/32
add list=allowed-servers address=46.yy.yy.yy/32
/ip/firewall/filter
add chain=input action=accept protocol=udp dst-port=60001 src-address-list=allowed-servers
add chain=input action=accept protocol=udp dst-port=60002
add chain=forward action=accept src-address-list=wg-infra
add chain=forward action=accept src-address-list=vlan10 dst-address-list=wg-infra
add chain=forward action=accept src-address-list=wireguard
Ajouter un client sur l'interface du serveur (peer)
Le protocole de Wireguard impose d'ajouter des deux côtés les machines qui souhaitent communiquer entre elles. Cela évite ainsi d'échanger des mots de passe ou tout autre donnée en clair sur le réseau. Dans cette section, je vais donc vous donner les instructions pour ajouter un client sur l'interface voulue. Il est possible de jouer la commande plusieurs fois, en fonction du nombre de clients à rajouter.
Il est aussi nécessaire de connaître la clé publique du client pour l'ajouter correctement (je vous expliquerai par la suite comment faire pour la générer).
Pour ajouter un client sur l'interface wireguard, on entre la commande suivante :
/interface/wireguard/peers
add allowed-address=172.16.10.2/32 endpoint-port=60001 interface=wg1 public-key="zzzzzzzzzzzz"
# Si on l'ajoute sur la deuxième interface
add allowed-address=172.16.0.6/32 interface=wg0 public-key="uuuuuuuuuuuuuuuuuuuuuuuu"
L'option endpoint-port
permet de choisir le port dédié à wireguard sur le client. Cela peut être pratique sur un serveur, afin d'ouvrir le strict nécessaire au niveau du pare-feu. On peut aussi spécifier une adresse précise en rajoutant l'option endpoint-address
.
Dans le cas de mon VPN de gestion, je ne spécifie ni le port, ni l'adresse, car les smartphones utilisent souvent des adresses provenant d'un CG-NAT et leur pare-feu n'est pas facilement contrôlable. C'est bien le couple de clés que l'on indique dans la configuration qui permet l'authentification de l'accès et qui assure la sécurité.
Mise en place des clients
Maintenant que le serveur est en place, nous allons connecter nos machines clientes, afin que celles-ci puissent communiquer entre elles et avec les autres machines situées sur mon réseau à la maison.
Exemples pour un serveur à surveiller
Sous Debian GNU/Linux
Installer Wireguard avec l'aide de apt :
$ sudo apt install wireguard-tools
Générer les clés privée et publique du client pour pouvoir se connecter par la suite :
$ sudo -i
# mkdir /etc/wireguard && cd /etc/wireguard
# wg genkey | tee privatekey | wg pubkey > publickey
Créer un fichier de configuration pour l'interface dédiée à Wireguard en ajoutant les paramètres pour se connecter au serveur :
# cat << EOF > /etc/wireguard/wg0.conf
[Interface]
Address = 172.16.10.2/24
SaveConfig = true
ListenPort = 60001
PrivateKey = xxxxxxxxxxxxxx # cat privatekey
[Peer]
PublicKey = yyyyyyyyyy # clé publique du serveur Wireguard (obtenue avec /interface/wireguard print)
AllowedIPs = 172.16.10.0/24,10.10.10.0/24
Endpoint = x.x.x.x:60001 # Adresse publique du routeur
EOF
Importer la configuration en utilisant l'utilitaire wg-quick, vu que l'option SaveConfig sauvegardera cette dernière pour les prochains redémarrages de la machine :
# wg-quick up wg0
La commande rajoute alors une nouvelle interface réseau et initie la connexion avec le routeur Mikrotik pour monter le VPN. Pour vérifier que tout fonctionne, on peut lister les interfaces réseaux et essayer de faire un ping vers une machine située sur le réseau local :
$ ip -c a show
...
8: wg0: <POINTOPOINT,NOARP,UP,LOWER_UP> mtu 1420 qdisc noqueue state UNKNOWN group default qlen 1000
link/none
inet 172.16.10.5/24 scope global wg0
valid_lft forever preferred_lft forever
$ ping -c 1 10.10.10.10
PING 10.10.10.10 (10.10.10.10) 56(84) bytes of data.
64 bytes from 10.10.10.10: icmp_seq=1 ttl=63 time=18.6 ms
--- 10.10.10.10 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 18.629/18.629/18.629/0.000 ms
Sous OpenBSD
Installer Wireguard avec l'aide de pkg_add :
$ doas pkg_add wireguard-tools
Générer les clés privée et publique pour pouvoir se connecter par la suite :
$ su
# mkdir /etc/wireguard && cd /etc/wireguard
# wg genkey | tee privatekey | wg pubkey > publickey
Créer un fichier de configuration dédié à Wireguard en ajoutant les paramètres pour se connecter au serveur :
# cat << EOF > /etc/wireguard/wg0.conf
[Interface]
ListenPort = 60001
PrivateKey = xxxxxxxxxxxxxx # cat privatekey
[Peer]
PublicKey = yyyyyyyyyy # clé publique du serveur Wireguard (obtenue avec /interface/wireguard print)
AllowedIPs = 172.16.10.0/24,10.10.10.0/24
Endpoint = x.x.x.x:60001 # Adresse publique du routeur
EOF
Créer un fichier de configuration pour l'interface réseau en indiquant le chemin du fichier de configuration de Wireguard et en ajoutant la route réseau nécessaire pour le préfixe du VLAN 10 :
# vi /etc/hostname.wg0
inet 172.16.10.3 255.255.255.0
up
!/usr/local/bin/wg setconf wg0 /etc/wireguard/wg0.conf
!/sbin/route add 10.10.10.0/24 172.16.10.3
Initialiser l'interface réseau :
# sh /etc/netstart wg0
La commande rajoute alors une nouvelle interface réseau et initie la connexion avec le routeur Mikrotik pour monter le VPN. Pour vérifier que tout fonctionne, on peut lister les interfaces réseaux et essayer de faire un ping vers une machine située sur le réseau local :
$ ifconfig
...
wg0: flags=80c3<UP,BROADCAST,RUNNING,NOARP,MULTICAST> mtu 1420
index 6 priority 0 llprio 3
wgport 60001
groups: wg
inet 172.16.10.3 netmask 0xffffff00 broadcast 172.16.10.255
$ ping -c 1 10.10.10.10
PING 10.10.10.10 (10.10.10.10): 56 data bytes
64 bytes from 10.10.10.10: icmp_seq=0 ttl=64 time=21.077 ms
--- 10.10.10.10 ping statistics ---
1 packets transmitted, 1 packets received, 0.0% packet loss
round-trip min/avg/max/std-dev = 21.077/21.077/21.077/0.000 ms
Exemple pour un client "classique"
iPhone
Dans cet exemple, je vais relier mon smartphone à mon réseau local, afin d'avoir accès à mes machines internes et toute autre ressource non exposée sur Internet. Pour mettre en place la configuration sur le smartphone, je vais générer un fichier de configuration sur un ordinateur et le convertir en code QR pour l'utiliser sur le téléphone.
Étant sous Fedora Linux, je peux utiliser les outils de Wireguard pour générer un fichier :
$ mkdir wireguard && cd wireguard # dans mon $HOME
$ wg genkey | tee privatekey | wg pubkey > publickey
$ cat << EOF > wg-iphone.conf
[Interface]
PrivateKey = xxxxxxxxxxxxxx # cat privatekey
Address = 172.16.0.2/24
[Peer]
PublicKey = yyyyyyyyyy # clé publique du serveur Wireguard (obtenue avec /interface/wireguard print)
AllowedIPs = 172.16.0.0/24,10.10.10.0/24
Endpoint = x.x.x.x:60002 # Adresse publique du routeur
EOF
Une fois le fichier prêt, on peut utiliser le programme qrencode
pour générer un code QR contenant la configuration du VPN pour notre iPhone :
$ sudo dnf install qrencode
$ qrencode --type=UTF8 --read-from=wg-iphone.conf
Installer ensuite l'application officielle via l'App Store d'Apple sur l'iPhone et ouvrir l'application. Appuyer sur le bouton Ajouter un tunnel et choisir l'option Créer à partir d'un QR code. Confirmer l'autorisation pour la caméra et scanner le code QR affiché dans le terminal. Nommer le tunnel et appuyer sur Sauvegarder en validant l'autorisation pour ajouter un VPN.
Le VPN est maintenant prêt à être utilisé. En tapant sur le bouton dans l'application, la connexion s'active et une petite icône VPN s'affiche tout en haut de l'écran de l'iPhone. On a désormais accès aux ressources locales !
Conclusion
Simplicité et rapidité de mise en place sont les deux grands avantages de Wireguard. J'ai pu ainsi mettre en place un système complet pour accéder à mon réseau local en déplacement et avoir un bon système de monitoring sans tout exposer directement sur Internet.
Le prochain article en lien avec celui-ci traitera justement de la mise en place de ma solution de monitoring à base de Netdata, de Prometheus et de Grafana.
Sources pour la rédaction de cet article :