services/enthalpy: refactor for better network isolation and usability

This commit is contained in:
Lu Wang 2024-12-02 01:18:21 +08:00
parent 4b2dcb5541
commit a746646d5e
Signed by: rebmit
SSH key fingerprint: SHA256:3px8QV1zEerIrEWHaqtH5rR9kjetyRST5EipOPrd+bU
16 changed files with 320 additions and 340 deletions

View file

@ -5,14 +5,13 @@
]; ];
services.enthalpy = { services.enthalpy = {
users.rebmit = { };
ipsec.interfaces = [ "enp14s0" ]; ipsec.interfaces = [ "enp14s0" ];
sing-box = { clat = {
enable = true; enable = true;
clat = { segment = lib.singleton "fde3:3be3:a244:2676::2";
enable = true;
segment = lib.singleton "fde3:3be3:a244:2676::2";
};
}; };
gost.enable = true;
}; };
systemd.network = { systemd.network = {

View file

@ -5,17 +5,16 @@
]; ];
services.enthalpy = { services.enthalpy = {
users.rebmit = { };
ipsec = { ipsec = {
interfaces = [ "wlan0" ]; interfaces = [ "wlan0" ];
whitelist = [ "rebmit's edge network" ]; whitelist = [ "rebmit's edge network" ];
}; };
sing-box = { clat = {
enable = true; enable = true;
clat = { segment = lib.singleton "fde3:3be3:a244:2676::2";
enable = true;
segment = lib.singleton "fde3:3be3:a244:2676::2";
};
}; };
gost.enable = true;
}; };
systemd.network = { systemd.network = {

View file

@ -1,4 +1,9 @@
{ profiles, ... }: {
profiles,
data,
lib,
...
}:
{ {
imports = with profiles; [ imports = with profiles; [
services.enthalpy services.enthalpy
@ -8,7 +13,13 @@
ipsec.interfaces = [ "enp3s0" ]; ipsec.interfaces = [ "enp3s0" ];
exit = { exit = {
enable = true; enable = true;
prefix = [ "::/0" ]; prefix = [
{
type = "bird";
destination = "::/0";
source = data.enthalpy_network_prefix;
}
];
}; };
srv6.enable = true; srv6.enable = true;
nat64.enable = true; nat64.enable = true;
@ -46,6 +57,12 @@
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";
};
};
}; };
}; };
} }

View file

@ -0,0 +1,8 @@
{ ... }:
{
ids.uids = {
rebmit = 1000;
};
ids.gids = { };
}

View file

@ -13,8 +13,8 @@ in
ssh = 2222; ssh = 2222;
# enthalpy # enthalpy
sing-box = 1080;
enthalpy-ipsec = 13000; enthalpy-ipsec = 13000;
enthalpy-gost = 1080;
}; };
readOnly = true; readOnly = true;
description = '' description = ''

View file

@ -28,7 +28,6 @@ in
# enthalpy # enthalpy
localsid = 300; localsid = 300;
nat64 = 301; nat64 = 301;
sing-box = 302;
}; };
readOnly = true; readOnly = true;
description = '' description = ''
@ -37,10 +36,7 @@ in
}; };
routingMarks = mkOption { routingMarks = mkOption {
type = with types; attrsOf int; type = with types; attrsOf int;
default = { default = { };
# enthalpy
sing-box = 1300;
};
readOnly = true; readOnly = true;
description = '' description = ''
A mapping of routing marks, each identified by a unique name. A mapping of routing marks, each identified by a unique name.
@ -56,7 +52,6 @@ in
# enthalpy # enthalpy
localsid = 500; localsid = 500;
sing-box = 13000;
}; };
readOnly = true; readOnly = true;
description = '' description = ''

View file

