mirror of
https://github.com/gensokyo-zone/infrastructure.git
synced 2026-02-09 04:19:19 -08:00
332 lines
9.8 KiB
Nix
332 lines
9.8 KiB
Nix
let
|
|
sshHostNetworkModule = {
|
|
lib,
|
|
gensokyo-zone,
|
|
osConfig,
|
|
homeConfig,
|
|
sshHostConfig,
|
|
config,
|
|
name,
|
|
...
|
|
}: let
|
|
inherit (gensokyo-zone.lib) unmerged mkAlmostOptionDefault;
|
|
inherit (lib.options) mkOption mkEnableOption;
|
|
inherit (lib.modules) mkIf mkOptionDefault mkDefault;
|
|
inherit (lib.lists) head optional;
|
|
in {
|
|
options = with lib.types; {
|
|
enable =
|
|
mkEnableOption "ssh match block configuration"
|
|
// {
|
|
default = true;
|
|
};
|
|
name = mkOption {
|
|
type = str;
|
|
};
|
|
network = mkOption {
|
|
type = nullOr str;
|
|
default = null;
|
|
};
|
|
hostName = mkOption {
|
|
type = str;
|
|
};
|
|
hostKeyAlias = mkOption {
|
|
type = nullOr str;
|
|
};
|
|
port = mkOption {
|
|
type = port;
|
|
};
|
|
proxyJump = mkOption {
|
|
type = nullOr str;
|
|
default = null;
|
|
};
|
|
matchBlockSettings = mkOption {
|
|
type = unmerged.types.attrs;
|
|
};
|
|
};
|
|
config = let
|
|
system = gensokyo-zone.systems.${sshHostConfig.systemName};
|
|
in {
|
|
port = let
|
|
inherit (system.exports.services) sshd;
|
|
port = head (
|
|
optional (config.network == null && sshd.ports.global.enable or false) sshd.ports.global.port
|
|
++ optional (sshd.ports.public.enable or false) sshd.ports.public.port
|
|
++ [sshd.ports.standard.port]
|
|
);
|
|
in
|
|
mkOptionDefault port;
|
|
hostName = let
|
|
hostName =
|
|
if config.network != null
|
|
then system.network.networks.${config.network}.fqdn
|
|
else sshHostConfig.hostName;
|
|
in
|
|
mkOptionDefault hostName;
|
|
hostKeyAlias = mkOptionDefault sshHostConfig.hostKeyAlias;
|
|
matchBlockSettings = {
|
|
hostname = mkDefault config.hostName;
|
|
port = mkIf (config.port != 22) (mkDefault config.port);
|
|
proxyJump = mkIf (config.proxyJump != null) (mkAlmostOptionDefault config.proxyJump);
|
|
extraOptions = {
|
|
HostKeyAlias = mkIf (config.hostKeyAlias != null && config.hostKeyAlias != config.hostName) (mkOptionDefault config.hostKeyAlias);
|
|
};
|
|
};
|
|
};
|
|
};
|
|
sshHostModule = {
|
|
lib,
|
|
pkgs,
|
|
gensokyo-zone,
|
|
osConfig,
|
|
homeConfig,
|
|
config,
|
|
name,
|
|
...
|
|
}: let
|
|
inherit (gensokyo-zone.lib) unmerged coalesce mkAlmostOptionDefault mapListToAttrs;
|
|
inherit (lib.options) mkOption mkEnableOption;
|
|
inherit (lib.modules) mkIf mkMerge mkOptionDefault mkDefault;
|
|
inherit (lib.lists) head elem filter unique intersectLists;
|
|
inherit (lib.attrsets) filterAttrs mapAttrs' mapAttrsToList nameValuePair;
|
|
inherit (lib.strings) optionalString;
|
|
inherit (osConfig.gensokyo-zone) access;
|
|
cfg = gensokyo-zone.ssh.cfg;
|
|
system = gensokyo-zone.systems.${config.systemName};
|
|
networks = let
|
|
fallbackNetwork =
|
|
if system.network.networks.local.enable or false && access.local.enable
|
|
then "local"
|
|
else if system.access.global.enable
|
|
then null
|
|
else if system.network.networks.int.enable or false
|
|
then "int"
|
|
else if system.network.networks.local.enable or false
|
|
then "local"
|
|
else null;
|
|
networks = map (name: coalesce [name fallbackNetwork]) config.networks;
|
|
in
|
|
unique networks;
|
|
in {
|
|
options = with lib.types; {
|
|
enable =
|
|
mkEnableOption "ssh client configuration"
|
|
// {
|
|
default = true;
|
|
};
|
|
name = mkOption {
|
|
type = str;
|
|
default = name;
|
|
};
|
|
systemName = mkOption {
|
|
type = str;
|
|
};
|
|
user = mkOption {
|
|
type = nullOr str;
|
|
default = cfg.user;
|
|
};
|
|
networks = mkOption {
|
|
type = listOf (nullOr str);
|
|
};
|
|
networks' = mkOption {
|
|
type = attrsOf (submoduleWith {
|
|
modules = [sshHostNetworkModule];
|
|
specialArgs = {
|
|
inherit gensokyo-zone osConfig homeConfig pkgs;
|
|
sshHostConfig = config;
|
|
};
|
|
});
|
|
};
|
|
hostName = mkOption {
|
|
type = nullOr str;
|
|
};
|
|
hostKeyAlias = mkOption {
|
|
type = nullOr str;
|
|
};
|
|
extraOptions = mkOption {
|
|
type = unmerged.types.attrs;
|
|
};
|
|
extraSettings = mkOption {
|
|
type = unmerged.types.attrs;
|
|
default = {};
|
|
};
|
|
set = {
|
|
matchBlockSettings = mkOption {
|
|
type = unmerged.types.attrs;
|
|
default = {};
|
|
};
|
|
matchBlocksSettings = mkOption {
|
|
type = unmerged.types.attrs;
|
|
default = {};
|
|
};
|
|
};
|
|
};
|
|
config = {
|
|
hostName = mkOptionDefault system.access.fqdn;
|
|
hostKeyAlias = mkOptionDefault system.access.fqdn;
|
|
extraOptions = mkOptionDefault (unmerged.mergeAttrs cfg.extraOptions);
|
|
user = mkIf (config.systemName == "u7pro") (mkAlmostOptionDefault "kittywitch");
|
|
networks = let
|
|
enabledNetworks = filterAttrs (_: net: net.enable) system.network.networks;
|
|
networkNames = mapAttrsToList (_: net: net.name) enabledNetworks;
|
|
networks = filter (name: name == null || elem name networkNames) cfg.networks;
|
|
in
|
|
mkOptionDefault networks;
|
|
networks' = let
|
|
canonNetworkName' = intersectLists networks [null "int" "local"];
|
|
canonNetworkName =
|
|
if canonNetworkName' != []
|
|
then head canonNetworkName'
|
|
else null;
|
|
mkNetwork = network: nameValuePair (mkNetworkName network) (mkNetworkConf network);
|
|
mkNetworkName = network:
|
|
if network != null
|
|
then network
|
|
else "fallback";
|
|
mkNetworkConf = network: let
|
|
needsProxy = network == "int" || (network == "local" && !access.local.enable);
|
|
networkConf = {
|
|
network = mkAlmostOptionDefault network;
|
|
name = mkAlmostOptionDefault (config.name + optionalString (network != canonNetworkName) "-${network}");
|
|
proxyJump = mkIf needsProxy (lib.warnIf (config.name == cfg.proxyJump) "proxyJump self-reference" (mkAlmostOptionDefault (
|
|
cfg.proxyJump
|
|
)));
|
|
};
|
|
in
|
|
networkConf;
|
|
in
|
|
mapListToAttrs mkNetwork networks;
|
|
set = {
|
|
matchBlockSettings = let
|
|
matchBlock = {
|
|
user = mkIf (config.user != null) (mkDefault config.user);
|
|
identitiesOnly = mkIf (config.systemName == "u7pro") (mkAlmostOptionDefault true);
|
|
extraOptions = unmerged.mergeAttrs config.extraOptions;
|
|
};
|
|
extraSettings = unmerged.mergeAttrs config.extraSettings;
|
|
in
|
|
mkMerge [matchBlock extraSettings];
|
|
matchBlocksSettings = let
|
|
mkMatchBlock = _: network: let
|
|
matchBlockConf = mkMerge [
|
|
(unmerged.mergeAttrs network.matchBlockSettings)
|
|
(unmerged.mergeAttrs config.set.matchBlockSettings)
|
|
];
|
|
in
|
|
nameValuePair network.name matchBlockConf;
|
|
in
|
|
mapAttrs' mkMatchBlock config.networks';
|
|
};
|
|
};
|
|
};
|
|
sshModule = {
|
|
lib,
|
|
gensokyo-zone,
|
|
osConfig,
|
|
homeConfig,
|
|
config,
|
|
pkgs,
|
|
...
|
|
}: let
|
|
inherit (lib.options) mkOption mkEnableOption;
|
|
inherit (lib.modules) mkIf mkMerge mkOptionDefault;
|
|
inherit (lib.attrsets) mapAttrs mapAttrsToList;
|
|
inherit (lib.lists) elem;
|
|
inherit (gensokyo-zone.lib) unmerged mkAlmostOptionDefault;
|
|
inherit (osConfig.gensokyo-zone) access;
|
|
in {
|
|
options = with lib.types; {
|
|
enable = mkEnableOption "ssh client configuration";
|
|
user = mkOption {
|
|
type = nullOr str;
|
|
default = null;
|
|
};
|
|
hosts = mkOption {
|
|
type = attrsOf (submoduleWith {
|
|
modules = [sshHostModule];
|
|
specialArgs = {
|
|
inherit gensokyo-zone osConfig homeConfig pkgs;
|
|
};
|
|
});
|
|
};
|
|
networks = mkOption {
|
|
type = listOf (nullOr str);
|
|
default = [null];
|
|
};
|
|
proxyJump = mkOption {
|
|
type = str;
|
|
};
|
|
extraOptions = mkOption {
|
|
type = unmerged.types.attrs;
|
|
default = {};
|
|
};
|
|
set = {
|
|
matchBlocksSettings = mkOption {
|
|
type = unmerged.types.attrs;
|
|
default = {};
|
|
};
|
|
};
|
|
};
|
|
config = {
|
|
proxyJump = mkOptionDefault (
|
|
if config.hosts.hakurei.enable
|
|
then config.hosts.hakurei.name
|
|
else gensokyo-zone.systems.hakurei.access.fqdn
|
|
);
|
|
networks = mkOptionDefault [
|
|
(mkIf access.local.enable "local")
|
|
(mkIf access.tail.enabled "tail")
|
|
];
|
|
hosts = mapAttrs (name: system:
|
|
mkIf (elem system.type ["NixOS" "MacOS" "Linux" "Darwin"]) {
|
|
enable = mkAlmostOptionDefault (system.access.online.enable && system.exports.services.sshd.enable);
|
|
systemName = mkOptionDefault name;
|
|
})
|
|
gensokyo-zone.systems;
|
|
set = {
|
|
matchBlocksSettings = let
|
|
mkMatchBlocksHost = host: mkIf host.enable (unmerged.mergeAttrs host.set.matchBlocksSettings);
|
|
in
|
|
mkMerge (
|
|
mapAttrsToList (_: mkMatchBlocksHost) config.hosts
|
|
);
|
|
};
|
|
};
|
|
};
|
|
in
|
|
{
|
|
config,
|
|
osConfig,
|
|
lib,
|
|
gensokyo-zone,
|
|
pkgs,
|
|
...
|
|
}: let
|
|
inherit (lib.options) mkOption;
|
|
inherit (lib.modules) mkIf;
|
|
inherit (gensokyo-zone.lib) unmerged;
|
|
cfg = config.gensokyo-zone.ssh;
|
|
in {
|
|
options.gensokyo-zone.ssh = mkOption {
|
|
type = lib.types.submoduleWith {
|
|
modules = [sshModule];
|
|
specialArgs = {
|
|
inherit gensokyo-zone pkgs;
|
|
inherit osConfig;
|
|
homeConfig = config;
|
|
};
|
|
};
|
|
default = {};
|
|
};
|
|
|
|
config = {
|
|
gensokyo-zone.ssh = {
|
|
};
|
|
programs.ssh = mkIf cfg.enable {
|
|
matchBlocks = unmerged.mergeAttrs cfg.set.matchBlocksSettings;
|
|
};
|
|
lib.gensokyo-zone.ssh = {
|
|
inherit cfg sshModule sshHostModule;
|
|
};
|
|
};
|
|
}
|