Simulons un réseau maillé (mesh en anglais) avec Nebula en configurant 2 machines virtuelles à l’aide de Vagrant.
Le tout sera fait sur ma distribution Linux (Ubuntu 20.04) où j’ai déjà installé Virtualbox.
Vagrant
Vagrant est un outil de gestion de machines virtuelles de la société Hashicorp.
1sudo apt install -y vagrant
Je configure vagrant de telle façon à avoir 2 machines virtuelles sous debian 11, nommées boxA et boxB.
Leur interface réseau est directement branchée au réseau de ma machine, soit eth0
(à adapter selon sa propre configuration), pour avoir une IP sur mon réseau local via DHCP.
1cat <<EOF > Vagrantfile
2Vagrant.configure("2") do |config|
3 config.vm.define "boxA" do |boxA|
4 boxA.vm.box = "generic/debian11"
5 boxA.vm.network "public_network", bridge: "eth0"
6 end
7 config.vm.define "boxB" do |boxB|
8 boxB.vm.box = "generic/debian11"
9 boxB.vm.network "public_network", bridge: "eth0"
10 end
11end
12EOF
Je lance les machines virtuelles avec la commande :
1vagrant up
Nebula
Pour nebula, je récupère les binaires depuis github selon ma configuration, en l’occurrence nebula-linux-amd64.tar.gz
.
1wget https://github.com/slackhq/nebula/releases/download/v1.6.0/nebula-linux-amd64.tar.gz
Ensuite, je décompresse l’archive :
tar xf nebula-linux-amd64.tar.gz
J’obtiens 2 binaires : nebula et nebula-cert.
Le binaire nebula
sera à recopier et exécuter dans les machines virtuelles (voir plus bas). C’est lui qui établiera le pont entre les machines.
Le binaire nebula-cert
sert à générer tous les certificats nécessaires :
1./nebula-cert ca -name "ACME, Inc"
2./nebula-cert sign -name "boxA" -ip "192.168.168.100/24"
3./nebula-cert sign -name "boxB" -ip "192.168.168.200/24"
J’indique les IP que j’utiliserai pour le réseau maillé : 192.168.168.100
pour boxA et 192.168.168.200
pour boxB.
J’obtiens les fichiers suivants :
1ca.crt
2ca.key
3boxA.crt
4boxA.key
5boxB.crt
6boxB.key
Pour faciliter la gestion des configurations, je vais créer un dossier par machine virtuelle et j’y déplacerai les fichiers respectifs :
1mkdir boxA boxB
2mv boxA.* boxA && mv boxB.* boxB
Je génère un fichier de configuration nebula qui sera commun pour les deux machines.
Pour cela, je dois d’abord récupèrer leur IP publique (pas l’IP interne vagrant mais bien celle de mon réseau local) qui doit être sur l’eth1 de la VM:
D’abord sur boxA :
1boxAip=$(vagrant ssh boxA --no-tty -c "ip address show eth1| grep 'inet ' | sed -e 's/^.*inet //' -e 's/\/.*$//'" | tr -d '\r')
Ensuite sur boxB :
1boxBip=$(vagrant ssh boxB --no-tty -c "ip address show eth1| grep 'inet ' | sed -e 's/^.*inet //' -e 's/\/.*$//'" | tr -d '\r')
Les 2 adresses IP seront rangées dans les variables d’environnement $boxAip
et $boxBip
.
Ces 2 variables sont utilisées dans la configuration de Nebula ci-dessous, dans la section static_host_map
: les IP obtenues plus haut sont injectées pour faire la correspondance avec l’IP maillée (192.168.168.xxx)
1cat <<EOF > config.yml
2pki:
3 ca: /etc/nebula/ca.crt
4 cert: /etc/nebula/host.crt
5 key: /etc/nebula/host.key
6static_host_map:
7 "192.168.168.100": ["$boxAip:4242"]
8 "192.168.168.200": ["$boxBip:4242"]
9lighthouse:
10 am_lighthouse: false
11listen:
12 host: 0.0.0.0
13 port: 4242
14punchy:
15 punch: true
16tun:
17 disabled: false
18 dev: nebula1
19 drop_local_broadcast: false
20 drop_multicast: false
21 tx_queue: 500
22 mtu: 1300
23 routes:
24 unsafe_routes:
25logging:
26 level: info
27 format: text
28firewall:
29 conntrack:
30 tcp_timeout: 12m
31 udp_timeout: 3m
32 default_timeout: 10m
33 max_connections: 100000
34 outbound:
35 - port: any
36 proto: any
37 host: any
38 inbound:
39 - port: any
40 proto: any
41 host: any
42EOF
Configurons les machines virtuelles
On doit envoyer tous les fichiers nécessaires sur chacune des machines :
1# pour uploader depuis le host vers les vms
2vagrant upload ./boxA /tmp/ boxA
3vagrant upload ./boxB /tmp/ boxB
4
5# il faut aussi uploader le ca.crt
6vagrant upload ca.crt /tmp/ boxA
7vagrant upload ca.crt /tmp/ boxB
8
9# la config nebula
10vagrant upload config.yml /tmp/ boxA
11vagrant upload config.yml /tmp/ boxB
12
13# et le binaire nebula
14vagrant upload nebula /tmp/ boxA
15vagrant upload nebula /tmp/ boxB
Puis on se connecte sur chaque box pour finaliser la configuration. Commençons par nous connecter sur la machine a :
1vagrant ssh boxA
Une fois à l’intérieure de la machine A, on déplace et renomme les fichiers :
1sudo mkdir /etc/nebula
2sudo mv /tmp/config.yml /etc/nebula/config.yml
3sudo mv /tmp/ca.crt /etc/nebula/ca.crt
4sudo mv /tmp/boxA.crt /etc/nebula/host.crt
5sudo mv /tmp/boxA.key /etc/nebula/host.key
6sudo mkdir /opt/nebula
7sudo mv /tmp/nebula /opt/nebula/
8chmod +x /opt/nebula/nebula
Enfin, on lance nebula en arrière plan sur cette machine :
1cd /opt/nebula
2sudo ./nebula -config /etc/nebula/config.yml &
On se déconnecte de la machine A avec la commande exit
et on recommence avec la machine B. D’abord on s’y connecte :
1vagrant ssh boxB
Puis, on déplace les fichiers de configurations et on lance nebula :
1sudo mkdir /etc/nebula
2sudo mv /tmp/config.yml /etc/nebula/config.yml
3sudo mv /tmp/ca.crt /etc/nebula/ca.crt
4sudo mv /tmp/boxB.crt /etc/nebula/host.crt
5sudo mv /tmp/boxB.key /etc/nebula/host.key
6sudo mkdir /opt/nebula
7sudo mv /tmp/nebula /opt/nebula/
8chmod +x /opt/nebula/nebula
9cd /opt/nebula
10sudo ./nebula -config /etc/nebula/config.yml &
11exit
Maintenant, nous avons 2 machines virtuelles reliées par Nebula. Cool, mais comment vérifier que le réseau fonctionne ?
On se connecte sur la machine A et on tente de pinguer la machine B avec son IP Nebula, c’est-à-dire 192.168.168.200 :
1vagrant ssh boxA
2
3ping 192.168.168.200
Si tout fonctionne, le ping répond normalement. On peut faire l’exercice inverse, c’est-à-dire pinguer boxA depuis boxB.
Et enfin, pour arrêter toutes les machines virtuelles :
1vagrant halt
C’est tout pour aujourd’hui !