SD-WAN
Définition
SD-WAN signifie Software Defined Wide Area Network. Cette technologie permet à des entreprises, organisations gouvernementales, mais aussi associations et particuliers (très motivés) de créer des réseaux privés virtuels interconnectant leurs différents réseaux à travers le monde. Les différents éléments composant une solution de SD-WAN permettent d’assurer:
- La haute-disponibilité des interconnexions, en s’affranchissant des contraintes liées aux opérateurs telco.
- L’interconnexion des ressources on-prem et cloud.
- l’accès aux ressources réseaux auxquelles ils et elles ont droit aux utilisateurs itinérants ou travaillant à domicile, en les authentifiant et en leur donnant uniquement l’accès aux ressources dont ils et elles ont besoin, de façon sécurisée et chiffrée (on est en 2026
).
- Combiné à des options de QoS (Qualité de Service) et de firewalling, de favoriser (ou pas…) certains flux en fonction des besoins (exemple: flux vidéos ou VoIP, etc), ce qui peut améliorer les performances du réseau perçues par les utilisateurs et utilisatrices.
- Une réduction des coûts par rapport aux solutions classiques proposées par les différents opérateurs (en général à base de MPLS).

Origines du SD-WAN, normes, terminologie et implémentations
Problématique
Historiquement, la création de liens réseau inter-sites est une tâche dévolue à l’opérateur de télécommunication de l’entreprise.
Techniquement, ce type d’interconnexion s’effectue de deux façons:
- Soit via des liens IPSec établis entre les routeurs sur site de l’opérateur, en règle générale pour les petites structures (PME/PMI).
- Soit via des liens MPLS nécessitants des équipements dédiés et de la configuration (assez complexe) côté opérateur (Label Edge Routers, Ingress et Egress Label Switch Routers (iLSR et eLSR), et de transit (P-routers), et donc beaucoup plus coûteux (mais très performants).
Bien que fonctionnelles et sécurisées (si elles sont mises en places dans les règles de l’art), ces solutions ont plusieurs défauts:
- Elles nécessitent que chaque site soit servi par le même opérateur telco (télécommunications, mais je vais abréger telco dans la suite
)
- Elles nécessitent de communiquer (tickets, etc) avec l’opérateur à chaque velléité de modification de la topologie du réseau, ce qui peut ralentir l’intégration d’un nouveau site au réseau de l’entreprise si l’opérateur n’est pas assez réactif
- Elles sont peu adaptées à l’intégrations de réseaux externe à l’entreprise (VPC cloud par exemple)
- En règle générale, elles permettent la liaison inter-sites, dans le sens où elles permettent de router le trafic réseau d’un site à l’autre, mais elles ne permettent pas de gérer finement l’identité et les droits des utilisateurs et utilisatrices accédant au réseau. En effet, peut-être que nous ne voulons pas que Michel du site de Nantes ait accès au réseau de Paris depuis son poste de travail.
- De plus, ces solutions ne permettent pas de favoriser les flux jugés importants par l’entreprise (QoS) et à l’inverse de limiter l’impact des flux jugés non-critiques, ou des flux dont l’utilisation de bande passante est jugée non prioritaire par l’entreprise (ex: reddit, réseaux sociaux, etc)
- De même, ces solutions sont en général assez rigide (ce qui se comprend du point de vue de l’opérateur telco) et sont peu adaptées au personnel itinérant, ou en télétravail, et nécessitent la mise en place de solutions dédiées, ajoutant au coût et à la surface d’attaque du réseau de l’entreprise.
- Enfin, elles sont peu adaptées aux problématiques de haute-disponibilité et d’interopérabilité: si le réseau de l’opérateur entre deux sites rencontre un problème, le lien entre ces sites va en pâtir: baisse de performances, perte de liens, etc.
Bien que ces solutions restent tout à fait valables d’un point de vue purement technique, leur rigidité et leur coût (notamment pour les liens MPLS) ont poussé les entreprises à rechercher des solutions alternatives permettant d’assurer des performances similaires tout en s’affranchissant de la dépendance à un seul opérateur telco, ce qui permet là aussi d’améliorer la haute-disponibilité des liaisons inter-sites (par exemple en utilisant plusieurs opérateurs) tout en réduisant les coûts liés à ces interconnexions. Le terme de SD-WAN (Software-Defined Wide Area Network) a commencé à circuler dès 2014, et sa popularité a connu une forte croissance notamment durant l’épidémie de COVID-19.
Le MEF: Historique, fonction.
En règle générale, les standards sur Internet sont définis par l’Internet Engineering Task Force (IETF). Dans le cas de SD-WAN, les bases ont été jetées par le MEF (Metro Ethernet Forum) dans la norme MEF 70. Le nom légal du MEF est MEF Forum. Il s’agit d’une organisation à but non-lucratif regroupant différents fournisseurs cloud, réseau et plus globalement du secteur des technologies de l’information, fondée en 2001.
Au début centré sur les problématiques des réseaux Ethernet opérateurs, ils ont étendu leur champ d’action à d’autres services comme la fibre optique, les réseaux IP, le cycle de vie de l’orchestration des services réseau (LSO, Lifecycle Service Orchestration, MEF 55) et donc, SD-WAN (Intégré dans la MEF 70).
Ils coopèrent avec l’IETF et l’IEEE dans la définition des standards réseau. SD-WAN s’appuie notamment sur les RFC 7149 (Software-Defined Networking: Perspectives, Mars 2014) et 7426 (Software-Defined Networking: Layers and Terminology, Janvier 2015).
Leur travail a été important sur la MEF-70 (https://www.mplify.net/wp-content/uploads/2019/07/MEF-70.pdf) pour bien définir la terminologie, les composants essentiels ainsi que leurs interactions dans la création d’un système de SD-WAN.
Terminologie MEF 70
Note: je simplifie volontairement afin de n’utiliser que la terminologie nécessaire pour ce module. La terminologie complète est disponible sur le lien précédemment fourni. Comme toute norme ou standard, un certains nombre d’éléments sont définis de façon atomique, afin d’apporter la meilleure précision possible à la définition de systèmes complexes. Lors de l’implémentation de la norme ou du standard, il peut être pertinent d’agglomérer certains éléments afin de faciliter la gestion, le déploiement et la mise à jour de la solution au quotidien.
| Acronyme | Signification | Définition |
|---|---|---|
| UNI | User Network Interface | une interface réseau physique ou virtuelle |
| USP | Underlay Service Provider | Le ou les FAI(s)/opérateurs telco sur lequel va s’appuyer notre SD-WAN |
| UCS | Underlay Connectivity Service. | Une connexion physique sur laquelle SD-WANva construire son overlay. C’est votre fournisseur réseau, votre routeur, etc, bref, l’underlay |
| UCS UNI | UCS + UNI | une interface UNI appartenant à une UCS (underlay) |
| SD-WAN UNI | Une interface UNI appartenant au SD-WAN (overlay) | |
| Egress IP Packet | Un paquet transmis par le service, sortant d’une UNI | |
| Ingress IP Packet | Un paquet reçu (entrant) par une UNI et transmis au service | |
| Application Flow | Flux identifié par un critère de flux (ex: HTTP(S), VoIP, etc) | |
| Application Flow Criterion | Règle (critère) permettant de classifier les paquets/flux reçus sur une UNI en vue d’y appliquer de la QoS et/ou des ACLs (Policy) | |
| Policy | Ensemble de règles appliquées à un Application Flow | |
| TVC | Tunnel Virtual Connection | Un lien Point-to-Point entre deux éléments du SD-WAN à travers l’UCS, dont on connaît les performances (BP, latence…) |
| SD-WAN Edge | Edge Router | Routeur entre le réseau virtuel et le réseau physique. Lie une UCS UNI avec une SD-WAN UNI. |
| SD-WAN VCEP | SD-WAN Virtual Connection End Point | Analyse le trafic d’une SD-WAN UNI pour y appliquer stratégie, QoS en fonction du fluxapplicatif demandé (Application Flow). |
| SD-WAN VC | SD-WAN Virtual Connection | Associe les SD-WAN VCEP aux routes nécessairespour qu’un Subscriber puisse accéder aux ressources voulues. |
| SPN | Service Provider Network | un SPN est l’ensemble des UCS, TVCs, Edge routers, contrôleurs et orchestrateurs qui permettent de fournir le service SD-WAN à un Subscriber |
| SD-WAN Service Provider | Un fournisseur de service SD-WAN. | |
| SD-WAN Subscriber | Utilisateur, routeur, etc | Un SD-WAN Subscriber est un utilisateur du SD-WAN. Machine ou humain. |
Objectifs des solutions SD-WAN
Dès lors, une solution de SD-WAN se doit:
- D’avoir un coût d’exploitation faible (relativement)
- De permettre de répartir la charge ou de procéder à un failover en cas de perte de lien d’un opérateur.
- De chiffrer de façon forte les communications inter-sites, car dès lors on ne repose plus sur un réseau contrôlé par l’opérateur telco mais on utilise directement Internet pour interconnecter nos sites (ou un mix des deux)
- De proposer, dans la mesure du possible, des options fines de QoS, et donc d’analyse des flux réseaux et ce jusqu’à la 7è couche du modèle OSI (ou la 4è du modèle TCP/IP DoD), ce qu’on appelle le Deep Packet Inspection (DPI), technique dont le coût en puissance de calcul est non-négligeable, et dont la dimension éthique ne s’applique pas dans le cadre d’un réseau d’entreprise (c’est une autre situation que sur le réseau public aka Internet).
- Et enfin, idéalement, d’authentifier les utilisateurs et de gérer leurs droits sur le réseau “WAN” créé par notre solution.
Composants décrits par la norme SD-WAN
En règle générale, un SD-WAN est composé:
- D’un ou plusieurs (idéalement… plusieurs, pour des raisons évidentes de haute-disponibilité) orchestrateurs, dont le rôle est de permettre la configuration du réseau via différentes interfaces de gestion et de contrôle (CLI, WebUI), permettant de centraliser les informations du réseau, de son administration et de ses permissions.
- D’un ou plusieurs contrôleurs (Controller, idéalement, plusieurs
), en général incorporés dans la solution d’orchestration, soit au niveau des orchestrateurs, soit au niveau des passerelles (cf plus bas), dont le rôle est de décider et d’appliquer les règles métiers définies pour chaque type de flux.
- De routeurs de bordure (Edge routers), physiques ou virtuels (VM, conteneurs) sur chaque site.
- De passerelles (Gateway routers) sur Internet (idéalement chez plusieurs hébergeurs en fonction des besoins fonctionnels et géographiques), là aussi, physiques ou virtuels.
- Optionnellement (mais préférablement), d’une solution externe d’identification des utilisateurs (OIDC, LDAP, etc), qui peut être couplée à l’identification interne de la solution de SD-WAN. On peut tout à fait imaginer une “posture”, où, lorsqu’un utilisateur s’est authentifié (c’est en général transparent) à la solution de SD-WAN, va donner l’accès à la solution d’authentification externe (AD, Keycloak, Authentik, etc), puis va aller l’interroger, et enfin donner l’accès aux ressources correspondant au niveau d’accès de l’utilisateur une fois authentifié sur l’IdP externe.
Capacités permettant de définir un SD-WAN au sens du MEF Forum (MEF 70)
Un SD-WAN doit être capable de:
- fonctionner au travers de multiples types de réseaux hétérogènes: FTTH, 4G/5G, MPLS, Internet, etc. (c’est l’underlay du réseau SD-WAN, l’overlay étant le réseau logique (VPN) du SD-WAN)
- d’être capable de choisir automatiquement (“automagiquement”
) les meilleurs chemins réseaux pour garantir la meilleur qualité de service (il se rapproche de protocoles de routage dynamique à état de lien comme OSPF) ou pour garantir la résilience du réseau SD-WAN aux pannes, et donc disposer de capacités de self-healing.
- Il doit fournir une interface de gestion - relativement - accessible
- Il doit supporter un fonctionnement site à site et client-to-network (VPN), et être compatible avec différents types de pare-feux.
- Et bien évidemment il doit être sécurisé: les communications entre chaque élément, site et utilisateur du SD-WAN doivent bien évidemment être chiffrées! (sinon on ferait juste du VxLAN et des connexions IP-IP
).
- Idéalement, la solution de SD-WAN doit adhérer aux principes Zero Trust, car elle doit combiner les liaisons site-à-site du réseau de l’entreprise mais aussi les liaisons éphémères des utilisateurs et utilisatrices itinérants ou travaillant à distance (télétravail).
- Il doit être facilement dimensionnable: on doit pouvoir ajouter ou supprimer des noeuds du réseau (Edge, Gateways, etc) facilement, rapidement et de façon sécurisés, en fonction de l’évolution du besoin.
Pour simplifier!
Pour simplifier, un SD-WAN c’est principalement:
- Un ensemble d’Orchestrateurs qui vont nous fournir une interface de gestion du SD-WAN, nous permettant de mettre en place l’identification des machines et utilisateurs du réseau, les permissions de chacun, dont les :
- Contrôleurs vont se servir pour définir les meilleurs routes possibles pour accéder à telle partie du réseau overlay ou à tel service hébergé sur un des sites accessibles, en vérifiant à intervalle régulier le bon fonctionnement de ces routes, et vont transmettre ces informations aux:
- Gateways du réseau, c’est à dire les machines par qui les flux vont transiter entre sites et utilisateurs, elles mêmes connectées aux:
- Edge-routers sur site. Les utilisateurs mobiles ou en télétravail peuvent être considérés comme des edge-routers ne routant rien par certaines implémentations (et notamment OpenZiti ou Netbird).
- Techniquement, il est possible de router leurs réseaux domestiques ou des services spécifiques de ces réseaux, mais ce n’est normalement pas le but. Cependant, cela peut être pratique pour exposer sur l’overlay un service de type RDP ou SSH sans risquer de l’exposer sur le réseau underlay (public ou domestique) en le faisant écouter sur localhost - vous allez voir, on va en créer quelques uns sur la partie TP
.
- Techniquement, il est possible de router leurs réseaux domestiques ou des services spécifiques de ces réseaux, mais ce n’est normalement pas le but. Cependant, cela peut être pratique pour exposer sur l’overlay un service de type RDP ou SSH sans risquer de l’exposer sur le réseau underlay (public ou domestique) en le faisant écouter sur localhost - vous allez voir, on va en créer quelques uns sur la partie TP
Bien évidemment, chaque solution est libre d’implémenter ces différents composants (voire, de les agglutiner entre eux) en fonction des besoins qu’elle doit couvrir et de ses utilisateurs cible. Une PME n’a pas les mêmes besoins, ni les mêmes moyens, qu’une multinationale, cependant l’un comme l’autre peuvent s’appuyer sur la norme MEF-70 pour choisir (ou créer!) une solution répondant au mieux à leur besoin en fonction de leur budget, tout en conservant le meilleur niveau de sécurité possible.
Par exemple, une solution “ultra-classique” (bienvenue en 2010!) à base de liens IPSec entre différents sites, et de VPN OpenVPN dont les utilisateurs s’authentifie d’abord par certificats puis sur un LDAP (AD, OpenLDAP, etc) via un serveur RADIUS, donnant accès à certaines routes bien précises à chaque utilisateur du VPN en fonction de son rôle dans l’entreprise constitue un embryon de SD-WAN: il lui manque la haute-disponibiilité et la répartition de charge, une interface de gestion unifiée, ainsi que la gestion de la QoS pour devenir un SD-WAN à part entière.
De plus, la plupart des solutions de SD-WAN commerciales actuelles s’appuient sur des technologies déjà éprouvées, qu’elles vont orchestrer pour obtenir les niveaux de service désirés, notamment:
- IPSec
- OIDC, LDAP/AD, et autres fournisseurs d’identité
- BGP pour la partie routage dynamique, du fait de sa simplicité de mise en œuvre (en utilisant les numéros d’AS privés: AS 64512 à 65535 (historiques, à l’époque où les numéros de systèmes autonomes étaient codés sur 16 bits) et AS 4200000000 à 4294967294 - mais le dernier numéro d’AS 32 bits 4294967295 est interdit par la RFC 7300)
Solutions
Libres/Open-Source
Les “gros” (aka usines à gaz)
- OpenDaylight
- ONAP
- Tungsten Fabric
À titre d’indication, un contrôleur OpenDaylight, c’est minimum 8Go de RAM et 4 vCPUs, à dimensionner en fonction du besoin.
ONAP requiert carrément un cluster Kubernetes avec 112 vCores, 224GB RAM et 160GB (seulement ) de storage idéalement répartis sur plusieurs workers pour un déploiement, cf https://docs.onap.org/projects/onap-oom/en/oslo/sections/guides/infra_guides/oom_infra_deployment_requirements.html
Bien évidemment, c’est une solution open-source taillées pour les très (très) grosses entreprises ayant de très (très) gros besoins .
Les “légers”
- Netbird utilise Wireguard “sous le capot”, donc fonctionne principalement en UDP, STUN/TURN si TCP est requis ou si le NAT traversal UDP est refusé, Zitadel par défaut comme IdP (mais ça se change)
- OpenZiti: utliise mTLS (mutual TLS), en TCP. ACLs très fines et structure se rapprochant plus du standard MEF 70.
- Defguard: utilise aussi Wireguard sous le capot, tout comme Netbird. Par contre leur licensing est assez flou…
À titre d’exemple, un contrôleur Netbird (+IdP) c’est 2 vCPUs, 2Go de RAM pour environ 300 machines et utilisateurs, un contrôleur OpenZiti, c’est 1 vCPU/1Go de RAM pour une centaine de machines et utilisateurs. On conserve donc beaucoup des avantages de la norme SD-WAN, tout en restant sur des configurations raisonnables pour des petits déploiements, ainsi qu’une scalabilité raisonnable pour des déploiements plus importants.
En général ces solutions font l’impasse sur la QoS qui implique des méthodes de DPI (Deep Packet Inspection), du fait du coût en puissance de calcul de cette technique - ce n’est pas pour rien qu’ONAP requiert autant de ressources! - ainsi que sur l’implémentation exacte de la norme MEF 70. Cependant, ces solutions permettent d’obtenir des niveaux de fonctionnalité similaires à ce qui est requis par la norme pour une fraction des coûts et sont donc adaptées en tant que solutions alternatives pour les réseaux SD-WAN de petite à moyenne dimensions (voire plus pour leurs offres SaaS).
Propriétaires/”Corpos”
Pure players (ils ne font que ça)
- En Europe: Telerys Communications, Sayse
- Mondiaux: Aryaka, Peplink, Barracuda…
Les omniprésents (et ils ne font pas que ça)
- Les fabricants de matériels dédiés: Cisco (Meraki, Catalyst), Ericsson, Broadcom VMWare, HPE (Aruba EdgeConnect), Palo-Alto (Prisma, PAN-OS), Fortinet, Huawei (cough cough), etc, qui proposent tous des solutions dédiées et/ou intégrées à leurs produits phares.
- Les opérateurs telco comme Orange, Verizon, Deutsche Telekom, etc, qui vont en général utiliser des solutions tierces et les revendre à leurs clients, en s’occupant de la gestion et de l’orchestration de ces solutions (et on retombe dans la problématique initiale…)
SaaS “grand public”:
- Tailscale
- Cloudflare Magic Wan
- Netbird.io (basé sur… Netbird, qui l’eut crû)
- NetFoundry (basé sur OpenZiti)
Mise en place
Pourquoi OpenZiti
Alors, j’adorerai qu’on puisse jouer avec ONAP, cependant la configuration minimale recommandée n’est pas adaptée ni à nos configurations (laptop et homelabs), ni aux labos dont nous disposons sur le campus
OpenZiti a ici l’avantage de la légèreté, il va nous permettre d’interconnecter nos labos (VMs sur vos laptops qui feront office d’edge-routers et tunnelers (qui vont nous servir de “points de sortie” - à noter qu’un Edge Router dans la terminologie OpenZiti est aussi capable de fonctionner comme un tunneler), avec des configurations minimales (vu que nous ne visons pas des performances ultimes ): 1 coeur, 1Go de RAM (voire 512Mo pour les VMs ), 8Go de disque seront amplement suffisants pour nos machines virtuelles.
De plus, OpenZiti étant développé en Go, il propose des paquets, exécutables, conteneurs, chartes Helm pour un large panel de systèmes d’exploitations et outils:
- Linux (Debian-likes, RedHat/RPM)
- macOS
- Windows
- Docker
- Kubernetes
- Android
- iOS
- FreeBSD
- OpenBSD (via compilation manuelle)
On va donc créer 3 petites machines virtuelles sous Debian: un “Edge Router”, un tunneler, et une machine client, sans interface graphique. Si vous avez plus de ressources, vous pouvez créer une machine client avec GUI, par exemple 2 coeurs/4Go de RAM. Idéalement, on va utiliser Debian Trixie (13) sur toutes nos VMs.
En prime, on dispose d’une interface d’administration Web plutôt sympathique:

Interface qu’il est important de faire écouter uniquement en localhost, et que nous servirons depuis l’Overlay à l’adresse https://zac.supdevinci.ziti/zac - vous allez voir, c’est très sympa quand ça tombe en marche!
Exemple (tiré de la doc’) de l’architecture d’OpenZiti:

Mise en place du contrôleur (ça c’est pour moi
)
Notre contrôleur va aussi nous servir de passerelle, donc, il vaut mieux qu’il se trouve sur Internet dans notre cas. Tout notre trafic réseau va passer par lui (et on ne voudrait pas faire ça en prod’ !)
Dans la vraie vie, on voudrait disposer de plusieurs Edge-Routers/Gateways, et de plusieurs contrôleurs (pour la haute disponibilité), dispatchés dans des datacenters différents (ou chez différents hébergeurs).
De la même manière, nos edge-routers vont faire du NAT, là où, normalement, ils auraient une interface (UNI) connectée directement à Internet (ou du moins, avec les ports nécessaires forwardés par notre routeur sur site) et une autre connectée aux VLANs nécessaires de nos sites. Là aussi, on voudrait à minima deux edge-routers par site et deux FAIs par site. OpenZiti s’occupera tout seul de la répartition de charge, du failover en cas de coupure, etc.
De mon côté, j’ai une VM déjà prête (on va vérifier qu’on a bien de la connectivité IPv6 sur le campus, sinon j’ajouterai une IPv4), il ne me reste qu’à installer OpenZiti.
Pour cela, je dois déjà ajouter le dépôt. On va d’abord ajouter au trousseau la clef GPG publique d’OpenZiti, qui permettra de s’assurer que ce que l’on télécharge provient bien de NetFoundry , puis ajouter le dépôt et enfin rafraîchir la base de données locale des paquets de notre distribution:
UBUNTU_LTS=jammy
echo "deb [signed-by=/usr/share/keyrings/openziti.gpg] https://packages.openziti.org/zitipax-openziti-deb-stable $UBUNTU_LTS main" \
| sudo tee /etc/apt/sources.list.d/openziti.list >/dev/null
curl -sSLf https://get.openziti.io/tun/package-repos.gpg \
| sudo gpg --dearmor --output /usr/share/keyrings/openziti.gpg
sudo chmod -c +r /usr/share/keyrings/openziti.gpg
sudo apt update
il ne me reste, dans mon cas qu’à installer les paquets nécessaires à mon contrôleur (qui va aussi servir de Gateway) - dans votre cas, vous installerez sur votre première VM les paquets openziti et openziti-router, et sur votre VM “tunneler” uniquement le paquet ziti-edge-tunnel, ainsi que sur votre machine cliente:
sudo apt install openziti openziti-controller openziti-router
Note: l’installation par défaut d’openziti-router le préconfigure aussi comme tunneler
Je vais ensuite pouvoir configurer mon contrôleur (et le routeur), en éditant le fichier /var/lib/ziti-controller/config.yml:
v: 3
db: "/var/lib/ziti-controller/bbolt.db"
identity:
cert: "pki/intermediate/certs/client.chain.pem"
server_cert: "pki/intermediate/certs/server.chain.pem"
key: "pki/intermediate/keys/server.key"
ca: "pki/root/certs/root.cert"
ctrl:
options:
advertiseAddress: tls:sdv-controller.lidstah.info:1280
listener: tls:0.0.0.0:1280
healthChecks:
boltCheck:
interval: 30s
timeout: 20s
initialDelay: 30s
edge:
api:
sessionTimeout: 30m
address: sdv-controller.lidstah.info:1280
enrollment:
signingCert:
cert: pki/intermediate/certs/intermediate.cert
key: pki/intermediate/keys/intermediate.key
edgeIdentity:
duration: 180m
edgeRouter:
duration: 180m
web:
- name: client-management
bindPoints:
- interface: 0.0.0.0:1280
address: sdv-controller.lidstah.info:1280
identity:
ca: "pki/root/certs/root.cert"
key: "pki/intermediate/keys/server.key"
server_cert: "pki/intermediate/certs/server.chain.pem"
cert: "pki/intermediate/certs/client.chain.pem"
options:
readTimeout: 5000ms
writeTimeout: 100000ms
minTLSVersion: TLS1.2
maxTLSVersion: TLS1.3
apis:
- binding: edge-client
options: { }
- binding: fabric
options: { }
- binding: edge-oidc
options: { }
- name: web-management
bindPoints:
- interface: 127.0.0.1:8443
address: localhost:8443
identity:
ca: "pki/root/certs/root.cert"
key: "pki/intermediate/keys/server.key"
server_cert: "pki/intermediate/certs/server.chain.pem"
cert: "pki/intermediate/certs/client.chain.pem"
options:
readTimeout: 5000ms
writeTimeout: 100000ms
minTLSVersion: TLS1.2
maxTLSVersion: TLS1.3
apis:
- binding: edge-management
options: { }
- binding: zac
options:
location: /opt/openziti/share/console
indexFile: index.html
Note importante: remarquez bien le bloc - name: web-management. Je force volontairement le service edge-management et le service zac (la WebUI) à écouter sur localhost. Ainsi, je n’expose pas la ZAC sur Internet directement, ce qui me permet de limiter la surface d’attaque correctement. Pour le moment, je vais accéder à la ZAC via un port-forwarding SSH: ssh -L 8443:127.0.0.1:8443 sdv-controller.lidstah.info, et je vais ensuite configurer un service OpenZiti pour accéder à la ZAC depuis l’overlay à l’URL https://zac.supdevinci.ziti.
Note sur le serveur OpenSSH: bien évidemment, on utilisera l’authentification par couple de clefs asymétriques (à minima RSA 2048 bits, 4096 de préférence, ou mieux, ED25519), idéalement par certificats, et on désactivera toujours l’authentification par login/mot de passe - on est en 2026! Vous avez normalement été formés là-dessus, cependant n’hésitez pas à me demander si vous avez besoin de rafraîchir votre mémoire!
Mise en place Edge-Routers
Une fois ajouté le dépôt OpenZiti à nos VMs routers, il nous suffit d’installer le paquet openziti-router.
Nous allons ensuite, dans la ZAC OpenZiti (c’est aussi faisable en CLI) ajouter un Edge-Router:

Pour le moment, notre routeur n’est pas encore joint au réseau Overlay. Pour cela, nous allons récupérer le token JWT, qui va nous servir à authentifier le routeur sur le réseau la première fois, pour générer les différents secrets et certificats mutual TLS (mTLS) qui seront utilisés par la suite pour authentifier les différents membres de l’overlay.
On récupère donc ce token, on le copie sur notre VM “Edge-router” (via SSH par exemple en utilisant la commande scp), puis, sur notre edge-router, nous allons lancer le script de bootstrap qui va nous permettre de rejoindre le réseau en répondant de façon interactive à plusieurs questions:
sudo /opt/openziti/etc/router/bootstrap.bash
On peut aussi (notamment si on veut utiliser des logiciels de gestion de configuration comme Ansible ou Puppet) peupler les variables d’environnement suivantes avant d’exécuter le script de bootstrap:
- ZITI_CTRL_ADVERTISED_ADDRESS - le nom DNS du contrôleur
- ZITI_CTRL_ADVERTISED_PORT - le port du contrôleur (par défaut: 1280)
- ZITI_ENROLL_TOKEN - le chemin du fichier contenant notre token d’enrôlement (ou directement son contenu)
- ZITI_ROUTER_ADVERTISED_ADDRESS - Le nom DNS ou l’adresse IP de notre routeur, par défaut localhost
- ZITI_ROUTER_PORT - le port d’écoute du routeur (par défaut: 3022)
Une fois le routeur joint au réseau, il devrait apparaître dans la ZAC.
Jetons un œil à la configuration d’un Edge-Router, qui se trouve dans /var/lib/private/ziti-router/config.yml
v: 3
identity:
cert: "router.cert"
server_cert: "/var/lib/private/ziti-router/router.server.chain.cert"
key: "/var/lib/private/ziti-router/router.key"
ca: "/var/lib/private/ziti-router/router.cas"
#alt_server_certs:
# - server_cert: ""
# server_key: ""
ha:
enabled: false
ctrl:
endpoint: tls:carcosa.lidstah.info:1280
link:
dialers:
- binding: transport
listeners:
- binding: transport
bind: tls:0.0.0.0:3022
advertise: tls:carcosa.lidstah.info:3022
options:
outQueueSize: 4
listeners:
- binding: edge
address: tls:0.0.0.0:3022
options:
advertise: carcosa.lidstah.info:3022
connectTimeoutMs: 5000
getSessionTimeout: 60
- binding: tunnel
options:
mode: host #tproxy|host
edge:
csr:
country: US
province: NC
locality: Charlotte
organization: NetFoundry
organizationalUnit: Ziti
sans:
dns:
- localhost
- carcosa.lidstah.info
- carcosa
ip:
- "127.0.0.1"
- "::1"
forwarder:
latencyProbeInterval: 0
xgressDialQueueLength: 1000
xgressDialWorkerCount: 128
linkDialQueueLength: 1000
linkDialWorkerCount: 32
Mise en place tunnelers/clients
De la même façon, nous allons créer, pour nos tunnelers, non pas des routeurs, mais des identités dans notre ZAC (au passage, nous verrons aussi que notre contrôleur et nos edge-routers ont aussi des identités):

De la même façon que pour nos Edge-routers, nous allons récupérer le token JWT d’enrôlement et le copier sur notre machine. À noter que c’est exactement la même procédure pour enrôler un client (c’est aussi le service ziti-edge-tunnel qui est utilisé pour joindre les clients finaux/utilisateurs au réseau Overlay).
Sur notre tunneler, nous allons installer le paquet ziti-edge-tunnel puis l’activer avec la commande systemctl enable —now ziti-edge-tunnel.service (le .service à la fin est optionnel) et enfin, enrôler notre tunneler (ici, notre token s’appelle token.jwt, et l’identité créée est “tunneler-1” - adaptez en fonction de vos choix de nommage):
sudo ziti-edge-tunnel add --jwt "$(< ./token.jwt)" --identity tunneler-1
Et voilà, notre tunneler est lui aussi joint au réseau.
Nous allons ensuite procéder de la même manière pour nos VMs clients graphique:
- Créer l’identité du client
- récupérer le token JWT d’enrôlement
- installer
ziti-edge-tunnelsur le client - Enrôler le client
- Profit
Mise en place des règles d’accès entre routeurs
Pour le moment, si nos différentes VMs ont bien rejoint le réseau Overlay, pour le moment, eh bien… elles n’ont accès à rien du tout!
En effet, par défaut OpenZiti se base sur les principes Zerotrust: par défaut, un routeur, un tunneler ou un utilisateur n’ont aucun accès aux ressources de l’overlay.
Nous allons commencer par créer des règles simples - trop simples et bien trop permissives, nous les afinerons par la suite - afin d’avoir accès à tout l’overlay, et d’exposer un premier service - la ZAC - sur l’overlay à toutes nos identités utilisateurs finaux afin d’accéder depuis l’overlay à la ZAC. Ça va me permettre de me passer du port-forwarding SSH que nous utilisons pour le moment. Au revoir:
ssh -L 0.0.0.0:8443:127.0.0.1:8443 sdv-controller.lidstah.info!
et bonjour: https://zac.supdevinci.ziti/zac/!
Nous allons donc devoir:
- Créer une “Router Policy”, pour le moment de type all/all (le any/any à la sauce OpenZiti). Notre contrôleur/gateway conservera ce rôle pour la suite, mais vos edge routers eux, non. Comme notre contrôleur/gateway est le seul lien entre les différents routeurs et tunnelers, il devra par contre conserver ce rôle (surtout si on veut rejoindre mon VxLAN chez moi
)
- Créer une configuration de type intercept.v1 pour nos clients, qui va intercepter (comme son nom l’indique!) le trafic au niveau des clients à destination du FQDN zac.supdevinci.ziti
- Créer une configuration de type hosts.v1, assigné à notre contrôleur, qui va lui, faire la passerelle entre le FQDN et l’adresse localhost:8443 du contrôleur
- Joindre ces deux configurations dans un service
- Et enfin créer deux Service Policies, zac-in et zac-out, qui vont déterminer respectivement les utilisateurs pouvant accéder à ce service et le(s) edge-router(s) ou tunnelers servant ce service, dans notre cas, notre contrôleur/passerelle (donc, lui aussi un edge-router).
Nous pourrons ensuite appliquer ces différents mécanismes aux différents services et sous-réseaux que nous voudrons exposer à nos différents routeurs et utilisateurs de notre Overlay.
Router Policies et Service Router Policies
Ces politiques déterminent:
- Quels routeurs ont accès à quelles identités (et quel groupe d’identité) dans le cas des Router Policies
- Quels routeurs ont accès à quels services exposés sur l’overlay (un Service peut aussi annoncer un subnet, par exemple, permettre d’accéder au réseau LAN d’un site distant)
En jouant sur ces différentes politiques, on peut donc assez facilement limiter l’accès utilisateur à certains routeurs (et donc aux ressources et services auxquels ils ont eux-mêmes accès) mais aussi quels services sont “annoncés” par quels routeurs.
Par exemple, on peut avoir un routeur nommé “router-st-nazaire-admin” lié uniquement aux identités appartenant au groupe “administrators”, et lié au service “active-directory-management-st-nazaire”.
Ce même routeur peut aussi être lié au service “LAN-saint-nazaire”, qui permettra aux identités membres du groupe administrateur d’accéder au sous-réseau privé du site de Saint-Nazaire.
Par exemple, une router-policy “all-all”:

et une service router policy où seuls les routeurs taggés “#home” ont accès à tous les services:

Évidemment, il est important de bien planifier quels routeurs ont accès à quelles identités et services. À propos de services…
Services
Les services sont composés de deux configurations, et deux Services Policies.
Les configurations permettent de déterminer:
- quel trafic réseau va être intercepté au niveau des clients ou en ingress
- Où le trafic réseau intercepté au niveau des clients va être distribué au niveau des edge-routers et tunnelers (en egress, donc)
Les Service Policies, elles, déterminent:
- Quels clients vont accéder à un service (en ingress)
- Quels routeurs sont aptes à distribuer le trafic lié à ce service (en egress, donc)
Ce comportement a une particularité: imaginons une requête http pour un FQDN donné intercepté au niveau d’un client, elle va être acheminée à travers l’overlay jusqu’au routeur d’egress. En règle générale, la réponse suivra le même chemin, mais pas obligatoirement! Le client peut en effet recevoir la réponse d’un autre routeur, et cette réponse peut suivre un autre trajet dans l’overlay, notamment s’il est plus rentable d’un point de vue performance d’utiliser un chemin différent.
Services et configurations liées à ces services
Tout d’abord, pour créer un service, nous devons créer deux configurations - nous utiliserons pour cela des templates déjà prêts:
- Une configuration d’interception du trafic (de type Intercept.v1)
- Une configuration d’interception peut intercepter des requêtes DNS, des requêtes IP, voire des requêtes destinées à un sous-réseau entier, ou un domaine entier, ou les deux.
- Un des avantages de cette méthode est de permettre de router des requêtes à destination d’un domaine, d’un sous-domaine ou d’un FQDN sans que le client ait connaissance de la topologie réseau sous-jacente.
- Pour cela, OpenZiti crée un réseau virtuel côté client, exécute un serveur DNS léger côté client, et va assigner une IP (de type CG-NAT, 100.64/10, par défaut) et un enregistrement DNS locaux à chaque service auquel le client peut accéder.
- Les protocoles de transport supportés sont UDP et TCP - mais pas ICMP! Lorsque vous “pinguez” un service OpenZiti, vous “pinguez” sa “représentation locale” au niveau du client (d’où les pings de 0.2ms pour celles et ceux qui ont déjà testé
).
- Un exemple de configuration d’interception pour tout le subnet 10.53.0.0/22 et tous les ports (1 à 65535), protocoles TCP et UDP:

- Une configuration d’hôte permettant de router le trafic vers sa destination (de type Hosts.v1)
- Une configuration de type hôte permet de configurer un (ou plusieurs!) edge-routers et tunnelers:
- comme de vrais routeurs Egress/Ingress avec NAT vers un subnet.
- comme des reverse-proxies TCP ou UDP purs.
- Un hôte peut aussi héberger un service local, et l’exposer sur l’overlay sans l’exposer sur le réseau underlay.
- Un exemple de configuration hosts.v1 pour le réseau précédent:
- Une configuration de type hôte permet de configurer un (ou plusieurs!) edge-routers et tunnelers:

Ici, on voit que tout le trafic pour tous les ports et tout le bloc 10.53/22 est intercepté puis transmis, avec NAT et forwarding (i.e. pas besoin de configurer les VMs avec net.ipv.ip_forward pour qu’elles se comportent comme des routeurs), au VLAN 53 . On pourrait bien sûr limiter les intervalles de ports transmis. Il s’agit d’un Service se comportant comme un VPN classique, réservé aux membres du groupe admin du réseau.
- Enfin, notre service sera la combinaison de ces deux configurations, mais aussi de deux Service Policies dont nous allons parler maintenant:
Service Policies
Les Stratégies de Services (Service Policies) permettent de définir quelles identités, groupe d’identités, routeurs, ont accès aux services précédemment créés.
Un Service est toujours la combinaison:
- de deux Configurations
- de deux Service Policies
Par exemple:

Par exemple, le service ci-dessus est un service composé de deux configurations:
- https-mobile-client, une configuration intercept.v1 qui intercepte tout le trafic HTTPS (port 443, donc) à destination d’*.lidstah.info
- https-mobile-server, une configuration hosts.v1 qui se contente de forwarder par le tunneler de sortie tout ce qui est à destination d’*.lidstah.info (la résolution DNS du tunneler s’occupant de la traduction)
Mais aussi de deux Service Policies:
- https-mobile-in-policy, qui lie mes clients taggés #mobile (i.e les smartphones de la maison dans ce cas) au service https-mobile-svc
- https-mobile-out-policy, qui lie les routeurs ayant accès aux ressources voulues au service en question.
De cette manière, les smartphones Android correspondant aux identités taggées #mobile n’ont accès qu’aux services HTTPS via leur FQDN et n’ont aucune notion de leur topologie physique (ni même de leur topologie dans l’overlay).
Exposons la ZAC dans l’overlay (promis, après c’est à vous!)
Pour pouvoir accéder à la ZAC directement depuis l’overlay, on va avoir besoin:
- Que vous ayez tous une identité, et que votre VM client (avec GUI) soit connectée au réseau
- Que vous apparteniez à un groupe (par exemple #zacadmins) qui aura les permissions nécessaires pour accéder au:
- Service exposant notre ZAC, lequel doit donc être composé:
- d’une configuration Intercept.v1 interceptant les requêtes à destination de zac.supdevinci.ziti
- d’une configuration Hosts.v1 servant les requêtes à destination de zac.supdevinci.ziti en TCP, sur le port 8443 de localhost du contrôleur
- d’une Service Policy zac-in-policy autorisant les utilisateurs membres du groupe #zacadmin à accéder au service @zac-svc (oui, @quelquechose → le service “pur”, pas son tag)
- et enfin d’une autre Service Policy, zac-out-policy, liant notre contrôleur (@sdv-controller.lidstah.info - on utiliserait un tag si nous avions plusieurs contrôleurs) au service @zac-svc
Cela va me permettre d’aborder un dernier point concernant OpenZiti: le concept de Terminateurs (Terminators)

Terminators
Un terminateur est un Edge-router, mais jamais un Tunneler, ayant une connexion directe avec la ressource, soit parcequ’il l’héberge, soit parcequ’il dispose d’une route directe ou indirecte lui permettant d’accéder à la ressource via un Tunneler (n’oublions pas qu’un Edge-Router peut être configuré pour se comporter comme un Tunneler, c’est d’ailleurs sa configuration par défaut).
Si un Service ne dispose pas de Terminator, alors, ce Service sera inaccessible.
Par exemple, le service Zac de mon propre réseau personnel a pour Terminator du service zac.ziti mon contrôleur:

Accédons à un service que VOUS hébergez, à vous de bosser :rolling_on_the_floor_laughing:!
Un simple serveur nginx ou apache2 sera suffisant.
Pour cela, installez nginx ou apache2 sur votre VM Edge-Router Tunneler, et configurez un Service dans la ZAC pour qu’on puisse y accéder:
- Une configuration Intercept.v1 pour définir les groupes d’identités autorisés à accéder à la ressource: groupeX-intercept-nginx-config
- Une configuration Hosts.v1 pour définir les routeurs permettant d’accéder à la ressource groupeX-host-nginx-config
- un service groupeX-nginx-svc
- Une Service Policy groupeX-nginx-in-policy
- Et enfin une Service Policy groupeX-nginx-out-policy
Où groupeX est le nom de votre groupe. Ce service devra être joignable avec le FQDN groupeX.nginx.ziti (ou autre si vous êtes imaginatifs ou si vous avez envie de rigoler )
Accédons à un service hébergé chez moi, dans le VxLAN dédié à votre groupe.
À mon tour de bosser
Accédons à tout le subnet de mon VxLAN (192.168.67/24)
C’est encore à moi de bosser
Accédons au subnet du réseau labo depuis mon VxLAN
À vous de bosser
Ici la procédure est identique à la création de votre service perso, sauf que vous allez devoir configurer vos règles d’interception et d’hosts différement (hint: il y a un exemple dans ce support de cours )
Note sur les Postures Checks
Bien que nous n’ayons pas forcément eu le temps d’aborder en profondeur ce sujet, il faut savoir qu’OpenZiti permet, une fois authentifié et joint au réseau, de vous authentifier à nouveau via, notamment, OIDC (OpenID Connect).
On peut donc tout à fait imaginer qu’un utilisateur lançant l’applicatif OpenZiti n’ait tout d’abord que les droits nécessaires pour s’authentifier via OIDC, avant de pouvoir accéder aux ressources lui étant autorisées sur l’Overlay ou sur les réseaux Underlay (VLANs, etc).
== COMMIT WikiJS 27/9/2026 ==