@ -53,7 +53,6 @@ in
systemd.services.enthalpy-bird2 = { systemd.services.enthalpy-bird2 = {
serviceConfig = { serviceConfig = {
NetworkNamespacePath = "/run/netns/${cfg.netns}";
Type = "forking"; Type = "forking";
Restart = "on-failure"; Restart = "on-failure";
RestartSec = 5; RestartSec = 5;
@ -81,14 +80,12 @@ in
SystemCallFilter = "~@cpu-emulation @debug @keyring @module @mount @obsolete @raw-io"; SystemCallFilter = "~@cpu-emulation @debug @keyring @module @mount @obsolete @raw-io";
MemoryDenyWriteExecute = "yes"; MemoryDenyWriteExecute = "yes";
}; };
partOf = [ "enthalpy.service" ];
after = [ "enthalpy.service" ];
requires = [ "enthalpy.service" ];
requiredBy = [ "enthalpy.service" ];
wantedBy = [ "multi-user.target" ]; wantedBy = [ "multi-user.target" ];
reloadTriggers = [ config.environment.etc."enthalpy/bird2.conf".source ]; reloadTriggers = [ config.environment.etc."enthalpy/bird2.conf".source ];
}; };
services.enthalpy.services.enthalpy-bird2 = { };
services.enthalpy.bird.config = mkBefore '' services.enthalpy.bird.config = mkBefore ''
router id ${toString cfg.bird.routerId}; router id ${toString cfg.bird.routerId};
ipv6 sadr table sadr6; ipv6 sadr table sadr6;

View file

@ -0,0 +1,84 @@
# Portions of this file are sourced from
# https://github.com/NickCao/flakes/blob/3b03efb676ea602575c916b2b8bc9d9cd13b0d85/nixos/mainframe/gravity.nix
{
config,
lib,
pkgs,
mylib,
...
}:
with lib;
let
inherit (mylib.network) cidr;
cfg = config.services.enthalpy;
in
{
options.services.enthalpy.clat = {
enable = mkEnableOption "464XLAT for IPv4 connectivity";
address = mkOption {
type = types.str;
default = cidr.host 2 cfg.prefix;
description = ''
IPv6 address used for 464XLAT as the mapped source address.
'';
};
segment = mkOption {
type = types.listOf types.str;
description = ''
SRv6 segments used for NAT64.
'';
};
};
config = mkIf (cfg.enable && cfg.clat.enable) {
systemd.services.enthalpy-clat = {
path = with pkgs; [
iproute2
tayga
];
preStart = ''
ip -6 route replace 64:ff9b::/96 from ${cfg.clat.address} encap seg6 mode encap \
segs ${concatStringsSep "," cfg.clat.segment} dev enthalpy mtu 1280
'';
script = ''
exec tayga --config ${pkgs.writeText "tayga.conf" ''
tun-device clat
prefix 64:ff9b::/96
ipv4-addr 192.0.0.1
map 192.0.0.2 ${cfg.clat.address}
''}
'';
postStart = ''
ip link set clat up
ip -4 addr add 192.0.0.2/32 dev clat
ip -6 route add ${cfg.clat.address} dev clat
ip -4 route add 0.0.0.0/0 dev clat src 192.0.0.2
'';
preStop = ''
ip -6 route del 64:ff9b::/96 from ${cfg.clat.address} encap seg6 mode encap \
segs ${concatStringsSep "," cfg.clat.segment} dev enthalpy mtu 1280
'';
serviceConfig = {
Type = "forking";
Restart = "on-failure";
RestartSec = 5;
DynamicUser = true;
RuntimeDirectory = "enthalpy";
CapabilityBoundingSet = [ "CAP_NET_ADMIN" ];
AmbientCapabilities = [ "CAP_NET_ADMIN" ];
ProtectSystem = "full";
ProtectHome = "yes";
ProtectKernelTunables = true;
ProtectControlGroups = true;
PrivateTmp = true;
SystemCallFilter = "~@cpu-emulation @debug @keyring @module @mount @obsolete @raw-io";
MemoryDenyWriteExecute = "yes";
};
wants = [ "network.target" ];
after = [ "network.target" ];
wantedBy = [ "multi-user.target" ];
};
services.enthalpy.services.enthalpy-clat = { };
};
}

View file

