nixos/jool: add service for setting up SIIT/NAT64
This commit is contained in:
parent
91dbeebd0f
commit
4657ff6ca7
|
@ -911,6 +911,7 @@
|
||||||
./services/networking/jibri/default.nix
|
./services/networking/jibri/default.nix
|
||||||
./services/networking/jicofo.nix
|
./services/networking/jicofo.nix
|
||||||
./services/networking/jitsi-videobridge.nix
|
./services/networking/jitsi-videobridge.nix
|
||||||
|
./services/networking/jool.nix
|
||||||
./services/networking/kea.nix
|
./services/networking/kea.nix
|
||||||
./services/networking/keepalived/default.nix
|
./services/networking/keepalived/default.nix
|
||||||
./services/networking/keybase.nix
|
./services/networking/keybase.nix
|
||||||
|
|
211
nixos/modules/services/networking/jool.nix
Normal file
211
nixos/modules/services/networking/jool.nix
Normal file
|
@ -0,0 +1,211 @@
|
||||||
|
{ config, pkgs, lib, ... }:
|
||||||
|
|
||||||
|
let
|
||||||
|
cfg = config.networking.jool;
|
||||||
|
|
||||||
|
jool = config.boot.kernelPackages.jool;
|
||||||
|
jool-cli = pkgs.jool-cli;
|
||||||
|
|
||||||
|
hardening = {
|
||||||
|
# Run as unprivileged user
|
||||||
|
User = "jool";
|
||||||
|
Group = "jool";
|
||||||
|
DynamicUser = true;
|
||||||
|
|
||||||
|
# Restrict filesystem to only read the jool module
|
||||||
|
TemporaryFileSystem = [ "/" ];
|
||||||
|
BindReadOnlyPaths = [
|
||||||
|
builtins.storeDir
|
||||||
|
"/run/current-system/kernel-modules"
|
||||||
|
];
|
||||||
|
|
||||||
|
# Give capabilities to load the module and configure it
|
||||||
|
AmbientCapabilities = [ "CAP_SYS_MODULE" "CAP_NET_ADMIN" ];
|
||||||
|
RestrictAddressFamilies = [ "AF_NETLINK" ];
|
||||||
|
|
||||||
|
# Other restrictions
|
||||||
|
RestrictNamespaces = [ "net" ];
|
||||||
|
SystemCallFilter = [ "@system-service" "@module" ];
|
||||||
|
CapabilityBoundingSet = [ "CAP_SYS_MODULE" "CAP_NET_ADMIN" ];
|
||||||
|
};
|
||||||
|
|
||||||
|
configFormat = pkgs.formats.json {};
|
||||||
|
|
||||||
|
mkDefaultAttrs = lib.mapAttrs (n: v: lib.mkDefault v);
|
||||||
|
|
||||||
|
defaultNat64 = {
|
||||||
|
instance = "default";
|
||||||
|
framework = "netfilter";
|
||||||
|
global.pool6 = "64:ff9b::/96";
|
||||||
|
};
|
||||||
|
defaultSiit = {
|
||||||
|
instance = "default";
|
||||||
|
framework = "netfilter";
|
||||||
|
};
|
||||||
|
|
||||||
|
nat64Conf = configFormat.generate "jool-nat64.conf" cfg.nat64.config;
|
||||||
|
siitConf = configFormat.generate "jool-siit.conf" cfg.siit.config;
|
||||||
|
|
||||||
|
in
|
||||||
|
|
||||||
|
{
|
||||||
|
###### interface
|
||||||
|
|
||||||
|
options = {
|
||||||
|
networking.jool.enable = lib.mkOption {
|
||||||
|
type = lib.types.bool;
|
||||||
|
default = false;
|
||||||
|
relatedPackages = [ "linuxPackages.jool" "jool-cli" ];
|
||||||
|
description = lib.mdDoc ''
|
||||||
|
Whether to enable Jool, an Open Source implementation of IPv4/IPv6
|
||||||
|
translation on Linux.
|
||||||
|
|
||||||
|
Jool can perform stateless IP/ICMP translation (SIIT) or stateful
|
||||||
|
NAT64, analogous to the IPv4 NAPT. Refer to the upstream
|
||||||
|
[documentation](https://nicmx.github.io/Jool/en/intro-xlat.html) for
|
||||||
|
the supported modes of translation and how to configure them.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
networking.jool.nat64.enable = lib.mkEnableOption (lib.mdDoc "a NAT64 instance of Jool.");
|
||||||
|
networking.jool.nat64.config = lib.mkOption {
|
||||||
|
type = configFormat.type;
|
||||||
|
default = defaultNat64;
|
||||||
|
example = lib.literalExpression ''
|
||||||
|
{
|
||||||
|
# custom NAT64 prefix
|
||||||
|
global.pool6 = "2001:db8:64::/96";
|
||||||
|
|
||||||
|
# Port forwarding
|
||||||
|
bib = [
|
||||||
|
{ # SSH 192.0.2.16 → 2001:db8:a::1
|
||||||
|
"protocol" = "TCP";
|
||||||
|
"ipv4 address" = "192.0.2.16#22";
|
||||||
|
"ipv6 address" = "2001:db8:a::1#22";
|
||||||
|
}
|
||||||
|
{ # DNS (TCP) 192.0.2.16 → 2001:db8:a::2
|
||||||
|
"protocol" = "TCP";
|
||||||
|
"ipv4 address" = "192.0.2.16#53";
|
||||||
|
"ipv6 address" = "2001:db8:a::2#53";
|
||||||
|
}
|
||||||
|
{ # DNS (UDP) 192.0.2.16 → 2001:db8:a::2
|
||||||
|
"protocol" = "UDP";
|
||||||
|
"ipv4 address" = "192.0.2.16#53";
|
||||||
|
"ipv6 address" = "2001:db8:a::2#53";
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
pool4 = [
|
||||||
|
# Ports for dynamic translation
|
||||||
|
{ protocol = "TCP"; prefix = "192.0.2.16/32"; "port range" = "40001-65535"; }
|
||||||
|
{ protocol = "UDP"; prefix = "192.0.2.16/32"; "port range" = "40001-65535"; }
|
||||||
|
{ protocol = "ICMP"; prefix = "192.0.2.16/32"; "port range" = "40001-65535"; }
|
||||||
|
|
||||||
|
# Ports for static BIB entries
|
||||||
|
{ protocol = "TCP"; prefix = "192.0.2.16/32"; "port range" = "22"; }
|
||||||
|
{ protocol = "UDP"; prefix = "192.0.2.16/32"; "port range" = "53"; }
|
||||||
|
];
|
||||||
|
}
|
||||||
|
'';
|
||||||
|
description = lib.mdDoc ''
|
||||||
|
The configuration of a stateful NAT64 instance of Jool managed through
|
||||||
|
NixOS. See https://nicmx.github.io/Jool/en/config-atomic.html for the
|
||||||
|
available options.
|
||||||
|
|
||||||
|
::: {.note}
|
||||||
|
Existing or more instances created manually will not interfere with the
|
||||||
|
NixOS instance, provided the respective `pool4` addresses and port
|
||||||
|
ranges are not overlapping.
|
||||||
|
:::
|
||||||
|
|
||||||
|
::: {.warning}
|
||||||
|
Changes to the NixOS instance performed via `jool instance nixos-nat64`
|
||||||
|
are applied correctly but will be lost after restarting
|
||||||
|
`jool-nat64.service`.
|
||||||
|
:::
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
networking.jool.siit.enable = lib.mkEnableOption (lib.mdDoc "a SIIT instance of Jool.");
|
||||||
|
networking.jool.siit.config = lib.mkOption {
|
||||||
|
type = configFormat.type;
|
||||||
|
default = defaultSiit;
|
||||||
|
example = lib.literalExpression ''
|
||||||
|
{
|
||||||
|
# Maps any IPv4 address x.y.z.t to 2001:db8::x.y.z.t and v.v.
|
||||||
|
pool6 = "2001:db8::/96";
|
||||||
|
|
||||||
|
# Explicit address mappings
|
||||||
|
eamt = [
|
||||||
|
# 2001:db8:1:: ←→ 192.0.2.0
|
||||||
|
{ "ipv6 prefix": "2001:db8:1::/128", "ipv4 prefix": "192.0.2.0" }
|
||||||
|
# 2001:db8:1::x ←→ 198.51.100.x
|
||||||
|
{ "ipv6 prefix": "2001:db8:2::/120", "ipv4 prefix": "198.51.100.0/24" }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
'';
|
||||||
|
description = lib.mdDoc ''
|
||||||
|
The configuration of a SIIT instance of Jool managed through
|
||||||
|
NixOS. See https://nicmx.github.io/Jool/en/config-atomic.html for the
|
||||||
|
available options.
|
||||||
|
|
||||||
|
::: {.note}
|
||||||
|
Existing or more instances created manually will not interfere with the
|
||||||
|
NixOS instance, provided the respective `EAMT` address mappings are not
|
||||||
|
overlapping.
|
||||||
|
:::
|
||||||
|
|
||||||
|
::: {.warning}
|
||||||
|
Changes to the NixOS instance performed via `jool instance nixos-siit`
|
||||||
|
are applied correctly but will be lost after restarting
|
||||||
|
`jool-siit.service`.
|
||||||
|
:::
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
###### implementation
|
||||||
|
|
||||||
|
config = lib.mkIf cfg.enable {
|
||||||
|
environment.systemPackages = [ jool-cli ];
|
||||||
|
boot.extraModulePackages = [ jool ];
|
||||||
|
|
||||||
|
systemd.services.jool-nat64 = lib.mkIf cfg.nat64.enable {
|
||||||
|
description = "Jool, NAT64 setup";
|
||||||
|
documentation = [ "https://nicmx.github.io/Jool/en/documentation.html" ];
|
||||||
|
after = [ "network.target" ];
|
||||||
|
wantedBy = [ "multi-user.target" ];
|
||||||
|
reloadIfChanged = true;
|
||||||
|
serviceConfig = {
|
||||||
|
Type = "oneshot";
|
||||||
|
RemainAfterExit = true;
|
||||||
|
ExecStartPre = "${pkgs.kmod}/bin/modprobe jool";
|
||||||
|
ExecStart = "${jool-cli}/bin/jool file handle ${nat64Conf}";
|
||||||
|
ExecStop = "${jool-cli}/bin/jool -f ${nat64Conf} instance remove";
|
||||||
|
} // hardening;
|
||||||
|
};
|
||||||
|
|
||||||
|
systemd.services.jool-siit = lib.mkIf cfg.siit.enable {
|
||||||
|
description = "Jool, SIIT setup";
|
||||||
|
documentation = [ "https://nicmx.github.io/Jool/en/documentation.html" ];
|
||||||
|
after = [ "network.target" ];
|
||||||
|
wantedBy = [ "multi-user.target" ];
|
||||||
|
reloadIfChanged = true;
|
||||||
|
serviceConfig = {
|
||||||
|
Type = "oneshot";
|
||||||
|
RemainAfterExit = true;
|
||||||
|
ExecStartPre = "${pkgs.kmod}/bin/modprobe jool_siit";
|
||||||
|
ExecStart = "${jool-cli}/bin/jool_siit file handle ${siitConf}";
|
||||||
|
ExecStop = "${jool-cli}/bin/jool_siit -f ${siitConf} instance remove";
|
||||||
|
} // hardening;
|
||||||
|
};
|
||||||
|
|
||||||
|
networking.jool.nat64.config = mkDefaultAttrs defaultNat64;
|
||||||
|
networking.jool.siit.config = mkDefaultAttrs defaultSiit;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
meta.maintainers = with lib.maintainers; [ rnhmjoj ];
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in a new issue