nixos-config/lib/fudo/sites.nix
2021-04-09 14:24:50 -07:00

172 lines
4.8 KiB
Nix

{ config, lib, pkgs, ... }:
with lib;
let
hostname = config.instance.hostname;
site-name = config.fudo.hosts.${hostname}.site;
site-cfg = config.fudo.sites.${site-name};
siteOpts = { site, ... }: {
options = with types; {
site = mkOption {
type = str;
description = "Site name.";
default = site;
};
network = mkOption {
type = str;
description = "Network to be treated as local.";
};
dynamic-network = mkOption {
type = nullOr str;
description = "Network to be allocated by DHCP.";
default = null;
};
gateway-v4 = mkOption {
type = nullOr str;
description = "Gateway to use for public ipv4 internet access.";
default = null;
};
gateway-v6 = mkOption {
type = nullOr str;
description = "Gateway to use for public ipv6 internet access.";
default = null;
};
gateway-host = mkOption {
type = nullOr str;
description = "Identity of the host to act as a gateway.";
default = null;
};
local-groups = mkOption {
type = listOf str;
description = "List of groups which should exist at this site.";
default = [ ];
};
local-users = mkOption {
type = listOf str;
description =
"List of users which should exist on all hosts at this site.";
default = [ ];
};
local-admins = mkOption {
type = listOf str;
description =
"List of admin users which should exist on all hosts at this site.";
default = [ ];
};
enable-monitoring =
mkEnableOption "Enable site-wide monitoring with prometheus.";
nameservers = mkOption {
type = listOf str;
description = "List of nameservers to be used by hosts at this site.";
default = [ ];
};
timezone = mkOption {
type = str;
description = "Timezone of the site.";
example = "America/Winnipeg";
};
deploy-pubkey = mkOption {
type = nullOr str;
description = "SSH pubkey of site deploy key. Used by dropbear daemon.";
default = null;
};
dropbear-rsa-key-path = mkOption {
type = str;
description = "Location of Dropbear RSA key.";
default = "/etc/dropbear/host_rsa_key";
};
dropbear-ecdsa-key-path = mkOption {
type = str;
description = "Location of Dropbear ECDSA key.";
default = "/etc/dropbear/host_ecdsa_key";
};
dropbear-deploy-port = mkOption {
type = port;
description = "Port to be used for the deploy SSH server.";
default = 2112;
};
};
};
in {
options.fudo.sites = mkOption {
type = with types; attrsOf (submodule siteOpts);
description = "Site configurations for all sites known to the system.";
default = { };
};
config = mkIf (site-cfg.deploy-pubkey != null) {
environment.etc."dropbear/authorized_keys" = {
text = "${site-cfg.deploy-pubkey} root@deploy";
mode = "0400";
};
networking.firewall.allowedTCPPorts = [ site-cfg.dropbear-deploy-port ];
systemd = {
sockets = {
dropbear-deploy = {
wantedBy = [ "sockets.target" ];
socketConfig = {
ListenStream = "0.0.0.0:${toString site-cfg.dropbear-deploy-port}";
Accept = true;
};
unitConfig = {
restartIfChanged = true;
};
};
};
services = {
dropbear-deploy-init = {
wantedBy = [ "multi-user.target" ];
script = ''
if [ ! -d /etc/dropbear ]; then
mkdir /etc/dropbear
chmod 700 /etc/dropbear
fi
if [ ! -f ${site-cfg.dropbear-rsa-key-path} ]; then
${pkgs.dropbear}/bin/dropbearkey -t rsa -f ${site-cfg.dropbear-rsa-key-path}
${pkgs.coreutils}/bin/chmod 0400 ${site-cfg.dropbear-rsa-key-path}
fi
if [ ! -f ${site-cfg.dropbear-ecdsa-key-path} ]; then
${pkgs.dropbear}/bin/dropbearkey -t ecdsa -f ${site-cfg.dropbear-ecdsa-key-path}
${pkgs.coreutils}/bin/chmod 0400 ${site-cfg.dropbear-ecdsa-key-path}
fi
'';
};
"dropbear-deploy@" = {
description = "Per-connection service for deployment, using dropbear.";
requires = [ "dropbear-deploy-init.service" ];
after = [ "network.target" ];
serviceConfig = {
Type = "simple";
ExecStart = "${pkgs.dropbear}/bin/dropbear -F -i -m -s -j -k -r ${site-cfg.dropbear-rsa-key-path} -r ${site-cfg.dropbear-ecdsa-key-path}";
ExecReload = "${pkgs.utillinux}/bin/kill -HUP $MAINPID";
StandardInput = "socket";
};
};
};
};
};
}