@ -18,21 +18,21 @@ in
prefix = mkOption { prefix = mkOption {
type = types.str; type = types.str;
description = '' description = ''
Prefix to be announced for the local node. Prefix to be announced for the local node in the enthalpy network.
'';
};
address = mkOption {
type = types.str;
default = cidr.host 1 cfg.prefix;
description = ''
Address to be added into the enthalpy network as source address.
''; '';
}; };
netns = mkOption { netns = mkOption {
type = types.str; type = types.str;
default = "enthalpy"; default = "enthalpy";
description = '' description = ''
Name of the network namespace for interfaces. Name of the network namespace for enthalpy interfaces.
'';
};
interface = mkOption {
type = types.str;
default = "enthalpy";
description = ''
Name of the interface to connect to the network namespace.
''; '';
}; };
network = mkOption { network = mkOption {
@ -44,6 +44,11 @@ in
}; };
config = mkIf cfg.enable { config = mkIf cfg.enable {
systemd.network.networks."50-enthalpy" = {
matchConfig.Name = "enthalpy";
linkConfig.RequiredForOnline = false;
};
systemd.services.enthalpy = { systemd.services.enthalpy = {
path = with pkgs; [ path = with pkgs; [
iproute2 iproute2
@ -52,34 +57,29 @@ in
]; ];
script = '' script = ''
ip netns add ${cfg.netns} ip netns add ${cfg.netns}
ip link add ${cfg.interface} mtu 1400 address 02:00:00:00:00:01 type veth peer enthalpy mtu 1400 address 02:00:00:00:00:00 netns ${cfg.netns} ip link add enthalpy mtu 1400 address 02:00:00:00:00:01 type veth peer enthalpy mtu 1400 address 02:00:00:00:00:00 netns ${cfg.netns}
ip link set ${cfg.interface} up
ip -n ${cfg.netns} link set lo up ip -n ${cfg.netns} link set lo up
ip -n ${cfg.netns} link set enthalpy up ip -n ${cfg.netns} link set enthalpy up
ip -n ${cfg.netns} addr add ${cidr.host 0 cfg.prefix}/127 dev enthalpy ip -n ${cfg.netns} addr add ${cfg.address}/128 dev enthalpy
ip netns exec ${cfg.netns} sysctl -w net.ipv6.conf.default.forwarding=1 ip netns exec ${cfg.netns} sysctl -w net.ipv6.conf.default.forwarding=1
ip netns exec ${cfg.netns} sysctl -w net.ipv6.conf.all.forwarding=1 ip netns exec ${cfg.netns} sysctl -w net.ipv6.conf.all.forwarding=1
ip netns exec ${cfg.netns} sysctl -w net.ipv4.conf.default.forwarding=0
ip netns exec ${cfg.netns} sysctl -w net.ipv4.conf.all.forwarding=0
''; '';
preStop = '' preStop = ''
ip link del ${cfg.interface}
ip netns del ${cfg.netns} ip netns del ${cfg.netns}
''; '';
serviceConfig = { serviceConfig = {
Type = "oneshot"; Type = "oneshot";
RemainAfterExit = true; RemainAfterExit = true;
}; };
wants = [ "network-online.target" ]; wants = [ "network.target" ];
after = [ "network-online.target" ]; after = [ "network.target" ];
wantedBy = [ "multi-user.target" ]; wantedBy = [ "multi-user.target" ];
}; };
systemd.network.networks."50-enthalpy" = { environment.etc."netns/enthalpy/resolv.conf".text = lib.mkDefault ''
matchConfig.Name = cfg.interface; nameserver 2606:4700:4700::1111
networkConfig.Address = "${cidr.host 1 cfg.prefix}/127"; '';
routes = singleton {
Destination = cfg.network;
Gateway = "fe80::ff:fe00:0";
};
};
}; };
} }

View file

