services/enthalpy: complete migration to networking.netns
This commit is contained in:
parent
e173247742
commit
aff0796cd3
|
@ -1,12 +1,15 @@
|
||||||
{ profiles, lib, ... }:
|
{
|
||||||
|
config,
|
||||||
|
profiles,
|
||||||
|
lib,
|
||||||
|
...
|
||||||
|
}:
|
||||||
{
|
{
|
||||||
imports = with profiles; [
|
imports = with profiles; [
|
||||||
services.enthalpy
|
services.enthalpy
|
||||||
];
|
];
|
||||||
|
|
||||||
services.enthalpy = {
|
services.enthalpy = {
|
||||||
users.rebmit = { };
|
|
||||||
services.nix-daemon = { };
|
|
||||||
ipsec.interfaces = [ "enp14s0" ];
|
ipsec.interfaces = [ "enp14s0" ];
|
||||||
clat = {
|
clat = {
|
||||||
enable = true;
|
enable = true;
|
||||||
|
@ -15,6 +18,19 @@
|
||||||
gost.enable = true;
|
gost.enable = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
systemd.services.nix-daemon = {
|
||||||
|
serviceConfig = config.networking.netns.enthalpy.serviceConfig;
|
||||||
|
after = [ "netns-enthalpy.service" ];
|
||||||
|
requires = [ "netns-enthalpy.service" ];
|
||||||
|
};
|
||||||
|
|
||||||
|
systemd.services."user@${toString config.users.users.rebmit.uid}" = {
|
||||||
|
overrideStrategy = "asDropin";
|
||||||
|
serviceConfig = config.networking.netns.enthalpy.serviceConfig;
|
||||||
|
after = [ "netns-enthalpy.service" ];
|
||||||
|
requires = [ "netns-enthalpy.service" ];
|
||||||
|
};
|
||||||
|
|
||||||
systemd.network = {
|
systemd.network = {
|
||||||
enable = true;
|
enable = true;
|
||||||
wait-online.anyInterface = true;
|
wait-online.anyInterface = true;
|
||||||
|
|
|
@ -1,12 +1,15 @@
|
||||||
{ profiles, lib, ... }:
|
{
|
||||||
|
config,
|
||||||
|
profiles,
|
||||||
|
lib,
|
||||||
|
...
|
||||||
|
}:
|
||||||
{
|
{
|
||||||
imports = with profiles; [
|
imports = with profiles; [
|
||||||
services.enthalpy
|
services.enthalpy
|
||||||
];
|
];
|
||||||
|
|
||||||
services.enthalpy = {
|
services.enthalpy = {
|
||||||
users.rebmit = { };
|
|
||||||
services.nix-daemon = { };
|
|
||||||
ipsec = {
|
ipsec = {
|
||||||
interfaces = [ "wlan0" ];
|
interfaces = [ "wlan0" ];
|
||||||
whitelist = [ "rebmit's edge network" ];
|
whitelist = [ "rebmit's edge network" ];
|
||||||
|
@ -18,6 +21,19 @@
|
||||||
gost.enable = true;
|
gost.enable = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
systemd.services.nix-daemon = {
|
||||||
|
serviceConfig = config.networking.netns.enthalpy.serviceConfig;
|
||||||
|
after = [ "netns-enthalpy.service" ];
|
||||||
|
requires = [ "netns-enthalpy.service" ];
|
||||||
|
};
|
||||||
|
|
||||||
|
systemd.services."user@${toString config.users.users.rebmit.uid}" = {
|
||||||
|
overrideStrategy = "asDropin";
|
||||||
|
serviceConfig = config.networking.netns.enthalpy.serviceConfig;
|
||||||
|
after = [ "netns-enthalpy.service" ];
|
||||||
|
requires = [ "netns-enthalpy.service" ];
|
||||||
|
};
|
||||||
|
|
||||||
systemd.network = {
|
systemd.network = {
|
||||||
enable = true;
|
enable = true;
|
||||||
wait-online.anyInterface = true;
|
wait-online.anyInterface = true;
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
{
|
{
|
||||||
profiles,
|
profiles,
|
||||||
data,
|
data,
|
||||||
lib,
|
|
||||||
...
|
...
|
||||||
}:
|
}:
|
||||||
{
|
{
|
||||||
|
@ -57,12 +56,6 @@
|
||||||
dhcpV6Config.RouteMetric = 1024;
|
dhcpV6Config.RouteMetric = 1024;
|
||||||
ipv6AcceptRAConfig.RouteMetric = 1024;
|
ipv6AcceptRAConfig.RouteMetric = 1024;
|
||||||
};
|
};
|
||||||
"50-enthalpy" = {
|
|
||||||
routes = lib.singleton {
|
|
||||||
Destination = data.enthalpy_network_prefix;
|
|
||||||
Gateway = "fe80::ff:fe00:0";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,7 +26,7 @@ in
|
||||||
};
|
};
|
||||||
mntnsPath = mkOption {
|
mntnsPath = mkOption {
|
||||||
type = types.str;
|
type = types.str;
|
||||||
default = if name == "default" then "/proc/1/ns/mnt" else "/run/netns-${name}/mntns/${name}";
|
default = if name == "default" then "/proc/1/ns/mnt" else "/run/${name}/mntns/${name}";
|
||||||
readOnly = true;
|
readOnly = true;
|
||||||
description = ''
|
description = ''
|
||||||
Path to the auxiliary mount namespace.
|
Path to the auxiliary mount namespace.
|
||||||
|
@ -71,7 +71,7 @@ in
|
||||||
BindReadOnlyPaths = optionals config.enableDNSIsolation [
|
BindReadOnlyPaths = optionals config.enableDNSIsolation [
|
||||||
"/etc/netns/${name}/resolv.conf:/etc/resolv.conf:norbind"
|
"/etc/netns/${name}/resolv.conf:/etc/resolv.conf:norbind"
|
||||||
"/etc/netns/${name}/nsswitch.conf:/etc/nsswitch.conf:norbind"
|
"/etc/netns/${name}/nsswitch.conf:/etc/nsswitch.conf:norbind"
|
||||||
"/run/netns-${name}/nscd:/run/nscd:norbind"
|
"/run/${name}/nscd:/run/nscd:norbind"
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
readOnly = true;
|
readOnly = true;
|
||||||
|
@ -143,13 +143,13 @@ in
|
||||||
${optionalString enableDNSIsolation ''
|
${optionalString enableDNSIsolation ''
|
||||||
nsenter --mount=${mntnsPath} mount --bind --read-only /etc/netns/${name}/resolv.conf /etc/resolv.conf
|
nsenter --mount=${mntnsPath} mount --bind --read-only /etc/netns/${name}/resolv.conf /etc/resolv.conf
|
||||||
nsenter --mount=${mntnsPath} mount --bind --read-only /etc/netns/${name}/nsswitch.conf /etc/nsswitch.conf
|
nsenter --mount=${mntnsPath} mount --bind --read-only /etc/netns/${name}/nsswitch.conf /etc/nsswitch.conf
|
||||||
nsenter --mount=${mntnsPath} mount --bind --read-only /run/netns-${name}/nscd /run/nscd
|
nsenter --mount=${mntnsPath} mount --bind --read-only /run/${name}/nscd /run/nscd
|
||||||
''}
|
''}
|
||||||
'';
|
'';
|
||||||
serviceConfig = {
|
serviceConfig = {
|
||||||
Type = "oneshot";
|
Type = "oneshot";
|
||||||
RemainAfterExit = true;
|
RemainAfterExit = true;
|
||||||
RuntimeDirectory = "netns-${name}/mntns";
|
RuntimeDirectory = "${name}/mntns";
|
||||||
};
|
};
|
||||||
after =
|
after =
|
||||||
[
|
[
|
||||||
|
|
|
@ -1,127 +0,0 @@
|
||||||
{
|
|
||||||
config,
|
|
||||||
lib,
|
|
||||||
pkgs,
|
|
||||||
...
|
|
||||||
}:
|
|
||||||
with lib;
|
|
||||||
let
|
|
||||||
allNetns = config.networking.netns;
|
|
||||||
allExtraVeths = flatten (mapAttrsToList (_name: cfg: cfg.extraVeths) allNetns);
|
|
||||||
in
|
|
||||||
{
|
|
||||||
options.networking.netns = mkOption {
|
|
||||||
type = types.attrsOf (
|
|
||||||
types.submodule (
|
|
||||||
{ name, ... }:
|
|
||||||
{
|
|
||||||
options.extraVeths = mkOption {
|
|
||||||
type = types.listOf (
|
|
||||||
types.submodule (
|
|
||||||
{ config, ... }:
|
|
||||||
{
|
|
||||||
options = {
|
|
||||||
sourceNetns = mkOption {
|
|
||||||
type = types.str;
|
|
||||||
default = name;
|
|
||||||
readOnly = true;
|
|
||||||
description = ''
|
|
||||||
The current network namespace.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
targetNetns = mkOption {
|
|
||||||
type = types.str;
|
|
||||||
description = ''
|
|
||||||
The network namespace to connect to.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
sourceInterface = mkOption {
|
|
||||||
type = types.str;
|
|
||||||
default = if config.targetNetns == "default" then "host" else config.targetNetns;
|
|
||||||
description = ''
|
|
||||||
The interface name in the current network namespace;
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
targetInterface = mkOption {
|
|
||||||
type = types.str;
|
|
||||||
default = if config.sourceNetns == "default" then "host" else config.sourceNetns;
|
|
||||||
description = ''
|
|
||||||
The interface name in the other network namespace;
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
||||||
)
|
|
||||||
);
|
|
||||||
default = [ ];
|
|
||||||
description = ''
|
|
||||||
Extra veth-pairs to be created for enabling link-scope connectivity
|
|
||||||
between inter-network namespaces.
|
|
||||||
Note that a veth-pair only needs to be defined on one end.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
}
|
|
||||||
)
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
config = {
|
|
||||||
systemd.services = listToAttrs (
|
|
||||||
map (
|
|
||||||
ev:
|
|
||||||
let
|
|
||||||
inherit (ev)
|
|
||||||
sourceNetns
|
|
||||||
targetNetns
|
|
||||||
sourceInterface
|
|
||||||
targetInterface
|
|
||||||
;
|
|
||||||
sourceNetnsPath = config.networking.netns.${sourceNetns}.netnsPath;
|
|
||||||
targetNetnsPath = config.networking.netns.${targetNetns}.netnsPath;
|
|
||||||
serviceDeps = map (ns: "netns-${ns}.service") (
|
|
||||||
filter (ns: ns != "default") [
|
|
||||||
sourceNetns
|
|
||||||
targetNetns
|
|
||||||
]
|
|
||||||
);
|
|
||||||
mkSetup =
|
|
||||||
netns: _netnsPath: interface:
|
|
||||||
if netns == "default" then
|
|
||||||
"ip link set ${interface} up"
|
|
||||||
else
|
|
||||||
"ip -n ${netns} link set ${interface} up";
|
|
||||||
mkDrop =
|
|
||||||
netns: _netnsPath: interface:
|
|
||||||
if netns == "default" then "ip link del ${interface}" else "ip -n ${netns} link del ${interface}";
|
|
||||||
in
|
|
||||||
nameValuePair "netns-extra-veth-1-${sourceNetns}-${targetNetns}" {
|
|
||||||
path = with pkgs; [
|
|
||||||
coreutils
|
|
||||||
iproute2
|
|
||||||
procps
|
|
||||||
];
|
|
||||||
script = ''
|
|
||||||
ip link add ${sourceInterface} mtu 1400 address 02:00:00:00:00:01 netns ${sourceNetnsPath} type veth \
|
|
||||||
peer ${targetInterface} mtu 1400 address 02:00:00:00:00:00 netns ${targetNetnsPath}
|
|
||||||
${mkSetup sourceNetns sourceNetnsPath sourceInterface}
|
|
||||||
${mkSetup targetNetns targetNetnsPath targetInterface}
|
|
||||||
'';
|
|
||||||
preStop = ''
|
|
||||||
${mkDrop sourceNetns sourceNetnsPath sourceInterface}
|
|
||||||
'';
|
|
||||||
serviceConfig = {
|
|
||||||
Type = "oneshot";
|
|
||||||
RemainAfterExit = true;
|
|
||||||
};
|
|
||||||
after = [
|
|
||||||
"network.target"
|
|
||||||
] ++ serviceDeps;
|
|
||||||
partOf = serviceDeps;
|
|
||||||
wantedBy = [
|
|
||||||
"multi-user.target"
|
|
||||||
] ++ serviceDeps;
|
|
||||||
}
|
|
||||||
) allExtraVeths
|
|
||||||
);
|
|
||||||
};
|
|
||||||
}
|
|
|
@ -43,12 +43,12 @@ in
|
||||||
"/etc/netns/${name}/resolv.conf:/etc/resolv.conf:norbind"
|
"/etc/netns/${name}/resolv.conf:/etc/resolv.conf:norbind"
|
||||||
"/etc/netns/${name}/nsswitch.conf:/etc/nsswitch.conf:norbind"
|
"/etc/netns/${name}/nsswitch.conf:/etc/nsswitch.conf:norbind"
|
||||||
];
|
];
|
||||||
BindPaths = [ "/run/netns-${name}/nscd:/run/nscd:norbind" ];
|
BindPaths = [ "/run/${name}/nscd:/run/nscd:norbind" ];
|
||||||
Type = "notify";
|
Type = "notify";
|
||||||
Restart = "on-failure";
|
Restart = "on-failure";
|
||||||
RestartSec = 5;
|
RestartSec = 5;
|
||||||
User = "${name}-nscd";
|
User = "${name}-nscd";
|
||||||
RuntimeDirectory = "netns-${name}/nscd";
|
RuntimeDirectory = "${name}/nscd";
|
||||||
RuntimeDirectoryPreserve = true;
|
RuntimeDirectoryPreserve = true;
|
||||||
ExecStart = "${pkgs.nsncd}/bin/nsncd";
|
ExecStart = "${pkgs.nsncd}/bin/nsncd";
|
||||||
};
|
};
|
||||||
|
|
|
@ -84,7 +84,7 @@ in
|
||||||
]
|
]
|
||||||
);
|
);
|
||||||
in
|
in
|
||||||
nameValuePair "netns-${name}-port-forward-${toString index}" {
|
nameValuePair "netns-${name}-port-forward-${toString index}-${netns}-${protocol}" {
|
||||||
serviceConfig =
|
serviceConfig =
|
||||||
mylib.misc.serviceHardened
|
mylib.misc.serviceHardened
|
||||||
// cfg.serviceConfig
|
// cfg.serviceConfig
|
||||||
|
|
|
@ -16,7 +16,7 @@ in
|
||||||
enable = mkEnableOption "bird for site-scope connectivity";
|
enable = mkEnableOption "bird for site-scope connectivity";
|
||||||
socket = mkOption {
|
socket = mkOption {
|
||||||
type = types.str;
|
type = types.str;
|
||||||
default = "/run/netns-${cfg.netns}/bird/bird.ctl";
|
default = "/run/enthalpy/bird/bird.ctl";
|
||||||
description = ''
|
description = ''
|
||||||
Path to the bird control socket.
|
Path to the bird control socket.
|
||||||
'';
|
'';
|
||||||
|
@ -43,7 +43,7 @@ in
|
||||||
};
|
};
|
||||||
|
|
||||||
config = mkIf (cfg.enable && cfg.bird.enable) {
|
config = mkIf (cfg.enable && cfg.bird.enable) {
|
||||||
environment.etc."netns/${cfg.netns}/bird.conf".source = pkgs.writeTextFile {
|
environment.etc."enthalpy/bird/bird.conf".source = pkgs.writeTextFile {
|
||||||
name = "bird";
|
name = "bird";
|
||||||
text = cfg.bird.config;
|
text = cfg.bird.config;
|
||||||
checkPhase = optionalString cfg.bird.checkConfig ''
|
checkPhase = optionalString cfg.bird.checkConfig ''
|
||||||
|
@ -55,14 +55,14 @@ in
|
||||||
systemd.services.enthalpy-bird = {
|
systemd.services.enthalpy-bird = {
|
||||||
serviceConfig =
|
serviceConfig =
|
||||||
mylib.misc.serviceHardened
|
mylib.misc.serviceHardened
|
||||||
// config.networking.netns.${cfg.netns}.serviceConfig
|
// config.networking.netns.enthalpy.serviceConfig
|
||||||
// {
|
// {
|
||||||
Type = "forking";
|
Type = "forking";
|
||||||
Restart = "on-failure";
|
Restart = "on-failure";
|
||||||
RestartSec = 5;
|
RestartSec = 5;
|
||||||
DynamicUser = true;
|
DynamicUser = true;
|
||||||
RuntimeDirectory = "netns-${cfg.netns}/bird";
|
RuntimeDirectory = "enthalpy/bird";
|
||||||
ExecStart = "${pkgs.bird}/bin/bird -s ${cfg.bird.socket} -c /etc/netns/${cfg.netns}/bird.conf";
|
ExecStart = "${pkgs.bird}/bin/bird -s ${cfg.bird.socket} -c /etc/enthalpy/bird/bird.conf";
|
||||||
ExecReload = "${pkgs.bird}/bin/birdc -s ${cfg.bird.socket} configure";
|
ExecReload = "${pkgs.bird}/bin/birdc -s ${cfg.bird.socket} configure";
|
||||||
ExecStop = "${pkgs.bird}/bin/birdc -s ${cfg.bird.socket} down";
|
ExecStop = "${pkgs.bird}/bin/birdc -s ${cfg.bird.socket} down";
|
||||||
CapabilityBoundingSet = [
|
CapabilityBoundingSet = [
|
||||||
|
@ -82,13 +82,13 @@ in
|
||||||
"AF_NETLINK"
|
"AF_NETLINK"
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
after = [ "netns-${cfg.netns}.service" ];
|
after = [ "netns-enthalpy.service" ];
|
||||||
partOf = [ "netns-${cfg.netns}.service" ];
|
partOf = [ "netns-enthalpy.service" ];
|
||||||
wantedBy = [
|
wantedBy = [
|
||||||
"multi-user.target"
|
"multi-user.target"
|
||||||
"netns-${cfg.netns}.service"
|
"netns-enthalpy.service"
|
||||||
];
|
];
|
||||||
reloadTriggers = [ config.environment.etc."netns/${cfg.netns}/bird.conf".source ];
|
reloadTriggers = [ config.environment.etc."enthalpy/bird/bird.conf".source ];
|
||||||
};
|
};
|
||||||
|
|
||||||
services.enthalpy.bird.config = mkBefore ''
|
services.enthalpy.bird.config = mkBefore ''
|
||||||
|
|
|
@ -11,7 +11,7 @@ with lib;
|
||||||
let
|
let
|
||||||
inherit (mylib.network) cidr;
|
inherit (mylib.network) cidr;
|
||||||
cfg = config.services.enthalpy;
|
cfg = config.services.enthalpy;
|
||||||
interface = config.networking.netns.${cfg.netns}.interface;
|
interface = config.networking.netns.enthalpy.interface;
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
options.services.enthalpy.clat = {
|
options.services.enthalpy.clat = {
|
||||||
|
@ -61,7 +61,7 @@ in
|
||||||
'';
|
'';
|
||||||
serviceConfig =
|
serviceConfig =
|
||||||
mylib.misc.serviceHardened
|
mylib.misc.serviceHardened
|
||||||
// config.networking.netns.${cfg.netns}.serviceConfig
|
// config.networking.netns.enthalpy.serviceConfig
|
||||||
// {
|
// {
|
||||||
Type = "forking";
|
Type = "forking";
|
||||||
Restart = "on-failure";
|
Restart = "on-failure";
|
||||||
|
@ -77,11 +77,11 @@ in
|
||||||
];
|
];
|
||||||
PrivateDevices = false;
|
PrivateDevices = false;
|
||||||
};
|
};
|
||||||
after = [ "netns-${cfg.netns}.service" ];
|
after = [ "netns-enthalpy.service" ];
|
||||||
partOf = [ "netns-${cfg.netns}.service" ];
|
partOf = [ "netns-enthalpy.service" ];
|
||||||
wantedBy = [
|
wantedBy = [
|
||||||
"multi-user.target"
|
"multi-user.target"
|
||||||
"netns-${cfg.netns}.service"
|
"netns-enthalpy.service"
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
|
@ -27,13 +27,6 @@ in
|
||||||
Address to be added into the enthalpy network as source address.
|
Address to be added into the enthalpy network as source address.
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
netns = mkOption {
|
|
||||||
type = types.str;
|
|
||||||
default = "enthalpy";
|
|
||||||
description = ''
|
|
||||||
Name of the network namespace for enthalpy interfaces.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
network = mkOption {
|
network = mkOption {
|
||||||
type = types.str;
|
type = types.str;
|
||||||
description = ''
|
description = ''
|
||||||
|
@ -43,8 +36,8 @@ in
|
||||||
};
|
};
|
||||||
|
|
||||||
config = mkIf cfg.enable {
|
config = mkIf cfg.enable {
|
||||||
networking.netns."${cfg.netns}" = {
|
networking.netns.enthalpy = {
|
||||||
interface = cfg.netns;
|
interface = "enthalpy";
|
||||||
address = singleton "${cfg.address}/128";
|
address = singleton "${cfg.address}/128";
|
||||||
enableIPv4Forwarding = false;
|
enableIPv4Forwarding = false;
|
||||||
enableIPv6Forwarding = true;
|
enableIPv6Forwarding = true;
|
||||||
|
|
|
@ -10,10 +10,7 @@ with lib;
|
||||||
let
|
let
|
||||||
cfg = config.services.enthalpy;
|
cfg = config.services.enthalpy;
|
||||||
birdPrefix = filter (p: p.type == "bird") cfg.exit.prefix;
|
birdPrefix = filter (p: p.type == "bird") cfg.exit.prefix;
|
||||||
staticPrefix = subtractLists birdPrefix cfg.exit.prefix;
|
staticPrefix = filter (p: p.type == "static") cfg.exit.prefix;
|
||||||
staticRoutes = map (
|
|
||||||
p: "${p.destination} from ${p.source} via fe80::ff:fe00:1 dev enthalpy"
|
|
||||||
) staticPrefix;
|
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
options.services.enthalpy.exit = {
|
options.services.enthalpy.exit = {
|
||||||
|
@ -45,29 +42,53 @@ in
|
||||||
};
|
};
|
||||||
|
|
||||||
config = mkIf (cfg.enable && cfg.exit.enable) {
|
config = mkIf (cfg.enable && cfg.exit.enable) {
|
||||||
|
systemd.network.networks."50-enthalpy" = {
|
||||||
|
matchConfig.Name = "enthalpy";
|
||||||
|
routes = singleton {
|
||||||
|
Destination = cfg.network;
|
||||||
|
Gateway = "fe80::ff:fe00:2";
|
||||||
|
};
|
||||||
|
linkConfig.RequiredForOnline = false;
|
||||||
|
};
|
||||||
|
|
||||||
services.enthalpy.bird.config = ''
|
services.enthalpy.bird.config = ''
|
||||||
protocol static {
|
protocol static {
|
||||||
ipv6 sadr;
|
ipv6 sadr;
|
||||||
${
|
${
|
||||||
concatMapStringsSep "\n" (p: ''
|
concatMapStringsSep "\n" (p: ''
|
||||||
route ${p.destination} from ${p.source} via fe80::ff:fe00:1 dev "enthalpy";
|
route ${p.destination} from ${p.source} via fe80::ff:fe00:1 dev "host";
|
||||||
'') birdPrefix
|
'') birdPrefix
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
'';
|
'';
|
||||||
|
|
||||||
systemd.services.enthalpy-exit = mkIf (staticRoutes != [ ]) {
|
systemd.services.enthalpy-exit = {
|
||||||
|
path = with pkgs; [
|
||||||
|
coreutils
|
||||||
|
iproute2
|
||||||
|
];
|
||||||
|
script = ''
|
||||||
|
ip link add enthalpy mtu 1400 address 02:00:00:00:00:01 type veth \
|
||||||
|
peer host mtu 1400 address 02:00:00:00:00:02 netns enthalpy
|
||||||
|
ip link set enthalpy up
|
||||||
|
ip -n enthalpy link set host up
|
||||||
|
${concatMapStringsSep "\n" (
|
||||||
|
p: "ip -n enthalpy -6 route add ${p.destination} from ${p.source} via fe80::ff:fe00:1 dev host"
|
||||||
|
) staticPrefix}
|
||||||
|
'';
|
||||||
|
preStop = ''
|
||||||
|
ip link del enthalpy
|
||||||
|
'';
|
||||||
serviceConfig = {
|
serviceConfig = {
|
||||||
Type = "oneshot";
|
Type = "oneshot";
|
||||||
RemainAfterExit = true;
|
RemainAfterExit = true;
|
||||||
ExecStart = builtins.map (route: "${pkgs.iproute2}/bin/ip -6 route add ${route}") staticRoutes;
|
|
||||||
ExecStop = builtins.map (route: "${pkgs.iproute2}/bin/ip -6 route del ${route}") staticRoutes;
|
|
||||||
};
|
};
|
||||||
after = [ "network.target" ];
|
after = [ "netns-enthalpy.service" ];
|
||||||
wants = [ "network.target" ];
|
partOf = [ "netns-enthalpy.service" ];
|
||||||
wantedBy = [ "multi-user.target" ];
|
wantedBy = [
|
||||||
|
"multi-user.target"
|
||||||
|
"netns-enthalpy.service"
|
||||||
|
];
|
||||||
};
|
};
|
||||||
|
|
||||||
services.enthalpy.services.enthalpy-exit = mkIf (staticRoutes != [ ]) { };
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,15 +25,15 @@ in
|
||||||
DynamicUser = true;
|
DynamicUser = true;
|
||||||
ExecStart = "${pkgs.gost}/bin/gost -L=socks5://[::1]:${toString config.networking.ports.enthalpy-gost}";
|
ExecStart = "${pkgs.gost}/bin/gost -L=socks5://[::1]:${toString config.networking.ports.enthalpy-gost}";
|
||||||
};
|
};
|
||||||
after = [ "netns-${cfg.netns}.service" ];
|
after = [ "netns-enthalpy.service" ];
|
||||||
partOf = [ "netns-${cfg.netns}.service" ];
|
partOf = [ "netns-enthalpy.service" ];
|
||||||
wantedBy = [
|
wantedBy = [
|
||||||
"multi-user.target"
|
"multi-user.target"
|
||||||
"netns-${cfg.netns}.service"
|
"netns-enthalpy.service"
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
|
|
||||||
networking.netns."${cfg.netns}".forwardPorts = singleton {
|
networking.netns.enthalpy.forwardPorts = singleton {
|
||||||
protocol = "tcp";
|
protocol = "tcp";
|
||||||
netns = "default";
|
netns = "default";
|
||||||
source = "[::1]:${toString config.networking.ports.enthalpy-gost}";
|
source = "[::1]:${toString config.networking.ports.enthalpy-gost}";
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
config,
|
config,
|
||||||
lib,
|
lib,
|
||||||
pkgs,
|
pkgs,
|
||||||
|
mylib,
|
||||||
...
|
...
|
||||||
}:
|
}:
|
||||||
with lib;
|
with lib;
|
||||||
|
@ -42,14 +43,6 @@ in
|
||||||
List of endpoints available on this node.
|
List of endpoints available on this node.
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
port = mkOption {
|
|
||||||
type = types.port;
|
|
||||||
default = config.networking.ports.enthalpy-ipsec;
|
|
||||||
readOnly = true;
|
|
||||||
description = ''
|
|
||||||
UDP port used by IKEv2. NAT-T is enabled by default.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
interfaces = mkOption {
|
interfaces = mkOption {
|
||||||
type = types.listOf types.str;
|
type = types.listOf types.str;
|
||||||
default = [ ];
|
default = [ ];
|
||||||
|
@ -99,25 +92,25 @@ in
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
environment.systemPackages = with pkgs; [ strongswan ];
|
environment.etc."enthalpy/ranet/config.json".source =
|
||||||
|
(pkgs.formats.json { }).generate "enthalpy-ranet-config-json"
|
||||||
environment.etc."ranet/config.json".source = (pkgs.formats.json { }).generate "config.json" {
|
{
|
||||||
organization = cfg.ipsec.organization;
|
organization = cfg.ipsec.organization;
|
||||||
common_name = cfg.ipsec.commonName;
|
common_name = cfg.ipsec.commonName;
|
||||||
endpoints = builtins.map (ep: {
|
endpoints = builtins.map (ep: {
|
||||||
serial_number = ep.serialNumber;
|
serial_number = ep.serialNumber;
|
||||||
address_family = ep.addressFamily;
|
address_family = ep.addressFamily;
|
||||||
address = ep.address;
|
address = ep.address;
|
||||||
port = cfg.ipsec.port;
|
port = config.networking.ports.enthalpy-ipsec;
|
||||||
updown = pkgs.writeShellScript "updown" ''
|
updown = pkgs.writeShellScript "updown" ''
|
||||||
LINK=enta$(printf '%08x\n' "$PLUTO_IF_ID_OUT")
|
LINK=enta$(printf '%08x\n' "$PLUTO_IF_ID_OUT")
|
||||||
case "$PLUTO_VERB" in
|
case "$PLUTO_VERB" in
|
||||||
up-client)
|
up-client)
|
||||||
ip link add "$LINK" type xfrm if_id "$PLUTO_IF_ID_OUT"
|
ip link add "$LINK" type xfrm if_id "$PLUTO_IF_ID_OUT"
|
||||||
ip link set "$LINK" netns ${cfg.netns} multicast on mtu 1400 up
|
ip link set "$LINK" netns enthalpy multicast on mtu 1400 up
|
||||||
;;
|
;;
|
||||||
down-client)
|
down-client)
|
||||||
ip -n ${cfg.netns} link del "$LINK"
|
ip -n enthalpy link del "$LINK"
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
'';
|
'';
|
||||||
|
@ -130,7 +123,7 @@ in
|
||||||
charon {
|
charon {
|
||||||
interfaces_use = ${strings.concatStringsSep "," cfg.ipsec.interfaces}
|
interfaces_use = ${strings.concatStringsSep "," cfg.ipsec.interfaces}
|
||||||
port = 0
|
port = 0
|
||||||
port_nat_t = ${toString cfg.ipsec.port}
|
port_nat_t = ${toString config.networking.ports.enthalpy-ipsec}
|
||||||
retransmit_base = 1
|
retransmit_base = 1
|
||||||
plugins {
|
plugins {
|
||||||
socket-default {
|
socket-default {
|
||||||
|
@ -168,7 +161,7 @@ in
|
||||||
''
|
''
|
||||||
else
|
else
|
||||||
cfg.ipsec.registry;
|
cfg.ipsec.registry;
|
||||||
command = "ranet -c /etc/ranet/config.json -r ${registry} -k ${cfg.ipsec.privateKeyPath}";
|
command = "ranet -c /etc/enthalpy/ranet/config.json -r ${registry} -k ${cfg.ipsec.privateKeyPath}";
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
path = with pkgs; [
|
path = with pkgs; [
|
||||||
|
@ -178,7 +171,7 @@ in
|
||||||
script = "${command} up";
|
script = "${command} up";
|
||||||
reload = "${command} up";
|
reload = "${command} up";
|
||||||
preStop = "${command} down";
|
preStop = "${command} down";
|
||||||
serviceConfig = {
|
serviceConfig = mylib.misc.serviceHardened // {
|
||||||
Type = "oneshot";
|
Type = "oneshot";
|
||||||
RemainAfterExit = true;
|
RemainAfterExit = true;
|
||||||
};
|
};
|
||||||
|
@ -189,16 +182,17 @@ in
|
||||||
"network-online.target"
|
"network-online.target"
|
||||||
"strongswan-swanctl.service"
|
"strongswan-swanctl.service"
|
||||||
];
|
];
|
||||||
requires = [
|
|
||||||
"netns-enthalpy.service"
|
|
||||||
];
|
|
||||||
after = [
|
after = [
|
||||||
"network-online.target"
|
"network-online.target"
|
||||||
|
"netns-enthalpy.service"
|
||||||
"strongswan-swanctl.service"
|
"strongswan-swanctl.service"
|
||||||
|
];
|
||||||
|
partOf = [ "netns-enthalpy.service" ];
|
||||||
|
wantedBy = [
|
||||||
|
"multi-user.target"
|
||||||
"netns-enthalpy.service"
|
"netns-enthalpy.service"
|
||||||
];
|
];
|
||||||
wantedBy = [ "multi-user.target" ];
|
reloadTriggers = [ config.environment.etc."enthalpy/ranet/config.json".source ];
|
||||||
reloadTriggers = [ config.environment.etc."ranet/config.json".source ];
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
config,
|
config,
|
||||||
lib,
|
lib,
|
||||||
pkgs,
|
pkgs,
|
||||||
|
mylib,
|
||||||
...
|
...
|
||||||
}:
|
}:
|
||||||
with lib;
|
with lib;
|
||||||
|
@ -13,14 +14,6 @@ in
|
||||||
{
|
{
|
||||||
options.services.enthalpy.nat64 = {
|
options.services.enthalpy.nat64 = {
|
||||||
enable = mkEnableOption "NAT64";
|
enable = mkEnableOption "NAT64";
|
||||||
table = mkOption {
|
|
||||||
type = types.int;
|
|
||||||
default = config.networking.routingTables.nat64;
|
|
||||||
readOnly = true;
|
|
||||||
description = ''
|
|
||||||
Routing table used for NAT64 entries.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
prefix = mkOption {
|
prefix = mkOption {
|
||||||
type = types.str;
|
type = types.str;
|
||||||
default = "64:ff9b::/96";
|
default = "64:ff9b::/96";
|
||||||
|
@ -38,19 +31,14 @@ in
|
||||||
};
|
};
|
||||||
|
|
||||||
config = mkIf (cfg.enable && cfg.nat64.enable) {
|
config = mkIf (cfg.enable && cfg.nat64.enable) {
|
||||||
systemd.network.config = {
|
systemd.network.config.networkConfig.IPv6Forwarding = true;
|
||||||
networkConfig = {
|
|
||||||
IPv6Forwarding = true;
|
|
||||||
ManageForeignRoutes = false;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
systemd.network.networks."70-nat64" = {
|
systemd.network.networks."70-nat64" = {
|
||||||
matchConfig.Name = "nat64";
|
matchConfig.Name = "nat64";
|
||||||
routes = [
|
routes = [
|
||||||
{
|
{
|
||||||
Destination = cfg.nat64.prefix;
|
Destination = cfg.nat64.prefix;
|
||||||
Table = cfg.nat64.table;
|
Table = config.networking.routingTables.nat64;
|
||||||
}
|
}
|
||||||
{ Destination = cfg.nat64.dynamicPool; }
|
{ Destination = cfg.nat64.dynamicPool; }
|
||||||
];
|
];
|
||||||
|
@ -59,7 +47,7 @@ in
|
||||||
};
|
};
|
||||||
|
|
||||||
systemd.services.enthalpy-nat64 = {
|
systemd.services.enthalpy-nat64 = {
|
||||||
serviceConfig = {
|
serviceConfig = mylib.misc.serviceHardened // {
|
||||||
Type = "forking";
|
Type = "forking";
|
||||||
Restart = "on-failure";
|
Restart = "on-failure";
|
||||||
RestartSec = 5;
|
RestartSec = 5;
|
||||||
|
@ -73,25 +61,19 @@ in
|
||||||
''}";
|
''}";
|
||||||
CapabilityBoundingSet = [ "CAP_NET_ADMIN" ];
|
CapabilityBoundingSet = [ "CAP_NET_ADMIN" ];
|
||||||
AmbientCapabilities = [ "CAP_NET_ADMIN" ];
|
AmbientCapabilities = [ "CAP_NET_ADMIN" ];
|
||||||
ProtectSystem = "full";
|
PrivateDevices = false;
|
||||||
ProtectHome = "yes";
|
|
||||||
ProtectKernelTunables = true;
|
|
||||||
ProtectControlGroups = true;
|
|
||||||
PrivateTmp = true;
|
|
||||||
SystemCallFilter = "~@cpu-emulation @debug @keyring @module @mount @obsolete @raw-io";
|
|
||||||
MemoryDenyWriteExecute = "yes";
|
|
||||||
};
|
};
|
||||||
wants = [ "network.target" ];
|
after = [ "netns-enthalpy.service" ];
|
||||||
after = [
|
partOf = [ "netns-enthalpy.service" ];
|
||||||
|
wantedBy = [
|
||||||
|
"multi-user.target"
|
||||||
"netns-enthalpy.service"
|
"netns-enthalpy.service"
|
||||||
"network.target"
|
|
||||||
];
|
];
|
||||||
requires = [ "netns-enthalpy.service" ];
|
|
||||||
wantedBy = [ "multi-user.target" ];
|
|
||||||
};
|
};
|
||||||
|
|
||||||
networking.nftables.enable = true;
|
networking.nftables = {
|
||||||
networking.nftables.tables.enthalpy4 = {
|
enable = true;
|
||||||
|
tables.enthalpy4 = {
|
||||||
family = "ip";
|
family = "ip";
|
||||||
content = ''
|
content = ''
|
||||||
chain forward {
|
chain forward {
|
||||||
|
@ -101,4 +83,5 @@ in
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,63 +0,0 @@
|
||||||
# Portions of this file are sourced from
|
|
||||||
# https://github.com/NickCao/flakes/blob/3b03efb676ea602575c916b2b8bc9d9cd13b0d85/modules/gravity/default.nix
|
|
||||||
{
|
|
||||||
config,
|
|
||||||
lib,
|
|
||||||
...
|
|
||||||
}:
|
|
||||||
with lib;
|
|
||||||
let
|
|
||||||
cfg = config.services.enthalpy;
|
|
||||||
in
|
|
||||||
{
|
|
||||||
options.services.enthalpy = {
|
|
||||||
services = mkOption {
|
|
||||||
type = types.attrsOf (
|
|
||||||
types.submodule {
|
|
||||||
options = {
|
|
||||||
overrideStrategy = mkOption {
|
|
||||||
type = types.str;
|
|
||||||
default = "asDropinIfExists";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
||||||
);
|
|
||||||
default = { };
|
|
||||||
description = ''
|
|
||||||
Services that need to run inside the enthalpy network namespace.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
users = mkOption {
|
|
||||||
type = types.attrsOf (types.submodule { });
|
|
||||||
default = { };
|
|
||||||
description = ''
|
|
||||||
Users utilizing the enthalpy network namespace.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
config = mkIf cfg.enable (mkMerge [
|
|
||||||
{
|
|
||||||
systemd.services = mapAttrs (_name: value: {
|
|
||||||
inherit (value) overrideStrategy;
|
|
||||||
serviceConfig = {
|
|
||||||
NetworkNamespacePath = "/run/netns/${cfg.netns}";
|
|
||||||
BindReadOnlyPaths = [
|
|
||||||
"/etc/netns/${cfg.netns}/resolv.conf:/etc/resolv.conf:norbind"
|
|
||||||
"/etc/netns/${cfg.netns}/nsswitch.conf:/etc/nsswitch.conf:norbind"
|
|
||||||
"/run/netns-${cfg.netns}/nscd:/run/nscd:norbind"
|
|
||||||
];
|
|
||||||
};
|
|
||||||
after = [ "netns-enthalpy.service" ];
|
|
||||||
requires = [ "netns-enthalpy.service" ];
|
|
||||||
}) cfg.services;
|
|
||||||
|
|
||||||
services.enthalpy.services = mapAttrs' (
|
|
||||||
name: _value:
|
|
||||||
nameValuePair "user@${toString config.users.users.${name}.uid}" {
|
|
||||||
overrideStrategy = "asDropin";
|
|
||||||
}
|
|
||||||
) cfg.users;
|
|
||||||
}
|
|
||||||
]);
|
|
||||||
}
|
|
|
@ -24,8 +24,11 @@ in
|
||||||
};
|
};
|
||||||
actions = mkOption {
|
actions = mkOption {
|
||||||
type = types.listOf types.str;
|
type = types.listOf types.str;
|
||||||
default = [
|
default =
|
||||||
|
[
|
||||||
"${cidr.host 1 cfg.srv6.prefix} encap seg6local action End.DT6 table main dev enthalpy table localsid"
|
"${cidr.host 1 cfg.srv6.prefix} encap seg6local action End.DT6 table main dev enthalpy table localsid"
|
||||||
|
]
|
||||||
|
++ optionals cfg.nat64.enable [
|
||||||
"${cidr.host 2 cfg.srv6.prefix} encap seg6local action End.DT6 table nat64 dev enthalpy table localsid"
|
"${cidr.host 2 cfg.srv6.prefix} encap seg6local action End.DT6 table nat64 dev enthalpy table localsid"
|
||||||
];
|
];
|
||||||
description = ''
|
description = ''
|
||||||
|
@ -57,27 +60,34 @@ in
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
services.enthalpy.exit = {
|
||||||
|
enable = true;
|
||||||
|
prefix = singleton {
|
||||||
|
type = "static";
|
||||||
|
destination = cfg.srv6.prefix;
|
||||||
|
source = cfg.network;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
systemd.services.enthalpy-srv6 = {
|
systemd.services.enthalpy-srv6 = {
|
||||||
path = with pkgs; [ iproute2 ];
|
path = with pkgs; [
|
||||||
|
iproute2
|
||||||
|
];
|
||||||
|
script = concatMapStringsSep "\n" (p: "ip -6 route add ${p}") cfg.srv6.actions;
|
||||||
|
preStop = concatMapStringsSep "\n" (p: "ip -6 route del ${p}") cfg.srv6.actions;
|
||||||
serviceConfig = {
|
serviceConfig = {
|
||||||
Type = "oneshot";
|
Type = "oneshot";
|
||||||
RemainAfterExit = true;
|
RemainAfterExit = true;
|
||||||
ExecStartPre = [
|
|
||||||
"${pkgs.iproute2}/bin/ip -n ${cfg.netns} -6 r a ${cfg.srv6.prefix} from ${cfg.network} via fe80::ff:fe00:1 dev enthalpy"
|
|
||||||
];
|
|
||||||
ExecStart = builtins.map (route: "${pkgs.iproute2}/bin/ip -6 r a ${route}") cfg.srv6.actions;
|
|
||||||
ExecStop = builtins.map (route: "${pkgs.iproute2}/bin/ip -6 r d ${route}") cfg.srv6.actions;
|
|
||||||
ExecStopPost = [
|
|
||||||
"${pkgs.iproute2}/bin/ip -n ${cfg.netns} -6 r d ${cfg.srv6.prefix} from ${cfg.network} via fe80::ff:fe00:1 dev enthalpy"
|
|
||||||
];
|
|
||||||
};
|
};
|
||||||
after = [
|
after = [ "netns-enthalpy.service" ];
|
||||||
|
partOf = [
|
||||||
|
"netns-enthalpy.service"
|
||||||
|
"enthalpy-exit.service"
|
||||||
|
];
|
||||||
|
wantedBy = [
|
||||||
|
"multi-user.target"
|
||||||
"netns-enthalpy.service"
|
"netns-enthalpy.service"
|
||||||
"network-online.target"
|
|
||||||
];
|
];
|
||||||
requires = [ "netns-enthalpy.service" ];
|
|
||||||
wants = [ "network-online.target" ];
|
|
||||||
wantedBy = [ "multi-user.target" ];
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue