infrastructure/modules/nixos/access/peeps.nix

53 lines
1.6 KiB
Nix

{
config,
options,
lib,
...
}: let
inherit (lib.options) mkOption mkEnableOption;
inherit (lib.modules) mkIf mkMerge mkBefore mkDefault;
inherit (lib.attrsets) mapAttrsToList mapAttrs' nameValuePair;
inherit (lib.strings) concatStringsSep;
inherit (config) networking;
cfg = config.networking.access.peeps;
mkSopsName = name: "access-peeps-nft-${name}";
mkNftName = name: "peeps_${name}6";
hasSops = options ? sops.secrets;
in {
options.networking.access.peeps = with lib.types; {
enable = mkEnableOption "peeps" // { default = hasSops; };
ranges = mkOption {
type = attrsOf str;
default = { };
};
stateDir = mkOption {
type = path;
default = "/run/access/peeps";
};
};
config.${if hasSops then "sops" else null}.secrets = let
sopsFile = mkDefault ../../../nixos/secrets/access.yaml;
sopsSecrets = mapAttrs' (name: _: nameValuePair (mkSopsName name) {
inherit sopsFile;
path = mkDefault "${cfg.stateDir}/${name}.nft";
}) cfg.ranges;
in mkIf cfg.enable sopsSecrets;
config.networking = let
nftRanges = mapAttrsToList (name: range: let
nft = "define ${mkNftName name} = ${range}";
in mkBefore nft) cfg.ranges;
condition = "ip6 saddr { ${concatStringsSep "," (mapAttrsToList (name: _: "$" + mkNftName name) cfg.ranges)} }";
in {
nftables.ruleset = mkIf cfg.enable (mkMerge (
nftRanges
++ [ (mkBefore ''include "${cfg.stateDir}/*.nft"'') ]
));
firewall.interfaces.peeps = {
nftables.enable = cfg.enable;
nftables.conditions = [
(mkIf (cfg.enable && networking.enableIPv6) condition)
];
};
};
}