@ -4,21 +4,39 @@
config, config,
lib, lib,
pkgs, pkgs,
mylib,
... ...
}: }:
with lib; with lib;
let let
inherit (mylib.network) cidr;
cfg = config.services.enthalpy; cfg = config.services.enthalpy;
internalPrefix = filter (p: cidr.child p cfg.prefix) cfg.exit.prefix; birdPrefix = filter (p: p.type == "bird") cfg.exit.prefix;
externalPrefix = subtractLists internalPrefix cfg.exit.prefix; staticPrefix = subtractLists birdPrefix 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 = {
enable = mkEnableOption "netns route leaking"; enable = mkEnableOption "netns route leaking";
prefix = mkOption { prefix = mkOption {
type = types.listOf types.str; type = types.listOf (
types.submodule {
options = {
type = mkOption {
type = types.enum [
"bird"
"static"
];
default = "static";
};
destination = mkOption { type = types.str; };
source = mkOption {
type = types.str;
default = "::/0";
};
};
}
);
default = [ ]; default = [ ];
description = '' description = ''
Prefixes to be announced from the default netns to the enthalpy network. Prefixes to be announced from the default netns to the enthalpy network.
@ -32,32 +50,24 @@ in
ipv6 sadr; ipv6 sadr;
${ ${
concatMapStringsSep "\n" (p: '' concatMapStringsSep "\n" (p: ''
route ${p} from ${cfg.network} via fe80::ff:fe00:1 dev "enthalpy"; route ${p.destination} from ${p.source} via fe80::ff:fe00:1 dev "enthalpy";
'') externalPrefix '') birdPrefix
} }
} }
''; '';
systemd.services.enthalpy-exit = systemd.services.enthalpy-exit = mkIf (staticRoutes != [ ]) {
let serviceConfig = {
routes = map (p: "${p} via fe80::ff:fe00:1 dev enthalpy") internalPrefix; Type = "oneshot";
in RemainAfterExit = true;
mkIf (routes != [ ]) { ExecStart = builtins.map (route: "${pkgs.iproute2}/bin/ip -6 route add ${route}") staticRoutes;
serviceConfig = { ExecStop = builtins.map (route: "${pkgs.iproute2}/bin/ip -6 route del ${route}") staticRoutes;
Type = "oneshot";
RemainAfterExit = true;
ExecStart = builtins.map (route: "${pkgs.iproute2}/bin/ip -n ${cfg.netns} -6 r a ${route}") routes;
ExecStop = builtins.map (route: "${pkgs.iproute2}/bin/ip -n ${cfg.netns} -6 r d ${route}") routes;
};
partOf = [ "enthalpy.service" ];
after = [
"enthalpy.service"
"network-online.target"
];
requires = [ "enthalpy.service" ];
requiredBy = [ "enthalpy.service" ];
wants = [ "network-online.target" ];
wantedBy = [ "multi-user.target" ];
}; };
after = [ "network.target" ];
wants = [ "network.target" ];
wantedBy = [ "multi-user.target" ];
};
services.enthalpy.services.enthalpy-exit = mkIf (staticRoutes != [ ]) { };
}; };
} }

View file

@ -0,0 +1,57 @@
# Portions of this file are sourced from
# https://github.com/NickCao/flakes/blob/3b03efb676ea602575c916b2b8bc9d9cd13b0d85/nixos/mainframe/gravity.nix
{
config,
lib,
pkgs,
...
}:
with lib;
let
cfg = config.services.enthalpy;
in
{
options.services.enthalpy.gost = {
enable = mkEnableOption "simple tunnel for accessing the underlay network";
};
config = mkIf (cfg.enable && cfg.gost.enable) {
systemd.network.networks."50-enthalpy" = {
address = singleton "fc00::";
routes = singleton { Destination = cfg.address; };
};
systemd.services.enthalpy-gost = {
serviceConfig = {
Type = "simple";
Restart = "on-failure";
RestartSec = 5;
DynamicUser = true;
RuntimeDirectory = "enthalpy";
ExecStart = "${pkgs.gost}/bin/gost -L=socks5://[fc00::]:${toString config.networking.ports.enthalpy-gost}";
ProtectSystem = "full";
ProtectHome = "yes";
ProtectKernelTunables = true;
ProtectControlGroups = true;
PrivateTmp = true;
PrivateDevices = true;
SystemCallFilter = "~@cpu-emulation @debug @keyring @module @mount @obsolete @raw-io";
MemoryDenyWriteExecute = "yes";
};
wants = [ "network-online.target" ];
after = [
"enthalpy.service"
"network-online.target"
];
requires = [ "enthalpy.service" ];
wantedBy = [ "multi-user.target" ];
};
services.enthalpy.exit.enable = true;
services.enthalpy.exit.prefix = singleton {
type = "static";
destination = "fc00::/128";
source = "${cfg.address}/128";
};
};
}

