Expérimenter Nebula Mesh - Partie 1

samedi 16 juillet 2022 · 5 minutes · 863 mots

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 !

Technique Linux