IPv6 mesh support yooooo

This commit is contained in:
Lyn 2025-01-14 18:56:49 +01:00
parent 91eda3a0ae
commit 9a0e250fc7
8 changed files with 151 additions and 202 deletions

View file

@ -58,24 +58,6 @@
"type": "github"
}
},
"flake-parts_2": {
"inputs": {
"nixpkgs-lib": "nixpkgs-lib"
},
"locked": {
"lastModified": 1730504689,
"narHash": "sha256-hgmguH29K2fvs9szpq2r3pz2/8cJd2LPS+b4tfNFCwE=",
"owner": "hercules-ci",
"repo": "flake-parts",
"rev": "506278e768c2a08bec68eb62932193e341f55c90",
"type": "github"
},
"original": {
"owner": "hercules-ci",
"repo": "flake-parts",
"type": "github"
}
},
"flake-utils": {
"inputs": {
"systems": "systems"
@ -96,14 +78,14 @@
},
"flake-utils_2": {
"inputs": {
"systems": "systems_3"
"systems": "systems_2"
},
"locked": {
"lastModified": 1726560853,
"narHash": "sha256-X6rJYSESBVr3hBoH0WbKE5KvhPU5bloyZ2L4K60/fPQ=",
"lastModified": 1731533236,
"narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=",
"owner": "numtide",
"repo": "flake-utils",
"rev": "c1dfcf08411b08f6b8615f7d8971a2bfa81d5e8a",
"rev": "11707dc2f618dd54ca8739b309ec4fc024de578b",
"type": "github"
},
"original": {
@ -159,27 +141,6 @@
"type": "github"
}
},
"lynpkgs": {
"inputs": {
"flake-parts": "flake-parts_2",
"nixpkgs": "nixpkgs_2",
"pkgs-by-name-for-flake-parts": "pkgs-by-name-for-flake-parts",
"systems": "systems_2"
},
"locked": {
"lastModified": 1732934040,
"narHash": "sha256-3QuAM3OP8SbZyz1bXKajHBRQGW8sMXZ3vJDLV6MQCRg=",
"owner": "lynatic1337",
"repo": "lynpkgs",
"rev": "1bad540c69e36520fcab64b99cf7a1907e2c0f73",
"type": "github"
},
"original": {
"owner": "lynatic1337",
"repo": "lynpkgs",
"type": "github"
}
},
"microvm": {
"inputs": {
"flake-utils": "flake-utils_2",
@ -189,11 +150,11 @@
"spectrum": "spectrum"
},
"locked": {
"lastModified": 1732633513,
"narHash": "sha256-6LmtOmeDpv9iHS8l0GNcppP11dKIJFMZLdFyxQ+qQBM=",
"lastModified": 1736637237,
"narHash": "sha256-kZELEfQDEbCljZUpmIw0G0tNNdcJlnLvc6bwKQ++Okw=",
"owner": "astro",
"repo": "microvm.nix",
"rev": "093ef734d3c37669860043a87dbf1c09fc6f5b38",
"rev": "6f7e4a7bfcdce1c703f9cb89ae9d634167b720b8",
"type": "github"
},
"original": {
@ -218,18 +179,6 @@
"type": "github"
}
},
"nixpkgs-lib": {
"locked": {
"lastModified": 1730504152,
"narHash": "sha256-lXvH/vOfb4aGYyvFmZK/HlsNsr/0CVWlwYvo2rxJk3s=",
"type": "tarball",
"url": "https://github.com/NixOS/nixpkgs/archive/cc2f28000298e1269cea6612cd06ec9979dd5d7f.tar.gz"
},
"original": {
"type": "tarball",
"url": "https://github.com/NixOS/nixpkgs/archive/cc2f28000298e1269cea6612cd06ec9979dd5d7f.tar.gz"
}
},
"nixpkgs-stable": {
"locked": {
"lastModified": 1710695816,
@ -248,11 +197,11 @@
},
"nixpkgs-unstable": {
"locked": {
"lastModified": 1732521221,
"narHash": "sha256-2ThgXBUXAE1oFsVATK1ZX9IjPcS4nKFOAjhPNKuiMn0=",
"lastModified": 1736798957,
"narHash": "sha256-qwpCtZhSsSNQtK4xYGzMiyEDhkNzOCz/Vfu4oL2ETsQ=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "4633a7c72337ea8fd23a4f2ba3972865e3ec685d",
"rev": "9abb87b552b7f55ac8916b6fc9e5cb486656a2f3",
"type": "github"
},
"original": {
@ -264,27 +213,11 @@
},
"nixpkgs_2": {
"locked": {
"lastModified": 1732521221,
"narHash": "sha256-2ThgXBUXAE1oFsVATK1ZX9IjPcS4nKFOAjhPNKuiMn0=",
"lastModified": 1735563628,
"narHash": "sha256-OnSAY7XDSx7CtDoqNh8jwVwh4xNL/2HaJxGjryLWzX8=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "4633a7c72337ea8fd23a4f2ba3972865e3ec685d",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "nixos-unstable",
"repo": "nixpkgs",
"type": "github"
}
},
"nixpkgs_3": {
"locked": {
"lastModified": 1732749044,
"narHash": "sha256-T38FQOg0BV5M8FN1712fovzNakSOENEYs+CSkg31C9Y=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "0c5b4ecbed5b155b705336aa96d878e55acd8685",
"rev": "b134951a4c9f3c995fd7be05f3243f8ecd65d798",
"type": "github"
},
"original": {
@ -294,7 +227,7 @@
"type": "github"
}
},
"nixpkgs_4": {
"nixpkgs_3": {
"locked": {
"lastModified": 1731763621,
"narHash": "sha256-ddcX4lQL0X05AYkrkV2LMFgGdRvgap7Ho8kgon3iWZk=",
@ -310,21 +243,6 @@
"type": "github"
}
},
"pkgs-by-name-for-flake-parts": {
"locked": {
"lastModified": 1727519927,
"narHash": "sha256-3SNX6BuaisoX9PKYI+fh3geZ3jBgKKkAtHcWuHRU0+o=",
"owner": "drupol",
"repo": "pkgs-by-name-for-flake-parts",
"rev": "91debb07d81ff25b8e3b48914b6abd6f11dc26e2",
"type": "github"
},
"original": {
"owner": "drupol",
"repo": "pkgs-by-name-for-flake-parts",
"type": "github"
}
},
"pre-commit-hooks-nix": {
"inputs": {
"flake-compat": [
@ -355,10 +273,10 @@
"root": {
"inputs": {
"lanzaboote": "lanzaboote",
"lynpkgs": "lynpkgs",
"microvm": "microvm",
"nixpkgs": "nixpkgs_3",
"nixpkgs": "nixpkgs_2",
"nixpkgs-unstable": "nixpkgs-unstable",
"rust-overlay": "rust-overlay_2",
"sops-nix": "sops-nix"
}
},
@ -387,16 +305,36 @@
"type": "github"
}
},
"sops-nix": {
"rust-overlay_2": {
"inputs": {
"nixpkgs": "nixpkgs_4"
"nixpkgs": [
"nixpkgs"
]
},
"locked": {
"lastModified": 1732575825,
"narHash": "sha256-xtt95+c7OUMoqZf4OvA/7AemiH3aVuWHQbErYQoPwFk=",
"lastModified": 1736735482,
"narHash": "sha256-QOA4jCDyyUM9Y2Vba+HSZ/5LdtCMGaTE/7NkkUzBr50=",
"owner": "oxalica",
"repo": "rust-overlay",
"rev": "cf960a1938ee91200fe0d2f7b2582fde2429d562",
"type": "github"
},
"original": {
"owner": "oxalica",
"repo": "rust-overlay",
"type": "github"
}
},
"sops-nix": {
"inputs": {
"nixpkgs": "nixpkgs_3"
},
"locked": {
"lastModified": 1736808430,
"narHash": "sha256-wlgdf/n7bJMLBheqt1jmPoxJFrUP6FByKQFXuM9YvIk=",
"owner": "Mic92",
"repo": "sops-nix",
"rev": "3433ea14fbd9e6671d0ff0dd45ed15ee4c156ffa",
"rev": "553c7cb22fed19fd60eb310423fdc93045c51ba8",
"type": "github"
},
"original": {
@ -408,11 +346,11 @@
"spectrum": {
"flake": false,
"locked": {
"lastModified": 1729945407,
"narHash": "sha256-iGNMamNOAnVTETnIVqDWd6fl74J8fLEi1ejdZiNjEtY=",
"lastModified": 1733308308,
"narHash": "sha256-+RcbMAjSxV1wW5UpS9abIG1lFZC8bITPiFIKNnE7RLs=",
"ref": "refs/heads/main",
"rev": "f1d94ee7029af18637dbd5fdf4749621533693fa",
"revCount": 764,
"rev": "80c9e9830d460c944c8f730065f18bb733bc7ee2",
"revCount": 792,
"type": "git",
"url": "https://spectrum-os.org/git/spectrum"
},
@ -450,21 +388,6 @@
"repo": "default",
"type": "github"
}
},
"systems_3": {
"locked": {
"lastModified": 1681028828,
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
"owner": "nix-systems",
"repo": "default",
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
"type": "github"
},
"original": {
"owner": "nix-systems",
"repo": "default",
"type": "github"
}
}
},
"root": "root",

View file

@ -7,7 +7,10 @@
nixpkgs.url = "github:NixOS/nixpkgs/nixos-24.05";
sops-nix.url = "github:Mic92/sops-nix";
nixpkgs-unstable.url = "github:NixOS/nixpkgs/nixos-unstable";
lynpkgs.url = "github:lynatic1337/lynpkgs";
rust-overlay = {
url = "github:oxalica/rust-overlay";
inputs.nixpkgs.follows = "nixpkgs";
};
};
outputs = {
self,
@ -16,7 +19,7 @@
sops-nix,
lanzaboote,
microvm,
lynpkgs,
rust-overlay,
} @ inputs: let
imports = {
imports = [
@ -26,8 +29,13 @@
lanzaboote.nixosModules.lanzaboote
inputs.microvm.nixosModules.host
./hosts/network.nix
./meta/wgautomesh
];
};
overlays = {
rust-overlay = inputs.rust-overlay.overlay;
default = import ./pkgs/overlay.nix;
};
passInputs = {
lib,
config,
@ -41,15 +49,10 @@
config.pkgsInstances = {
unstable = import inputs.nixpkgs-unstable {system = config.nixpkgs.system;};
};
config.nixpkgs.overlays = lib.attrValues overlays;
};
inherit (nixpkgs) lib;
pkgs = import nixpkgs {
overlays = [
lynpkgs.overlays.default
];
};
mkLocalMods = import ./meta/mkLocalMods.nix {inherit lib;};
mkLocalModsInput = mkLocalMods {
prefix = ["lyn"];

View file

@ -11,7 +11,6 @@
wg = {
enabled = true;
pubkey = "Fknzk7lltkPKJZlF3KXWKGQXXSj7CUD9ev0ZEZtpbjY=";
port = 51820;
};
IPv4 = {
public = "78.47.226.47";
@ -28,15 +27,12 @@
wg = {
enabled = true;
pubkey = "jdfbOnP0mFWFobtQunm0h6EtqOZiar9G9jngMU7b+Co=";
port = 51820;
};
IPv4 = {
public = "";
# we use 10.35.0.0/16 as a range for private subnets, specifically 10.35.0.0/24 for wireguard peers
internal = "10.35.0.2";
};
IPv6 = {
public = "";
# 1aacabcafe is the global ID and 1337 is the wireguard peer subnet ID, resulting in the ULA fd1a:acab:cafe:1337::/64
internal = "fd1a:acab:cafe:1337:6722:3657::";
};
@ -62,11 +58,16 @@ in {
default = null;
description = "Public key for WireGuard";
};
port = lib.mkOption {
port_v4 = lib.mkOption {
type = lib.types.int;
default = 51820;
description = "Port for WireGuard";
};
port_v6 = lib.mkOption {
type = lib.types.int;
default = 51821;
description = "Port for WireGuard";
};
};
};
description = "WireGuard configuration";
@ -75,8 +76,8 @@ in {
type = lib.types.submodule {
options = {
public = lib.mkOption {
type = lib.types.str;
default = "";
type = lib.types.nullOr lib.types.str;
default = null;
description = "Public IPv4 address";
};
internal = lib.mkOption {
@ -92,8 +93,8 @@ in {
type = lib.types.submodule {
options = {
public = lib.mkOption {
type = lib.types.str;
default = "";
type = lib.types.nullOr lib.types.str;
default = null;
description = "Public IPv6 address";
};
internal = lib.mkOption {

View file

@ -26,7 +26,7 @@ with config.lyn.lib; {
lyn.services.wgautomesh = {
enable = true;
#useIPv6 = false;
enable_upnp = true;
};
##1##3##3##7##

View file

@ -20,7 +20,6 @@
lyn.services.wgautomesh = {
enable = true;
#useIPv6 = false;
};
networking.useDHCP = false;

View file

@ -13,16 +13,19 @@ with lib; let
settingsFormat.generate "wgautomesh-config.toml"
(filterAttrs (k: v: v != null)
(mapAttrs
(k: v:
if k == "peers"
then map (e: filterAttrs (k: v: v != null) e) v
else v)
(
k: v:
if k == "peers" || k == "interfaces"
then map (e: filterAttrs (k: v: v != null) e) v
else v
)
cfg.settings));
runtimeConfigFile =
if cfg.enableGossipEncryption
then "/run/wgautomesh/wgautomesh.toml"
else configFile;
in {
disabledModules = ["services/networking/wgautomesh.nix"];
options.services.wgautomesh = {
enable = mkEnableOption "the wgautomesh daemon";
logLevel = mkOption {
@ -58,15 +61,6 @@ in {
type = types.submodule {
freeformType = settingsFormat.type;
options = {
interface = mkOption {
type = types.str;
description = ''
Wireguard interface to manage (it is NOT created by wgautomesh, you
should use another NixOS option to create it such as
`networking.wireguard.interfaces.wg0 = {...};`).
'';
example = "wg0";
};
gossip_port = mkOption {
type = types.port;
description = ''
@ -80,18 +74,24 @@ in {
default = true;
description = "Enable discovery of peers on the same LAN using UDP broadcast.";
};
ipv6 = mkOption {
type = types.bool;
default = true;
description = "Whether to use IPv6 or IPv4.";
};
upnp_forward_external_port = mkOption {
type = types.nullOr types.port;
default = null;
description = ''
Public port number to try to redirect to this machine's Wireguard
daemon using UPnP IGD.
'';
interfaces = mkOption {
type = types.listOf (types.submodule {
options = {
name = mkOption {
type = types.str;
};
upnp_forward_external_port = mkOption {
type = types.nullOr types.port;
default = null;
description = ''
Public port number to try to redirect to this machine's Wireguard
daemon using UPnP IGD. For IPv6 only interfaces the value is discarded, to enable please set it to any valid port number.
'';
};
};
});
default = [];
description = "wgautomesh interface settings.";
};
peers = mkOption {
type = types.listOf (types.submodule {
@ -100,6 +100,13 @@ in {
type = types.str;
description = "Wireguard public key of this peer.";
};
interface = mkOption {
type = types.str;
};
port = mkOption {
type = types.nullOr types.port;
example = 51820;
};
address = mkOption {
type = types.str;
description = ''
@ -115,7 +122,7 @@ in {
other address is known or none are working.
'';
default = null;
example = "wgnode.mydomain.example:51820";
example = "wgnode.mydomain.example";
};
};
});

View file

@ -6,11 +6,6 @@
...
}: let
buildInputs = [pkgs.wgautomesh];
options.services.wgautomesh.settings.ipv6 = lib.mkOption {
type = lib.types.bool;
default = true;
description = "Whether to use IPv6 or IPv4.";
};
prefix = "lyn";
@ -22,46 +17,40 @@
buildPeerlist = version: hosts: let
#filter out hosts that have wg.enabled set to false
wgEnabledHosts = lib.filterAttrs (_: host: host.wg.enabled or false) hosts;
#filter out hosts that don't support IP{$version}
filteredHosts = lib.filterAttrs (_: host: host.${version} != null) wgEnabledHosts;
in
lib.mapAttrsToList (name: host: {
interface =
if version == "IPv6"
then "wg1"
else "wg0";
pubkey = host.wg.pubkey;
#if there is no public IP, make endpoint null so wgautomesh knows it unknown. Else format it to a SocketAddr
endpoint =
if host.${version}.public == ""
then null
else "${
if version == "IPv6"
then "[${host.${version}.public}]"
else host.${version}.public
}:${toString host.wg.port}";
endpoint = host.${version}.public;
port =
if version == "IPv6"
then host.wg.port_v6
else host.wg.port_v4;
address = host.${version}.internal;
})
filteredHosts;
wgEnabledHosts;
# helper vars to prettify
meshnetwork = config.${prefix}.network;
currentHost = meshnetwork.hosts.${config.networking.hostName};
wireguardPort = currentHost.wg.port;
in {
opt = {
useIPv6 = lib.mkOption {
type = lib.types.bool;
description = "Whether to use IPv6. Defaults to true";
default = true;
};
enable_upnp = lib.mkOption {
type = lib.types.bool;
description = "Whether to allow the wireguard port in the gateway using UPnP IGD. Necessary on some firewalls, might spam unnecessary debug messages on environments without IGD gateways.";
default = false;
};
};
config = {
config = rec {
networking.firewall = {
allowedUDPPorts =
[
wireguardPort
currentHost.wg.port_v4
currentHost.wg.port_v6
]
# UPnP broadcast responses
++ (
@ -72,11 +61,14 @@ in {
};
networking.wireguard.interfaces.wg0 = {
ips =
if cfg.useIPv6
then ["${currentHost.IPv6.internal}/64"]
else ["${currentHost.IPv4.internal}/24"];
listenPort = wireguardPort;
ips = ["${currentHost.IPv4.internal}/24"];
listenPort = currentHost.wg.port_v4;
privateKeyFile = "/var/lib/wireguard-keys/private";
mtu = 1280;
};
networking.wireguard.interfaces.wg1 = {
ips = ["${currentHost.IPv6.internal}/64"];
listenPort = currentHost.wg.port_v6;
privateKeyFile = "/var/lib/wireguard-keys/private";
mtu = 1280;
};
@ -84,12 +76,20 @@ in {
services.wgautomesh = {
enable = true;
settings = {
interface = "wg0";
peers =
if cfg.useIPv6
then buildPeerlist "IPv6" meshnetwork.hosts
else buildPeerlist "IPv4" meshnetwork.hosts;
upnp_forward_external_port = wireguardPort;
interfaces =
if cfg.enable_upnp
then [
{
name = "wg0";
upnp_forward_external_port = config.networking.wireguard.interfaces.wg0.listenPort;
}
{
name = "wg1";
upnp_forward_external_port = config.networking.wireguard.interfaces.wg1.listenPort;
}
]
else null;
peers = buildPeerlist "IPv6" meshnetwork.hosts ++ buildPeerlist "IPv4" meshnetwork.hosts;
};
gossipSecretFile = gossip_secret_path;

16
pkgs/overlay.nix Normal file
View file

@ -0,0 +1,16 @@
final: prev: {
wgautomesh = prev.wgautomesh.overrideAttrs (old: rec {
src = prev.fetchFromGitHub {
owner = "lynatic1337";
repo = "wgautomesh";
rev = "53b7a6b6edc144fc0d9679ed5c756530f9883374";
hash = "sha256-3pUQbNcx/EMhsiqZ74l8Y99VrdlsLgOgcYuHb4hKOiI=";
};
buildInputs = [(rust-bin.nightly.latest.default)];
cargoDeps = final.rustPlatform.fetchCargoTarball {
inherit src;
# TODO
hash = "sha256-YUlS7G26c3X8nJ2eDK2DTqR+QjcrF/2ZpZWPGecwyPo=";
};
});
}