View file

@ -60,21 +60,34 @@ in
systemd.services.enthalpy-nat64 = { systemd.services.enthalpy-nat64 = {
serviceConfig = { serviceConfig = {
ExecStart = "${pkgs.tayga}/bin/tayga -d --config ${pkgs.writeText "tayga.conf" '' Type = "forking";
Restart = "on-failure";
RestartSec = 5;
DynamicUser = true;
RuntimeDirectory = "enthalpy";
ExecStart = "${pkgs.tayga}/bin/tayga --config ${pkgs.writeText "tayga.conf" ''
tun-device nat64 tun-device nat64
ipv6-addr fc00:: ipv6-addr fc00::
ipv4-addr 100.127.0.1 ipv4-addr 100.127.0.1
prefix ${cfg.nat64.prefix} prefix ${cfg.nat64.prefix}
dynamic-pool ${cfg.nat64.dynamicPool} dynamic-pool ${cfg.nat64.dynamicPool}
''}"; ''}";
CapabilityBoundingSet = [ "CAP_NET_ADMIN" ];
AmbientCapabilities = [ "CAP_NET_ADMIN" ];
ProtectSystem = "full";
ProtectHome = "yes";
ProtectKernelTunables = true;
ProtectControlGroups = true;
PrivateTmp = true;
SystemCallFilter = "~@cpu-emulation @debug @keyring @module @mount @obsolete @raw-io";
MemoryDenyWriteExecute = "yes";
}; };
partOf = [ "enthalpy.service" ]; wants = [ "network.target" ];
after = [ after = [
"enthalpy.service" "enthalpy.service"
"network.target" "network.target"
]; ];
requires = [ "enthalpy.service" ]; requires = [ "enthalpy.service" ];
requiredBy = [ "enthalpy.service" ];
wantedBy = [ "multi-user.target" ]; wantedBy = [ "multi-user.target" ];
}; };

View file

@ -0,0 +1,57 @@
# 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 {
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";
};
after = [ "enthalpy.service" ];
requires = [ "enthalpy.service" ];
}) cfg.services;
services.enthalpy.services = mapAttrs' (
name: _value:
nameValuePair "user@${toString config.users.users.${name}.uid}" {
overrideStrategy = "asDropin";
}
) cfg.users;
};
}

View file

