mirror of
https://github.com/gensokyo-zone/infrastructure.git
synced 2026-02-10 04:49:19 -08:00
236 lines
7 KiB
Nix
236 lines
7 KiB
Nix
{
|
|
pkgs,
|
|
inputs,
|
|
config,
|
|
lib,
|
|
...
|
|
}: let
|
|
inherit (lib.modules) mkIf mkMerge mkBefore mkAfter mkDefault mkOptionDefault;
|
|
inherit (lib.options) mkOption mkEnableOption;
|
|
inherit (lib.lists) optionals;
|
|
inherit (lib.strings) concatStringsSep optionalString;
|
|
inherit (config.services) tailscale avahi;
|
|
inherit (config) networking;
|
|
inherit (networking) hostName;
|
|
cfg = config.networking.access;
|
|
cidrModule = { config, ... }: {
|
|
options = with lib.types; {
|
|
all = mkOption {
|
|
type = listOf str;
|
|
readOnly = true;
|
|
};
|
|
v4 = mkOption {
|
|
type = listOf str;
|
|
default = [ ];
|
|
};
|
|
v6 = mkOption {
|
|
type = listOf str;
|
|
default = [ ];
|
|
};
|
|
};
|
|
config.all = mkOptionDefault (
|
|
config.v4
|
|
++ optionals networking.enableIPv6 config.v6
|
|
);
|
|
};
|
|
in {
|
|
options.networking.access = with lib.types; {
|
|
hostnameForNetwork = mkOption {
|
|
type = attrsOf str;
|
|
default = { };
|
|
};
|
|
cidrForNetwork = mkOption {
|
|
type = attrsOf (submodule cidrModule);
|
|
default = { };
|
|
};
|
|
localaddrs = {
|
|
enable = mkEnableOption "localaddrs" // {
|
|
default = networking.firewall.interfaces.local.nftables.enable;
|
|
};
|
|
stateDir = mkOption {
|
|
type = path;
|
|
default = "/var/lib/localaddrs";
|
|
};
|
|
reloadScript = mkOption {
|
|
type = path;
|
|
readOnly = true;
|
|
};
|
|
nftablesInclude = mkOption {
|
|
type = lines;
|
|
readOnly = true;
|
|
};
|
|
};
|
|
};
|
|
|
|
config.networking.access = {
|
|
hostnameForNetwork = {
|
|
local = let
|
|
eth0 = config.systemd.network.networks.eth0 or { };
|
|
hasStaticAddress = eth0.address or [ ] != [ ] || eth0.addresses or [ ] != [ ];
|
|
hasSLAAC = eth0.slaac.enable or false;
|
|
in mkMerge [
|
|
(mkIf (hasStaticAddress || hasSLAAC) (mkDefault "${hostName}.local.${networking.domain}"))
|
|
(mkIf (avahi.enable && avahi.publish.enable) (mkOptionDefault "${hostName}.local"))
|
|
];
|
|
tail = mkIf tailscale.enable "${hostName}.tail.${networking.domain}";
|
|
global = mkIf (networking.enableIPv6 && networking.tempAddresses == "disabled") "${hostName}.${networking.domain}";
|
|
};
|
|
cidrForNetwork = {
|
|
loopback = {
|
|
v4 = [
|
|
"127.0.0.0/8"
|
|
];
|
|
v6 = [
|
|
"::1"
|
|
];
|
|
};
|
|
local = {
|
|
v4 = [
|
|
"10.1.1.0/24"
|
|
];
|
|
v6 = [
|
|
"fd0a::/64"
|
|
"fe80::/64"
|
|
];
|
|
};
|
|
tail = mkIf tailscale.enable {
|
|
v4 = [
|
|
"100.64.0.0/10"
|
|
];
|
|
v6 = [
|
|
"fd7a:115c:a1e0::/96"
|
|
"fd7a:115c:a1e0:ab12::/64"
|
|
];
|
|
};
|
|
};
|
|
localaddrs = {
|
|
nftablesInclude = mkBefore (''
|
|
define localrange6 = 2001:568::/29
|
|
'' + optionalString cfg.localaddrs.enable ''
|
|
include "${cfg.localaddrs.stateDir}/*.nft"
|
|
'');
|
|
reloadScript = let
|
|
localaddrs-reload = pkgs.writeShellScript "localaddrs-reload" ''
|
|
${config.systemd.package}/bin/systemctl reload localaddrs 2>/dev/null ||
|
|
${config.systemd.package}/bin/systemctl restart localaddrs ||
|
|
true
|
|
'';
|
|
in "${localaddrs-reload}";
|
|
};
|
|
};
|
|
|
|
config.networking = {
|
|
nftables.ruleset = mkBefore cfg.localaddrs.nftablesInclude;
|
|
firewall = {
|
|
interfaces.local = {
|
|
nftables.conditions = [
|
|
"ip saddr { ${concatStringsSep ", " cfg.cidrForNetwork.local.v4} }"
|
|
(mkIf networking.enableIPv6
|
|
"ip6 saddr { $localrange6, ${concatStringsSep ", " cfg.cidrForNetwork.local.v6} }"
|
|
)
|
|
];
|
|
};
|
|
};
|
|
};
|
|
config.systemd.services = let
|
|
localaddrs = pkgs.writeShellScript "localaddrs" ''
|
|
set -eu
|
|
getaddrs() {
|
|
local PREFIX=$1 PATTERN=$2 IPADDRS
|
|
IPADDRS=$(${pkgs.iproute2}/bin/ip -o addr show to "$PREFIX") || return $?
|
|
IPADDRS=$(printf '%s\n' "$IPADDRS" | ${pkgs.gnugrep}/bin/grep -o "$PATTERN") || return $?
|
|
if [[ -z $IPADDRS ]]; then
|
|
return 1
|
|
fi
|
|
printf '%s\n' "$IPADDRS"
|
|
}
|
|
getaddrs4() {
|
|
getaddrs 10.1.1.0/24 '[0-9]*\.[0-9.]*/[0-9]*'
|
|
}
|
|
getaddrs6() {
|
|
getaddrs 2001:568::/29 '[0-9a-f:]*:[0-9a-f:]*/[0-9]*'
|
|
}
|
|
mkdir -p $STATE_DIRECTORY
|
|
if LOCALADDRS4=$(getaddrs4); then
|
|
printf '%s\n' "$LOCALADDRS4" > $STATE_DIRECTORY/localaddrs4
|
|
else
|
|
echo WARNING: localaddr4 not found >&2
|
|
fi
|
|
if LOCALADDRS6=$(getaddrs6); then
|
|
echo "$LOCALADDRS6" > $STATE_DIRECTORY/localaddrs6
|
|
else
|
|
echo WARNING: localaddr6 not found >&2
|
|
fi
|
|
'';
|
|
localaddrs-nftables = pkgs.writeShellScript "localaddrs-nftables" ''
|
|
set -eu
|
|
LOCALADDR6=$(head -n1 "${cfg.localaddrs.stateDir}/localaddrs6" || true)
|
|
if [[ -n $LOCALADDR6 ]]; then
|
|
printf 'redefine localrange6 = %s\n' "$LOCALADDR6" > ${cfg.localaddrs.stateDir}/ranges.nft
|
|
fi
|
|
'';
|
|
localaddrs-nginx = pkgs.writeShellScript "localaddrs-nginx" ''
|
|
set -eu
|
|
LOCALADDR6=$(head -n1 "${cfg.localaddrs.stateDir}/localaddrs6" || true)
|
|
if [[ -n $LOCALADDR6 ]]; then
|
|
printf 'allow %s;\n' "$LOCALADDR6" > ${cfg.localaddrs.stateDir}/allow.nginx.conf
|
|
fi
|
|
LOCALADDR4=$(head -n1 "${cfg.localaddrs.stateDir}/localaddrs4" || true)
|
|
if [[ -n $LOCALADDR4 ]]; then
|
|
printf 'allow %s;\n' "$LOCALADDR4" >> ${cfg.localaddrs.stateDir}/allow.nginx.conf
|
|
fi
|
|
'';
|
|
in {
|
|
localaddrs = mkIf cfg.localaddrs.enable {
|
|
unitConfig = {
|
|
After = [ "network-online.target" ];
|
|
};
|
|
serviceConfig = rec {
|
|
StateDirectory = "localaddrs";
|
|
ExecStart = mkMerge [
|
|
[ "${localaddrs}" ]
|
|
(mkIf networking.nftables.enable (mkAfter [
|
|
"${localaddrs-nftables}"
|
|
]))
|
|
(mkIf config.services.nginx.enable (mkAfter [
|
|
"${localaddrs-nginx}"
|
|
]))
|
|
];
|
|
ExecReload = ExecStart;
|
|
Type = "oneshot";
|
|
RemainAfterExit = true;
|
|
};
|
|
};
|
|
nftables = mkIf (networking.nftables.enable && cfg.localaddrs.enable) rec {
|
|
wants = [ "localaddrs.service" ];
|
|
serviceConfig = {
|
|
ExecReload = mkBefore [
|
|
"+${cfg.localaddrs.reloadScript}"
|
|
];
|
|
};
|
|
};
|
|
nginx = mkIf (config.services.nginx.enable && cfg.localaddrs.enable) rec {
|
|
wants = [ "localaddrs.service" ];
|
|
after = wants;
|
|
serviceConfig = {
|
|
ExecReload = mkBefore [
|
|
"+${cfg.localaddrs.reloadScript}"
|
|
];
|
|
};
|
|
};
|
|
};
|
|
|
|
config._module.args.access = let
|
|
systemFor = hostName: inputs.self.nixosConfigurations.${hostName}.config;
|
|
systemForOrNull = hostName: inputs.self.nixosConfigurations.${hostName}.config or null;
|
|
in {
|
|
inherit (cfg) hostnameForNetwork cidrForNetwork localaddrs;
|
|
systemFor = hostName: if hostName == networking.hostName
|
|
then config
|
|
else systemFor hostName;
|
|
systemForOrNull = hostName: if hostName == networking.hostName
|
|
then config
|
|
else systemForOrNull hostName;
|
|
};
|
|
config.lib.access.mkSnakeOil = pkgs.callPackage ../../packages/snakeoil.nix { };
|
|
}
|