2021-02-23 12:58:29 -08:00
|
|
|
{ config, lib, pkgs, ... }:
|
|
|
|
|
|
|
|
with lib;
|
|
|
|
let
|
2021-09-22 18:43:23 -07:00
|
|
|
mapOptional = f: val: if (val != null) then (f val) else null;
|
|
|
|
|
2021-02-23 12:58:29 -08:00
|
|
|
hostOpts = { hostname, ... }: {
|
2021-03-01 14:43:27 -08:00
|
|
|
options = with types; {
|
2021-02-23 12:58:29 -08:00
|
|
|
domain = mkOption {
|
2021-03-17 12:45:40 -07:00
|
|
|
type = str;
|
2021-02-23 12:58:29 -08:00
|
|
|
description =
|
2021-03-17 12:45:40 -07:00
|
|
|
"Primary domain to which the host belongs, in the form of a domain name.";
|
2021-02-23 12:58:29 -08:00
|
|
|
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;
|
2021-02-27 11:05:58 -08:00
|
|
|
description = "Site at which the host is located.";
|
2021-02-25 12:45:50 -08:00
|
|
|
};
|
|
|
|
|
2021-02-23 12:58:29 -08:00
|
|
|
local-networks = mkOption {
|
2021-03-01 14:43:27 -08:00
|
|
|
type = listof str;
|
2021-02-23 12:58:29 -08:00
|
|
|
description =
|
|
|
|
"A list of networks to be considered trusted by this host.";
|
|
|
|
default = [ "127.0.0.0/8" ];
|
|
|
|
};
|
|
|
|
|
|
|
|
profile = mkOption {
|
2021-09-29 17:55:13 -07:00
|
|
|
type = listOf (enumOf (attrNames config.fudo.profiles));
|
2021-02-23 12:58:29 -08:00
|
|
|
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;
|
2021-02-23 12:58:29 -08:00
|
|
|
description = "Email for the administrator of this host.";
|
|
|
|
default = null;
|
|
|
|
};
|
|
|
|
|
|
|
|
local-users = mkOption {
|
2021-03-01 14:43:27 -08:00
|
|
|
type = listOf str;
|
2021-02-23 12:58:29 -08:00
|
|
|
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;
|
2021-02-27 11:05:58 -08:00
|
|
|
description = "Description of this host.";
|
|
|
|
default = "Another Fudo Host.";
|
2021-02-25 12:45:50 -08:00
|
|
|
};
|
|
|
|
|
2021-02-23 12:58:29 -08:00
|
|
|
local-admins = mkOption {
|
2021-03-01 14:43:27 -08:00
|
|
|
type = listOf str;
|
2021-02-23 12:58:29 -08:00
|
|
|
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;
|
2021-02-27 11:05:58 -08:00
|
|
|
description = "List of groups which should exist on this host.";
|
|
|
|
default = [ ];
|
2021-02-25 12:45:50 -08:00
|
|
|
};
|
|
|
|
|
2021-02-27 11:05:58 -08:00
|
|
|
ssh-fingerprints = mkOption {
|
2021-03-01 14:43:27 -08:00
|
|
|
type = listOf str;
|
2021-02-27 11:05:58 -08:00
|
|
|
description = ''
|
2021-04-07 14:03:52 -07:00
|
|
|
A list of DNS SSHFP records for this host. Get with `ssh-keygen -r <hostname>`
|
2021-02-27 11:05:58 -08:00
|
|
|
'';
|
|
|
|
default = [ ];
|
|
|
|
};
|
|
|
|
|
|
|
|
rp = mkOption {
|
2021-03-01 14:43:27 -08:00
|
|
|
type = nullOr str;
|
2021-02-27 11:05:58 -08:00
|
|
|
description = "Responsible person.";
|
|
|
|
default = null;
|
2021-02-25 12:45:50 -08:00
|
|
|
};
|
|
|
|
|
2021-04-12 13:41:00 -07:00
|
|
|
tmp-on-tmpfs = mkOption {
|
|
|
|
type = bool;
|
|
|
|
description =
|
|
|
|
"Use tmpfs for /tmp. Great if you've got enough (>16G) RAM.";
|
|
|
|
default = true;
|
|
|
|
};
|
|
|
|
|
2021-02-23 12:58:29 -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
|
|
|
|
2021-09-29 17:55:13 -07:00
|
|
|
ssh-pubkeys = mkOption {
|
|
|
|
type = listOf str;
|
2021-03-17 12:45:40 -07:00
|
|
|
description =
|
2021-09-29 17:55:13 -07:00
|
|
|
"SSH keys of the host. Find with `ssh-keyscan`. Skip the hostname, just type and key.";
|
|
|
|
default = [];
|
2021-03-17 12:45:40 -07:00
|
|
|
};
|
2021-04-10 13:25:43 -07:00
|
|
|
|
|
|
|
build-pubkeys = mkOption {
|
|
|
|
type = listOf str;
|
|
|
|
description = "SSH public keys used to access the build server.";
|
|
|
|
default = [ ];
|
|
|
|
};
|
2021-04-12 14:53:55 -07:00
|
|
|
|
|
|
|
external-interfaces = mkOption {
|
|
|
|
type = listOf str;
|
|
|
|
description = "A list of interfaces on which to enable the firewall.";
|
|
|
|
default = [ ];
|
|
|
|
};
|
2021-04-29 21:39:21 -07:00
|
|
|
|
|
|
|
keytab-secret-file = mkOption {
|
|
|
|
type = nullOr str;
|
|
|
|
description = "Keytab from which to create a keytab secret.";
|
|
|
|
default = null;
|
|
|
|
};
|
2021-05-01 17:25:31 -07:00
|
|
|
|
|
|
|
keep-cool = mkOption {
|
|
|
|
type = bool;
|
|
|
|
description = "A host that tends to overheat. Try to keep it cooler.";
|
|
|
|
default = false;
|
|
|
|
};
|
2021-07-28 12:01:06 -07:00
|
|
|
|
2021-08-16 16:20:30 -07:00
|
|
|
nixos-system = mkOption {
|
|
|
|
type = bool;
|
|
|
|
description = "Whether the host is a NixOS system.";
|
|
|
|
default = true;
|
|
|
|
};
|
|
|
|
|
|
|
|
arch = mkOption {
|
2021-07-28 12:01:06 -07:00
|
|
|
type = str;
|
2021-08-16 16:20:30 -07:00
|
|
|
description = "System architecture of the system.";
|
2021-07-28 12:01:06 -07:00
|
|
|
};
|
2021-08-18 10:00:18 -07:00
|
|
|
|
|
|
|
android-dev = mkEnableOption "Enable ADB on the host.";
|
2021-02-23 12:58:29 -08:00
|
|
|
};
|
|
|
|
};
|
|
|
|
|
2021-08-18 10:00:18 -07:00
|
|
|
system = import ../system.nix { inherit config lib; };
|
|
|
|
|
2021-02-23 12:58:29 -08:00
|
|
|
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 = { };
|
|
|
|
};
|
2021-02-23 12:58:29 -08:00
|
|
|
|
|
|
|
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};
|
2021-02-23 12:58:29 -08:00
|
|
|
domain-name = host-cfg.domain;
|
2021-03-10 17:23:45 -08:00
|
|
|
domain = config.fudo.domains.${domain-name};
|
2021-04-10 13:25:43 -07:00
|
|
|
has-build-servers = (length (attrNames site.build-servers)) > 0;
|
|
|
|
has-build-keys = (length host-cfg.build-pubkeys) > 0;
|
2021-02-23 12:58:29 -08:00
|
|
|
|
|
|
|
in {
|
|
|
|
networking = {
|
|
|
|
hostName = config.instance.hostname;
|
2021-04-12 14:41:08 -07:00
|
|
|
domain = domain-name;
|
2021-02-23 12:58:29 -08:00
|
|
|
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;
|
2021-02-23 12:58:29 -08:00
|
|
|
|
2021-04-12 14:53:55 -07:00
|
|
|
firewall = {
|
|
|
|
enable = (length host-cfg.external-interfaces) > 0;
|
|
|
|
allowedTCPPorts = [ 22 ];
|
|
|
|
};
|
2021-04-12 13:38:56 -07:00
|
|
|
};
|
|
|
|
|
2021-09-07 15:39:45 -07:00
|
|
|
# NixOS generates a stupid hosts file, just force it
|
|
|
|
environment.etc.hosts = let
|
|
|
|
host-entries = mapAttrsToList
|
|
|
|
(ip: hostnames: "${ip} ${concatStringsSep " " hostnames}")
|
|
|
|
config.fudo.system.hostfile-entries;
|
|
|
|
in mkForce {
|
2021-04-12 13:38:56 -07:00
|
|
|
text = ''
|
|
|
|
127.0.0.1 ${hostname}.${domain-name} ${hostname} localhost
|
|
|
|
127.0.0.2 ${hostname} localhost
|
|
|
|
::1 ${hostname}.${domain-name} ${hostname} localhost
|
2021-09-07 15:39:45 -07:00
|
|
|
${concatStringsSep "\n" host-entries}
|
2021-04-12 13:38:56 -07:00
|
|
|
'';
|
|
|
|
user = "root";
|
|
|
|
group = "root";
|
|
|
|
mode = "0444";
|
2021-02-23 12:58:29 -08:00
|
|
|
};
|
|
|
|
|
2021-09-29 17:55:13 -07:00
|
|
|
# fudo.hosts.${hostname}.build-pubkeys =
|
|
|
|
# map builtins.readFile
|
|
|
|
# (map (build-key-path: "${build-key-path}/${hostname}.key.pub")
|
|
|
|
# (optional (site.build-key-path != null) site.build-key-path));
|
|
|
|
|
|
|
|
# nix = mkIf
|
|
|
|
# (has-build-servers && has-build-keys && site.enable-distributed-builds) {
|
|
|
|
# buildMachines = mapAttrsToList (hostname: buildOpts: {
|
|
|
|
# hostName = "${hostname}.${domain-name}";
|
|
|
|
# maxJobs = buildOpts.max-jobs;
|
|
|
|
# speedFactor = buildOpts.speed-factor;
|
|
|
|
# supportedFeatures = buildOpts.supported-features;
|
|
|
|
# sshKey = config.fudo.secrets.host-secrets.${hostname}.build-private-key.target-file;
|
|
|
|
# }) site.build-servers;
|
|
|
|
# distributedBuilds = true;
|
|
|
|
# };
|
2021-04-10 13:25:43 -07:00
|
|
|
|
2021-04-03 10:15:10 -07:00
|
|
|
time.timeZone = site.timezone;
|
|
|
|
|
2021-02-23 12:58:29 -08:00
|
|
|
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-23 12:58:29 -08:00
|
|
|
|
2021-02-25 12:45:50 -08:00
|
|
|
virtualisation.docker = mkIf (host-cfg.docker-server) {
|
2021-02-23 12:58:29 -08:00
|
|
|
enable = true;
|
|
|
|
enableOnBoot = true;
|
2021-02-25 12:45:50 -08:00
|
|
|
autoPrune.enable = true;
|
2021-02-23 12:58:29 -08:00
|
|
|
};
|
2021-03-17 12:45:40 -07:00
|
|
|
|
2021-04-12 13:41:00 -07:00
|
|
|
boot.tmpOnTmpfs = host-cfg.tmp-on-tmpfs;
|
|
|
|
|
2021-09-29 18:44:33 -07:00
|
|
|
fudo.secrets.host-secrets.${hostname} = let
|
|
|
|
keytab-file =
|
|
|
|
if (hasAttr hostname config.fudo.secrets.files.host-keytabs) then
|
|
|
|
config.fudo.secrets.files.host-keytabs.${hostname}
|
|
|
|
else null;
|
|
|
|
|
|
|
|
build-private-key-file =
|
|
|
|
if (hasAttr hostname config.fudo.secrets.files.build-keypairs) then
|
|
|
|
config.fudo.secrets.files.build-keypairs.${hostname}
|
|
|
|
else null;
|
|
|
|
in {
|
|
|
|
host-keytab = mkIf (keytab-file != null) {
|
|
|
|
source-file = keytab-file;
|
2021-09-22 18:43:23 -07:00
|
|
|
target-file = "/etc/krb5.keytab";
|
|
|
|
user = "root";
|
|
|
|
};
|
|
|
|
|
2021-09-29 18:44:33 -07:00
|
|
|
build-private-key = mkIf (build-private-key-file != null) {
|
|
|
|
source-file = build-private-key-file;
|
2021-09-22 18:43:23 -07:00
|
|
|
target-file = "/var/run/nix-build/host.key";
|
|
|
|
user = "root";
|
|
|
|
};
|
2021-04-29 21:39:21 -07:00
|
|
|
};
|
|
|
|
|
2021-08-18 10:00:18 -07:00
|
|
|
programs.adb.enable = host-cfg.android-dev;
|
|
|
|
users.groups.adbusers = mkIf host-cfg.android-dev {
|
|
|
|
members = system.local-admins;
|
|
|
|
};
|
|
|
|
|
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);
|
2021-02-23 12:58:29 -08:00
|
|
|
};
|
|
|
|
}
|