@ -1,232 +0,0 @@
# Portions of this file are sourced from
# https://github.com/NickCao/flakes/blob/3b03efb676ea602575c916b2b8bc9d9cd13b0d85/nixos/mainframe/gravity.nix
{
config,
lib,
pkgs,
mylib,
...
}:
with lib;
let
inherit (mylib.network) cidr;
cfg = config.services.enthalpy;
in
{
options.services.enthalpy.sing-box = {
enable = mkEnableOption "sing-box universal proxy platform";
tableName = mkOption {
type = types.str;
default = "sing-box";
readOnly = true;
description = ''
Routing table used for sing-box.
'';
};
table = mkOption {
type = types.int;
default = config.networking.routingTables."${cfg.sing-box.tableName}";
readOnly = true;
description = ''
Routing table ID associated with the sing-box routing table.
'';
};
priority = mkOption {
type = types.int;
default = config.networking.routingPolicyPriorities."${cfg.sing-box.tableName}";
readOnly = true;
description = ''
Routing priority assigned to the sing-box routing table.
'';
};
fwmark = mkOption {
type = types.int;
default = config.networking.routingMarks."${cfg.sing-box.tableName}";
readOnly = true;
description = ''
Firewall mark designated for the sing-box routing table.
'';
};
port = mkOption {
type = types.int;
default = config.networking.ports.sing-box;
readOnly = true;
description = ''
Port for the mixed proxy to listen on.
'';
};
clat = {
enable = mkEnableOption "464XLAT for IPv4 connectivity";
address = mkOption {
type = types.str;
default = cidr.host 2 cfg.prefix;
description = ''
IPv6 address used for 464XLAT as the mapped source address.
'';
};
segment = mkOption {
type = types.listOf types.str;
description = ''
SRv6 segments used for NAT64.
'';
};
};
};
config = mkIf (cfg.enable && cfg.sing-box.enable) (mkMerge [
# IPv6
{
systemd.network.networks."50-enthalpy" = {
routes = [
{
Destination = "::/0";
Gateway = "fe80::ff:fe00:0";
Table = cfg.sing-box.table;
Metric = 1024;
}
{
Destination = "::0/0";
Type = "blackhole";
Table = cfg.sing-box.table;
Metric = 4096;
}
];
routingPolicyRules = lib.singleton {
Family = "both";
FirewallMark = cfg.sing-box.fwmark;
Priority = cfg.sing-box.priority;
Table = cfg.sing-box.table;
};
};
services.sing-box = {
enable = true;
settings = {
log = {
level = "info";
};
dns = {
servers = [
{
tag = "cloudflare";
address = "https://[2606:4700:4700::1111]/dns-query";
strategy = "prefer_ipv6";
}
{
tag = "local";
address = "local";
strategy = "prefer_ipv4";
}
];
rules = [
{
geosite = [ "cn" ];
server = "local";
}
];
final = "cloudflare";
};
inbounds = [
{
type = "mixed";
tag = "inbound";
listen = "127.0.0.1";
listen_port = cfg.sing-box.port;
sniff = true;
sniff_override_destination = true;
}
];
outbounds = [
{
type = "direct";
tag = "enthalpy";
routing_mark = cfg.sing-box.fwmark;
domain_strategy = "prefer_ipv6";
}
{
type = "direct";
tag = "direct";
}
];
route = {
rules = [
{
geosite = [ "cn" ];
geoip = [ "cn" ];
ip_cidr = [ "10.0.0.0/8" ];
outbound = "direct";
}
];
final = "enthalpy";
};
};
};
environment.systemPackages = with pkgs; [ gg ];
environment.etc."ggconfig.toml".source = (pkgs.formats.toml { }).generate "ggconfig.toml" {
allow_insecure = false;
no_udp = false;
node = "socks5://127.0.0.1:${toString cfg.sing-box.port}";
proxy_private = false;
test_node_before_use = false;
};
}
# IPv4 (464XLAT)
(mkIf cfg.sing-box.clat.enable {
systemd.network.config = {
networkConfig = {
IPv6Forwarding = true;
ManageForeignRoutes = false;
};
};
systemd.network.networks."50-clat" = {
name = "clat";
linkConfig = {
MTUBytes = "1400";
RequiredForOnline = false;
};
addresses = singleton { Address = "192.0.0.2/32"; };
routes = [
{
Destination = "0.0.0.0/0";
Table = cfg.sing-box.table;
PreferredSource = "192.0.0.2";
Metric = 1024;
}
{ Destination = cfg.sing-box.clat.address; }
];
};
services.enthalpy.exit.enable = true;
services.enthalpy.exit.prefix = singleton "${cfg.sing-box.clat.address}/128";
systemd.services.enthalpy-clatd = {
path = with pkgs; [
iproute2
tayga
];
script = ''
ip r replace 64:ff9b::/96 from ${cfg.sing-box.clat.address} encap seg6 mode encap \
segs ${concatStringsSep "," cfg.sing-box.clat.segment} dev ${cfg.interface} mtu 1280
exec tayga -d --config ${pkgs.writeText "tayga.conf" ''
tun-device clat
prefix 64:ff9b::/96
ipv4-addr 192.0.0.1
map 192.0.0.2 ${cfg.sing-box.clat.address}
''}
'';
partOf = [ "enthalpy.service" ];
after = [
"enthalpy.service"
"network.target"
];
requires = [ "enthalpy.service" ];
requiredBy = [ "enthalpy.service" ];
wantedBy = [ "multi-user.target" ];
};
})
]);
}

