Created: 2023-11-14 mar. 16:18
Aime bien regarder des nouvelles technologies et en discuter après
Recherche d’une solution plus légère qu’openvpn => wireguard
Gestion centralisée des clefs wireguard => tailscale
version opensource du serveur central tailscale => headscale
boringtun en rust
=> supportés sur tous les OS
Point à point entre A et B
=> installer wireguard-tools, fournit :
# sur chaque pair A et B wg genkey > /etc/wg/private_key wg pubkey < /etc/wg/private_key > /etc/wg/public_key
Il faut copier la clef publique de A sur B, celle de B sur A
peer A, public IP 198.51.100.3
ip link add dev wg0 type wireguard ip addr add 10.0.0.1/24 dev wg0 ip addr add fdc9:281f:04d7:9ee9::1/64 dev wg0 wg set wg0 private-key /etc/wg/private_key \ listen-port 12345 wg set wg0 peer PEER_B_PUBLIC_KEY \ allowed-ips 10.0.0.2/32,fdc9:281f:04d7:9ee9::2/128 ip link set up dev wg0
A écoute sur 195.51.100.3:12345
peer B has no static IP
ip link add dev wg0 type wireguard ip addr add 10.0.0.2/24 dev wg0 ip addr add fdc9:281f:04d7:9ee9::2/64 dev wg0 # no listen : will be dynamic wg set wg0 private-key /etc/wg/private_key wg set wg0 peer PEER_A_PUBLIC_KEY allowed-ips 10.0.0.2/32,fdc9:281f:04d7:9ee9::1/128 \ endpoint 198.51.100.3:12345 ip link set up dev wg0
B n’écoute initialement pas pour des connexions, il peut seulement en initier une.
wg show wg0
peer B
interface: wg0 public key: UhmH1vJBPmV2cG6w2gC5WNX7k35gutV+tdfe3rCaRRs= private key: (hidden) listening port: 38461 peer: TjR1IfrK6L7JUeoFJ+rDjQ+Oveq3XAFO/mH90I7ZKQc= endpoint: 195.51.100.3:12345 allowed ips: 10.100.0.1/32 latest handshake: 17 minutes, 48 seconds ago transfer: 348 B received, 3.66 KiB sent
peer A
interface: wg0 public key: TjR1IfrK6L7JUeoFJ+rDjQ+Oveq3XAFO/mH90I7ZKQc= private key: (hidden) listening port: 41641 peer: UhmH1vJBPmV2cG6w2gC5WNX7k35gutV+tdfe3rCaRRs= endpoint: 130.120.38.57:38461 allowed ips: 10.100.0.2/32 latest handshake: 19 minutes, 39 seconds ago transfer: 404 B received, 3.23 KiB sent
endpoint créé quand B s’est connecté à A !
wg-quick, permet de gérer des fichiers de conf
[Interface] Address = 10.200.100.8/24 DNS = 10.200.100.1 PrivateKey = oK56DE9Ue9zK76rAc8pBl6opph+1v36lm7cXXsQKrQM= [Peer] PublicKey = GtL7fZc/bLnqZldpVofMCD6hDjrK28SsdLxevJ+qtKU= PresharedKey = /UwcSPg38hW/D9Y3tcS1FOV0K1wuURMbS0sesJEP5ak= AllowedIPs = 0.0.0.0/0 Endpoint = demo.wireguard.com:51820
simple pour du point à point, performant, stable
vite compliqué :
(Source) Network Address Translation
Comment faire communiquer 2 machines qui n’ont pas d’IP publiques ?
chaque machine doit connaître son (IPext, PExt) pour la communiquer
STUN/ICE : on passe par un serveur tiers
Au pire : tunnel par un hôte tiers : TURN server
Tailscale et Nat Traversal : gère tous les cas
Besoin d’un serveur STUN, pourquoi ne pas faire :
copier les infos des pairs sur tous les nœuds
idée :
en résumé :
=> étude des solutions basées sur ce modèle
source : github:MarvsG/WireGuardMeshes
Pourquoi tailscale :
headscale : implémentation opensource du serveur de coordination tailscale
Principe global :
client tailcale –> connection https sur le serveur de configuration :
What firewall ports should I open to use tailscale ?
https://headscale.net/running-headscale-linux/
limite de base : un seul réseau mesh de supporté
frontal nginx
{ config, lib, pkgs, ... }: let proxy-hostname = "ts.math.univ-toulouse.fr"; proxy-uri = "https://${proxy-hostname}"; backend-uri = "http://130.120.38.54:8080"; in { services.nginx.virtualHosts."${proxy-hostname}" = { enableACME = true; forceSSL = true; locations."/" = { proxyPass = "${backend-uri}"; proxyWebsockets = true; # needed if you need to use WebSocket }; }; }
backend :
{ config, lib, pkgs, flakes, ... }: { environment.systemPackages = [ config.services.headscale.package ]; networking.firewall = { allowedTCPPorts = [ 8080 ]; }; services.headscale = { enable = true; address = "0.0.0.0"; port = 8080; settings = { ip_prefixes = [ "100.64.0.0/10" ]; server_url = "https://ts.math.univ-toulouse.fr"; dns_config = { override_local_dns = true; nameservers = [ "172.22.1.7" ]; base_domain = "math.univ-toulouse.fr"; domains = [ "servers.math.univ-toulouse.fr" "math.univ-toulouse.fr" ]; magic_dns = true; }; }; }
tailscale up --login-server https://ts.math.univ-toulouse.fr
tailscale status 100.64.0.1 alba gamba linux - 100.64.0.3 headscale.servers.math.univ-toulouse.fr servers linux active; direct 130.120.38.54:41641, tx 20056 rx 18392 100.64.0.2 in.servers.math.univ-toulouse.fr servers linux offline 100.64.0.5 oneplus-in2023 gamba android offline 100.64.0.4 tsrouter.servers.math.univ-toulouse.fr servers linux active; direct 130.120.38.57:41641, tx 517348 rx 2733380
clef permanente créé côté serveur headscale :
headscale --user bob preauthkeys create --reusable --tags tag:servers # expiration possible
On peut la trouver avec
headscale preauthkeys list --user bob
Sur une machine cliente à connecter :
tailscule up --login-server https://ts.math.univ-toulouse.fr --auth-key the-key
Pour ne pas avoir à installer tailscale sur toutes les machines existantes
sur le nœud de sortie :
# activate routing : echo 1 > /proc/sys/net/ipv4/ip_forward tailscale set --advertise-exit-node
sur headscale :
headscale routes list # le serveur est dispo pour fournir une route par défaut heasdcale routes enable -r 3
sur un autre nœud
tailscale set --exit-node headscale
# sur le nœud faisant le routage tailscale set --advertise-exit-node=false --advertise-routes \ "130.120.36.0/22,130.120.80.0/22,\ 130.120.224.0/22,\ 172.22.0.0/16" # sur le serveur headscale, activer les routes headscale routes list headscale routes enable -r X # à faire pour chaque route # sur le client : tailscale up --force-reauth \ --login-server=https://ts.math.univ-toulouse.fr \ --accept-routes
tailscale utilise une table de routage séparée :
ip route show table 52 100.64.0.2 dev tailscale0 100.64.0.3 dev tailscale0 100.100.100.100 dev tailscale0 130.120.36.0/22 dev tailscale0 130.120.80.0/22 dev tailscale0 130.120.224.0/22 dev tailscale0 172.22.0.0/16 dev tailscale0 # ip rule # to show priority # ip route show table all
Encore à tester :
Évolution : à attendre ou à coder soi-même
Gestion actuelle des clefs : génération sur le serveur headscale
tailscale : auth oidc => clef d’enregistrement pour un utilisateur
Cela commence à arriver côté headscale, mais pas encore au point sur la gestion des claims. => échec pour le moment avec l’openid plm
acls : un seul fichier texte pas dynamique