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.
sudo 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.
cat <<EOF > Vagrantfile
Vagrant.configure("2") do |config|
config.vm.define "boxA" do |boxA|
boxA.vm.box = "generic/debian11"
boxA.vm.network "public_network", bridge: "eth0"
end
config.vm.define "boxB" do |boxB|
boxB.vm.box = "generic/debian11"
boxB.vm.network "public_network", bridge: "eth0"
end
end
EOF
Je lance les machines virtuelles avec la commande :
vagrant up
Nebula
Pour nebula, je récupère les binaires depuis github selon ma configuration, en l’occurrence nebula-linux-amd64.tar.gz
.
wget 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 :
./nebula-cert ca -name "ACME, Inc"
./nebula-cert sign -name "boxA" -ip "192.168.168.100/24"
./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 :
ca.crt
ca.key
boxA.crt
boxA.key
boxB.crt
boxB.key
Pour faciliter la gestion des configurations, je vais créer un dossier par machine virtuelle et j’y déplacerai les fichiers respectifs :
mkdir boxA boxB
mv 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 :
boxAip=$(vagrant ssh boxA --no-tty -c "ip address show eth1| grep 'inet ' | sed -e 's/^.*inet //' -e 's/\/.*$//'" | tr -d '\r')
Ensuite sur boxB :
boxBip=$(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)
cat <<EOF > config.yml
pki:
ca: /etc/nebula/ca.crt
cert: /etc/nebula/host.crt
key: /etc/nebula/host.key
static_host_map:
"192.168.168.100": ["$boxAip:4242"]
"192.168.168.200": ["$boxBip:4242"]
lighthouse:
am_lighthouse: false
listen:
host: 0.0.0.0
port: 4242
punchy:
punch: true
tun:
disabled: false
dev: nebula1
drop_local_broadcast: false
drop_multicast: false
tx_queue: 500
mtu: 1300
routes:
unsafe_routes:
logging:
level: info
format: text
firewall:
conntrack:
tcp_timeout: 12m
udp_timeout: 3m
default_timeout: 10m
max_connections: 100000
outbound:
- port: any
proto: any
host: any
inbound:
- port: any
proto: any
host: any
EOF
Configurons les machines virtuelles
On doit envoyer tous les fichiers nécessaires sur chacune des machines :
# pour uploader depuis le host vers les vms
vagrant upload ./boxA /tmp/ boxA
vagrant upload ./boxB /tmp/ boxB
# il faut aussi uploader le ca.crt
vagrant upload ca.crt /tmp/ boxA
vagrant upload ca.crt /tmp/ boxB
# la config nebula
vagrant upload config.yml /tmp/ boxA
vagrant upload config.yml /tmp/ boxB
# et le binaire nebula
vagrant upload nebula /tmp/ boxA
vagrant upload nebula /tmp/ boxB
Puis on se connecte sur chaque box pour finaliser la configuration. Commençons par nous connecter sur la machine a :
vagrant ssh boxA
Une fois à l’intérieure de la machine A, on déplace et renomme les fichiers :
sudo mkdir /etc/nebula
sudo mv /tmp/config.yml /etc/nebula/config.yml
sudo mv /tmp/ca.crt /etc/nebula/ca.crt
sudo mv /tmp/boxA.crt /etc/nebula/host.crt
sudo mv /tmp/boxA.key /etc/nebula/host.key
sudo mkdir /opt/nebula
sudo mv /tmp/nebula /opt/nebula/
chmod +x /opt/nebula/nebula
Enfin, on lance nebula en arrière plan sur cette machine :
cd /opt/nebula
sudo ./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 :
vagrant ssh boxB
Puis, on déplace les fichiers de configurations et on lance nebula :
sudo mkdir /etc/nebula
sudo mv /tmp/config.yml /etc/nebula/config.yml
sudo mv /tmp/ca.crt /etc/nebula/ca.crt
sudo mv /tmp/boxB.crt /etc/nebula/host.crt
sudo mv /tmp/boxB.key /etc/nebula/host.key
sudo mkdir /opt/nebula
sudo mv /tmp/nebula /opt/nebula/
chmod +x /opt/nebula/nebula
cd /opt/nebula
sudo ./nebula -config /etc/nebula/config.yml &
exit
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 :
vagrant ssh boxA
ping 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 :
vagrant halt
C’est tout pour aujourd’hui !