View file

@ -15,30 +15,6 @@ in
{ {
options.services.enthalpy.srv6 = { options.services.enthalpy.srv6 = {
enable = mkEnableOption "segment routing over IPv6"; enable = mkEnableOption "segment routing over IPv6";
tableName = mkOption {
type = types.str;
default = "localsid";
readOnly = true;
description = ''
Routing table designated for SRv6 SID.
'';
};
table = mkOption {
type = types.int;
default = config.networking.routingTables."${cfg.srv6.tableName}";
readOnly = true;
description = ''
Routing table ID associated with the localsid routing table.
'';
};
priority = mkOption {
type = types.int;
default = config.networking.routingPolicyPriorities."${cfg.srv6.tableName}";
readOnly = true;
description = ''
Routing priority assigned to the localsid routing table.
'';
};
prefix = mkOption { prefix = mkOption {
type = types.str; type = types.str;
default = cidr.subnet 4 6 cfg.prefix; default = cidr.subnet 4 6 cfg.prefix;
@ -49,8 +25,8 @@ 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 ${cfg.interface} table ${cfg.srv6.tableName}" "${cidr.host 1 cfg.srv6.prefix} encap seg6local action End.DT6 table main dev enthalpy table localsid"
"${cidr.host 2 cfg.srv6.prefix} encap seg6local action End.DT6 table nat64 dev ${cfg.interface} table ${cfg.srv6.tableName}" "${cidr.host 2 cfg.srv6.prefix} encap seg6local action End.DT6 table nat64 dev enthalpy table localsid"
]; ];
description = '' description = ''
List of SRv6 actions configured in the default network namespace. List of SRv6 actions configured in the default network namespace.
@ -70,12 +46,12 @@ in
routes = singleton { routes = singleton {
Destination = "::/0"; Destination = "::/0";
Type = "blackhole"; Type = "blackhole";
Table = cfg.srv6.table; Table = config.networking.routingTables.localsid;
}; };
routingPolicyRules = singleton { routingPolicyRules = singleton {
Priority = cfg.srv6.priority; Priority = config.networking.routingPolicyPriorities.localsid;
Family = "ipv6"; Family = "ipv6";
Table = cfg.srv6.table; Table = config.networking.routingTables.localsid;
From = cfg.network; From = cfg.network;
To = cfg.srv6.prefix; To = cfg.srv6.prefix;
}; };
@ -95,13 +71,11 @@ in
"${pkgs.iproute2}/bin/ip -n ${cfg.netns} -6 r d ${cfg.srv6.prefix} from ${cfg.network} via fe80::ff:fe00:1 dev enthalpy" "${pkgs.iproute2}/bin/ip -n ${cfg.netns} -6 r d ${cfg.srv6.prefix} from ${cfg.network} via fe80::ff:fe00:1 dev enthalpy"
]; ];
}; };
partOf = [ "enthalpy.service" ];
after = [ after = [
"enthalpy.service" "enthalpy.service"
"network-online.target" "network-online.target"
]; ];
requires = [ "enthalpy.service" ]; requires = [ "enthalpy.service" ];
requiredBy = [ "enthalpy.service" ];
wants = [ "network-online.target" ]; wants = [ "network-online.target" ];
wantedBy = [ "multi-user.target" ]; wantedBy = [ "multi-user.target" ];
}; };

View file

@ -1,11 +1,13 @@
{ config, pkgs, ... }: { config, pkgs, ... }:
let let
uid = config.ids.uids.rebmit;
homeDirectory = "/home/rebmit"; homeDirectory = "/home/rebmit";
in in
{ {
programs.fish.enable = true; programs.fish.enable = true;
users.users.rebmit = { users.users.rebmit = {
inherit uid;
hashedPasswordFile = config.sops.secrets."user-password/rebmit".path; hashedPasswordFile = config.sops.secrets."user-password/rebmit".path;
isNormalUser = true; isNormalUser = true;
shell = pkgs.fish; shell = pkgs.fish;