nixos-config/lib/fudo/hosts.nix

184 lines
5.2 KiB
Nix
Raw Normal View History

{ config, lib, pkgs, ... }:
with lib;
let
hostOpts = { hostname, ... }: {
2021-03-01 14:43:27 -08:00
options = with types; {
domain = mkOption {
2021-03-17 12:45:40 -07:00
type = str;
description =
2021-03-17 12:45:40 -07:00
"Primary domain to which the host belongs, in the form of a domain name.";
default = "fudo.org";
};
2021-03-17 12:45:40 -07:00
extra-domains = mkOption {
type = listOf str;
description = "Extra domain in which this host is reachable.";
default = [ ];
};
aliases = mkOption {
type = listOf str;
description =
"Host aliases used by the current host. Note this will be multiplied with extra-domains.";
default = [ ];
};
2021-02-25 12:45:50 -08:00
site = mkOption {
2021-03-17 12:45:40 -07:00
type = str;
description = "Site at which the host is located.";
2021-02-25 12:45:50 -08:00
};
local-networks = mkOption {
2021-03-01 14:43:27 -08:00
type = listof str;
description =
"A list of networks to be considered trusted by this host.";
default = [ "127.0.0.0/8" ];
};
profile = mkOption {
# FIXME: get this list from profiles directly
2021-03-01 14:43:27 -08:00
type = listof (enum "desktop" "laptop" "server");
description =
"The profile to be applied to the host, determining what software is included.";
};
admin-email = mkOption {
2021-03-01 14:43:27 -08:00
type = nullOr str;
description = "Email for the administrator of this host.";
default = null;
};
local-users = mkOption {
2021-03-01 14:43:27 -08:00
type = listOf str;
description =
"List of users who should have local (i.e. login) access to the host.";
default = [ ];
};
2021-02-25 12:45:50 -08:00
description = mkOption {
2021-03-17 12:45:40 -07:00
type = str;
description = "Description of this host.";
default = "Another Fudo Host.";
2021-02-25 12:45:50 -08:00
};
local-admins = mkOption {
2021-03-01 14:43:27 -08:00
type = listOf str;
description =
"A list of users who should have admin access to this host.";
default = [ ];
};
2021-02-25 12:45:50 -08:00
local-groups = mkOption {
2021-03-01 14:43:27 -08:00
type = listOf str;
description = "List of groups which should exist on this host.";
default = [ ];
2021-02-25 12:45:50 -08:00
};
ssh-fingerprints = mkOption {
2021-03-01 14:43:27 -08:00
type = listOf str;
description = ''
A list of DNS SSHFP records for this host.
'';
default = [ ];
};
rp = mkOption {
2021-03-01 14:43:27 -08:00
type = nullOr str;
description = "Responsible person.";
default = null;
2021-02-25 12:45:50 -08:00
};
enable-gui = mkEnableOption "Install desktop GUI software.";
docker-server = mkEnableOption "Enable Docker on the current host.";
2021-03-16 19:47:13 -07:00
kerberos-services = mkOption {
type = listOf str;
description =
"List of services which should exist for this host, if it belongs to a realm.";
default = [ "ssh" "host" ];
};
2021-03-17 12:45:40 -07:00
ssh-pubkey = mkOption {
type = nullOr str;
description =
"SSH key of the host. Find with `ssh-keyscan`. Skip the hostname, just type and key.";
default = null;
};
};
};
in {
2021-03-01 14:43:27 -08:00
options.fudo.hosts = with types;
mkOption {
type = attrsOf (submodule hostOpts);
description = "Host configurations for all hosts known to the system.";
default = { };
};
config = let
hostname = config.instance.hostname;
host-cfg = config.fudo.hosts.${hostname};
site-name = host-cfg.site;
2021-02-25 12:45:50 -08:00
site = config.fudo.sites.${site-name};
domain-name = host-cfg.domain;
2021-03-10 17:23:45 -08:00
domain = config.fudo.domains.${domain-name};
in {
networking = {
hostName = config.instance.hostname;
nameservers = site.nameservers;
2021-03-01 16:08:14 -08:00
# This will cause a loop on the gateway itself
#defaultGateway = site.gateway-v4;
#defaultGateway6 = site.gateway-v6;
# Necessary to ensure that Kerberos and Avahi both work. Kerberos needs
# the fqdn of the host, whereas Avahi wants just the simple hostname.`
hosts = { "127.0.0.1" = [ "${hostname}.${domain-name}" "${hostname}" ]; };
};
2021-04-03 10:15:10 -07:00
time.timeZone = site.timezone;
krb5.libdefaults.default_realm = domain.gssapi-realm;
services.cron.mailto = domain.admin-email;
environment.systemPackages = with pkgs;
2021-02-25 12:45:50 -08:00
mkIf (host-cfg.docker-server) [ docker nix-prefetch-docker ];
2021-02-25 12:45:50 -08:00
virtualisation.docker = mkIf (host-cfg.docker-server) {
enable = true;
enableOnBoot = true;
2021-02-25 12:45:50 -08:00
autoPrune.enable = true;
};
2021-03-17 12:45:40 -07:00
programs.ssh.knownHosts = let
keyed-hosts =
filterAttrs (host: opts: opts.ssh-pubkey != null) config.fudo.hosts;
traceOut = obj: builtins.trace obj obj;
crossProduct = f: list0: list1:
concatMap (el0: map (el1: f el0 el1) list1) list0;
getHostnames = hostOpts:
[ hostOpts.hostname ]
++ (crossProduct (host: domain: "${host}.${domain}")
([ hostOpts.hostname ] ++ hostOpts.aliases)
([ hostOpts.domain ] ++ hostOpts.extra-domains));
getHostEntryPairs = host:
map (hostname: nameValuePair hostname { publicKey = host.ssh-pubkey; })
(getHostnames host);
hostAttrsToList = hostAttrs:
mapAttrsToList (hostname: opts: { hostname = hostname; } // opts)
hostAttrs;
getKnownHosts = hosts:
concatMap getHostEntryPairs (hostAttrsToList hosts);
in listToAttrs (getKnownHosts keyed-hosts);
};
}