nixos/l2mesh: Initial VXLAN mesh support
This commit is contained in:
@@ -46,7 +46,7 @@ let
|
||||
];
|
||||
|
||||
_module.args = {
|
||||
inherit (cfg) secretsPath;
|
||||
inherit (cfg) secretsPath vpns;
|
||||
inherit (config') assignments;
|
||||
pkgs' = allPkgs;
|
||||
};
|
||||
@@ -116,6 +116,24 @@ let
|
||||
};
|
||||
};
|
||||
|
||||
l2PeerOpts = with lib.types; {
|
||||
options = {
|
||||
addr = mkOpt' str null "Address.";
|
||||
};
|
||||
};
|
||||
l2MeshOpts = with lib.types; { name, ... }: {
|
||||
options = {
|
||||
interface = mkOpt' str name "Name of VXLAN interface.";
|
||||
firewall = mkBoolOpt' true "Whether to generate firewall rules.";
|
||||
vni = mkOpt' ints.unsigned 1 "VXLAN VNI.";
|
||||
peers = mkOpt' (attrsOf (submodule l2PeerOpts)) { } "Peers.";
|
||||
security = {
|
||||
enable = mkBoolOpt' true "Whether to enable IPsec authentication.";
|
||||
encrypt = mkBoolOpt' false "Whether to enable IPsec encryption.";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
systemOpts = with lib.types; { name, ... }@args:
|
||||
let
|
||||
config' = args.config;
|
||||
@@ -161,6 +179,9 @@ in
|
||||
secretsPath = mkOpt' path null "Path to encrypted secret files.";
|
||||
modules = mkOpt' (attrsOf commonOpts.moduleType) { } "NixOS modules to be exported by nixfiles.";
|
||||
systems = mkOpt' (attrsOf (submodule systemOpts)) { } "NixOS systems to be exported by nixfiles.";
|
||||
vpns = {
|
||||
l2 = mkOpt' (attrsOf (submodule l2MeshOpts)) { } "Layer 2 meshes.";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
|
@@ -15,5 +15,6 @@
|
||||
pdns = ./pdns.nix;
|
||||
nginx-sso = ./nginx-sso.nix;
|
||||
gui = ./gui.nix;
|
||||
l2mesh = ./l2mesh.nix;
|
||||
};
|
||||
}
|
||||
|
78
nixos/modules/l2mesh.nix
Normal file
78
nixos/modules/l2mesh.nix
Normal file
@@ -0,0 +1,78 @@
|
||||
{ lib, pkgs, config, vpns, ... }:
|
||||
let
|
||||
inherit (lib) optionalString mapAttrsToList concatStringsSep filterAttrs mkIf mkMerge;
|
||||
inherit (lib.my) isIPv6;
|
||||
|
||||
vxlanPort = 4789;
|
||||
|
||||
selfName = config.system.name;
|
||||
memberMeshes = filterAttrs (_: c: c.peers ? "${selfName}") vpns.l2;
|
||||
|
||||
info = mesh: {
|
||||
ownAddr = mesh.peers."${selfName}".addr;
|
||||
otherPeers = filterAttrs (n: _: n != selfName) mesh.peers;
|
||||
};
|
||||
|
||||
mkNetConfig = name: mesh: with info mesh; {
|
||||
netdevs."30-l2mesh-${name}" = {
|
||||
netdevConfig = {
|
||||
Name = mesh.interface;
|
||||
Kind = "vxlan";
|
||||
};
|
||||
vxlanConfig = {
|
||||
VNI = mesh.vni;
|
||||
Local = ownAddr;
|
||||
MacLearning = true;
|
||||
DestinationPort = vxlanPort;
|
||||
Independent = true;
|
||||
};
|
||||
};
|
||||
networks."90-l2mesh-${name}" = {
|
||||
matchConfig.Name = mesh.interface;
|
||||
extraConfig = concatStringsSep "\n" (mapAttrsToList (n: peer: ''
|
||||
[BridgeFDB]
|
||||
MACAddress=00:00:00:00:00:00
|
||||
Destination=${peer.addr}
|
||||
'') otherPeers);
|
||||
};
|
||||
};
|
||||
|
||||
mkLibreswanConfig = name: mesh: with info mesh; {
|
||||
enable = true;
|
||||
# TODO: finish this...
|
||||
connections."l2mesh-${name}" = ''
|
||||
keyexchange=ike
|
||||
type=transport
|
||||
left=${ownAddr}
|
||||
|
||||
auto=start
|
||||
phase2=esp
|
||||
ikev2=yes
|
||||
'';
|
||||
};
|
||||
|
||||
mkFirewallConfig = name: mesh: with info mesh;
|
||||
let
|
||||
netProto = if (isIPv6 ownAddr) then "ip6" else "ip";
|
||||
in
|
||||
''
|
||||
table inet filter {
|
||||
chain l2mesh-${name} {
|
||||
${optionalString mesh.security.enable "meta l4proto esp accept"}
|
||||
udp dport ${toString vxlanPort} @th,96,24 ${toString mesh.vni} accept
|
||||
return
|
||||
}
|
||||
chain input {
|
||||
${netProto} daddr ${ownAddr} ${netProto} saddr { ${concatStringsSep ", " (mapAttrsToList (_: p: p.addr) otherPeers)} } jump l2mesh-${name}
|
||||
}
|
||||
}
|
||||
'';
|
||||
in
|
||||
{
|
||||
config = {
|
||||
systemd.network = mkMerge (mapAttrsToList mkNetConfig memberMeshes);
|
||||
# TODO: finish this...
|
||||
#services.libreswan = mkMerge (mapAttrsToList mkLibreswanConfig (filterAttrs (_: c: c.security.enable) memberMeshes));
|
||||
my.firewall.extraRules = concatStringsSep "\n" (mapAttrsToList mkFirewallConfig (filterAttrs (_: c: c.firewall) memberMeshes));
|
||||
};
|
||||
}
|
Reference in New Issue
Block a user