TP 16 : Déploiement Zero Trust Network Access (ZTNA) avec NetBird

Module : 5 – NetSecDevOps et Sécurité Automatisée Durée indicative : 2h Prérequis : un compte NetBird (Cloud, offre gratuite), deux pairs Linux accessibles (voir fichier d’environnement), Python 3, pip install requests

Objectifs

  • Comprendre le déploiement d’un réseau overlay WireGuard managé (NetBird).
  • Provisionner des pairs et des politiques d’accès via l’API REST NetBird.
  • Illustrer concrètement la différence ZTNA / VPN classique du Module 5.

Contexte

Deux machines (peer-web, peer-admin) doivent communiquer uniquement sur le port applicatif nécessaire, sans être exposées l’une à l’autre sur l’ensemble de leur sous-réseau — contrairement à un VPN classique qui les placerait sur le même LAN virtuel complet.

Étape 1 – Création du compte et du token API

  1. Créez un compte sur https://app.netbird.io (offre gratuite, jusqu’à 10 pairs).
  2. Settings → Service Users (ou Personal Access Tokens), générez un token API.
  3. Stockez-le dans .env :
NETBIRD_API_TOKEN=xxxxxxxxxxxx
NETBIRD_API_URL=https://api.netbird.io/api

Étape 2 – Inscription des pairs (agents)

Sur chaque machine (peer-web, peer-admin), installez l’agent NetBird :

curl -fsSL https://pkgs.netbird.io/install.sh | sh
sudo netbird up

Suivez le lien d’authentification affiché pour associer chaque pair à votre compte. Vérifiez leur apparition dans le tableau de bord NetBird.

Étape 3 – Lister les pairs via l’API

import os, requests
from dotenv import load_dotenv

load_dotenv()
HEADERS = {"Authorization": f"Token {os.getenv('NETBIRD_API_TOKEN')}"}
BASE = os.getenv("NETBIRD_API_URL")

resp = requests.get(f"{BASE}/peers", headers=HEADERS)
resp.raise_for_status()
for peer in resp.json():
    print(peer["name"], peer["ip"])

Étape 4 – Groupes et politique d’accès restrictive

Modèle d’objets NetBird : groupes et policy Modèle d’objets NetBird : groupes et policy peer-admin (groupe admin-clients) → policy admin-to-web-8080 → peer-web (groupe web-servers) ; tout le reste est refusé implicitement.

  1. Créez deux groupes via l’API (POST /groups) : web-servers et admin-clients, et associez chaque pair à son groupe.
  2. Créez une politique (POST /policies) autorisant uniquement admin-clients -> web-servers sur le port 8080/tcp, et refusant tout le reste par défaut.
policy_payload = {
    "name": "admin-to-web-8080",
    "enabled": True,
    "rules": [{
        "name": "allow-8080",
        "sources": ["<id-groupe-admin-clients>"],
        "destinations": ["<id-groupe-web-servers>"],
        "protocol": "tcp",
        "ports": ["8080"],
        "action": "accept"
    }]
}
requests.post(f"{BASE}/policies", json=policy_payload, headers=HEADERS).raise_for_status()

Étape 5 – Vérification du principe de moindre privilège

Sur peer-admin :

curl http://<ip-netbird-peer-web>:8080   # doit fonctionner
ping <ip-netbird-peer-web>               # doit échouer si ICMP non autorisé par la politique

Constatez que seul le flux explicitement autorisé passe — à la différence d’un VPN classique qui aurait exposé tout peer-web.

Rendu attendu

  • Script(s) Python d’automatisation (inscription vérifiée, groupes, politique) versionnés (.env exclu).
  • Une capture du tableau de bord NetBird montrant les deux pairs et la politique créée.
  • Un test démontrant qu’un flux non autorisé échoue bien.

Points de vérification

  • Les deux pairs apparaissent connectés dans NetBird.
  • La politique restreint bien l’accès au port 8080 uniquement, dans le bon sens.
  • Un flux hors politique (ex. ICMP) est bloqué, démontrant l’absence de confiance implicite.