j'ai migré récemment toutes mes machines vers nix et nixos — desktop, laptop, vps, téléphone (nix-on-droid). je voulais un vpn pour qu'elles puissent toutes se joindre entre elles sans tracas, et headscale semblait assez populaire pour valoir le coup.
comment ?
prérequis
1. récupère un domaine. j'utilise headscale.juke.fr ; configure un enregistrement Aqui pointe vers la machine qui hébergera headscale. tu peux aussi utiliser un service de dns dynamique, mais c'est hors scope ici — regarde ddclientsi c'est ton plan.
2. ouvre 80/tcp, 443/tcp et 3478/udpsur le firewall de l'hôte. la config nixos plus bas s'en occupe pour nous, mais sur un vps (le mien est sur l'offre gratuite oracle) il faudra peut-être les ouvrir en amont aussi.
crée un module headscale.nix que tu importes dans ta config nixos. à ajuster selon ton goût :
{
config,
...
}:
let
domain = "juke.fr"; # domain to use
derpPort = 3478; # default derp port
in
{
services = {
# enable headscale service and configure
headscale = {
enable = true;
address = "127.0.0.1";
port = 8085;
settings = {
dns_config = {
override_local_dns = true;
base_domain = domain;
magic_dns = true;
domains = [ "hs.${domain}" ];
nameservers = [
"1.1.1.1"
"9.9.9.9"
];
};
server_url = "https://headscale.${domain}";
metrics_listen_addr = "127.0.0.1:8095";
derp.server = {
enable = true;
region_id = 999;
stun_listen_addr = "0.0.0.0:${toString derpPort}";
};
};
};
# reverse proxy with ssl
nginx = {
enable = true;
virtualHosts."headscale.${domain}" = {
forceSSL = true;
enableACME = true;
locations = {
"/" = {
proxyPass = "http://localhost:${toString config.services.headscale.port}";
proxyWebsockets = true;
};
"/metrics" = {
proxyPass = "http://${config.services.headscale.settings.metrics_listen_addr}/metrics";
};
};
};
};
};
# configure ssl certificate options
security.acme = {
defaults.email = "acme@juke.fr";
acceptTerms = true;
};
# punch through firewall
networking.firewall.allowedUDPPorts = [ derpPort ];
networking.firewall.allowedTCPPorts = [ 80 443 ];
environment.systemPackages = [ config.services.headscale.package ];
}bascule ta config nixos et vérifie que tout fonctionne en allant sur headscale.juke.fr/metrics. il faut aussi créer un namespace (qui sert également d'utilisateur) pour la suite :
mets en place le service tailscale dans tailscale.nix et importe-le dans ta config commune pour que chaque machine l'ait :
{
lib,
...
}:
{
services.tailscale = {
enable = true;
useRoutingFeatures = lib.mkDefault "client";
};
networking.firewall = {
checkReversePath = "loose";
allowedUDPPorts = [ 41641 ]; # facilitate firewall punching
};
}rebuild nixos. on peut maintenant rejoindre l'instance headscale :
tu vas recevoir une url de login qui affiche une commande à exécuter sur la machine headscale (en remplaçant $USERpar le namespace créé plus haut). n'oublie pas le sudo.
pour finir
ta machine est maintenant accessible via $HOST.$NAMESPACE.$DOMAIN — par exemple nixos-home.net.juke.fr. voilà, c'est à peu près tout. merci pour la lecture.