{ zentralwerk, config, lib, pkgs, ... }: let cfg = config.c3d2; hqPrefix64 = lib.removeSuffix "::" (builtins.head ( builtins.split "/" zentralwerk.lib.config.site.net.c3d2.subnets6.dn42 )); neighMod = with lib; types.submodule { options = { addrs = mkOption { type = with types; attrsOf str; default = { }; }; via = mkOption { type = with types; listOf str; default = [ ]; }; } // (with builtins; let value = mkOption { type = types.str; }; in listToAttrs (map (name: { inherit name value; }) [ "exchpub" "id" "noisepub" "signpub" ])); }; # Generate a deterministic IPv6 address for a 64 bit prefix # and seed string. Prefix must not contain trailing ':'. toIpv6Address = prefix64: seed: with builtins; let digest = builtins.hashString "sha256" seed; hextets = map (i: substring (4 * i) 4 digest) [ 0 1 2 3 ]; in concatStringsSep ":" ([ prefix64 ] ++ hextets); # Generate a deterministic public IPv6 addresses # for the HQ networking using a seed string. toHqPrivateAddress = toIpv6Address hqPrefix64; in { options.c3d2 = { k-ot.enable = lib.mkEnableOption '' Add k-ot user to this machine. Anyone with an SSH key listed in c3d2.users can log in as this user. ''; hq = { interface = lib.mkOption { type = with lib.types; nullOr str; default = null; example = "eth0"; description = '' Configure the given interface name with an internal IP address. ''; }; journalToMqtt = lib.mkOption { type = lib.types.bool; # broken :( default = false; }; sendmail = lib.mkOption { type = lib.types.bool; default = false; description = '' Wether to configure sendmail via msmtp. ''; }; }; nncp = { mergeSettings = lib.mkEnableOption '' Whether to merge c3d2.nncp.<…>.nncp into programs.nncp.settings. ''; neigh = lib.mkOption { type = with lib.types; attrsOf neighMod; default = { }; description = '' Attrset of NNCP neighbours for relaying packets. User endpoints go in c3d2.users. ''; }; }; sshKeys = lib.mkOption { type = with lib.types; attrsOf (listOf str); default = [ ]; }; }; config = { networking.interfaces = lib.mkIf (cfg.hq.interface != null) { "${cfg.hq.interface}".ipv6.addresses = [{ address = toHqPrivateAddress config.networking.hostName; prefixLength = 64; }]; }; programs = { nncp.settings = lib.optionalAttrs cfg.nncp.mergeSettings cfg.nncp; msmtp = lib.mkIf cfg.hq.sendmail { enable = true; accounts.default = { host = "mail.c3d2.de"; port = 587; tls = true; tls_starttls = true; auth = false; domain = "gitea.c3d2.de"; from = "mail@c3d2.de"; }; }; }; services.vector = lib.mkIf config.c3d2.hq.journalToMqtt { enable = true; journaldAccess = true; settings = { sources.journal = { type = "journald"; current_boot_only = true; }; sinks.mqtt = { inputs = [ "journal" ]; type = "mqtt"; host = "broker.serv.zentralwerk.org"; # port = 8883; user = "SECRET[mqtt.user]"; password = "SECRET[mqtt.password]"; client_id = "vector-${config.networking.hostName}"; encoding.codec = "json"; topic = "journal/{{ host }}/{{ _SYSTEMD_UNIT }}/{{ PRIORITY }}"; # tls.enabled = true; # tls.ca_file = "/etc/ssl/certs/ca-certificates.crt"; }; secret.mqtt = let catSecrets = pkgs.writeScript "cat-vector-secrets" /* bash */ '' #!${pkgs.runtimeShell} -e echo '{' COMMA=n for F in $@; do if [ $COMMA = y ]; then echo ' ,' else COMMA=y fi echo ' "'$(basename $F)'": {"value": "'$(cat $F)'", "error": null }' done echo '}' ''; in { type = "exec"; command = [ catSecrets config.sops.secrets."mqtt/user".path config.sops.secrets."mqtt/password".path ]; }; }; }; sops.secrets = lib.mkIf config.c3d2.hq.journalToMqtt { "mqtt/user" = { sopsFile = ../modules/mqtt.yaml; owner = config.systemd.services.vector.serviceConfig.User; }; "mqtt/password" = { sopsFile = ../modules/mqtt.yaml; owner = config.systemd.services.vector.serviceConfig.User; }; }; systemd.network.networks = lib.mkIf (cfg.hq.interface != null && config.networking.useNetworkd) { "40-eth0".routes = [{ routeConfig = { Gateway = "172.22.99.4"; GatewayOnLink = true; }; }]; }; users = let adminKeys = with builtins; lib.lists.flatten (attrValues cfg.sshKeys); in { users = { k-ot = lib.mkIf cfg.k-ot.enable { createHome = true; isNormalUser = true; uid = 1000; extraGroups = [ "audio" "video" "wheel" ]; # get by running mkpasswd logged in as the user hashedPassword = "$y$j9T$AoK/PRviZS4BDJ6jX/Qt6/$FDM/JfANEU7H0RAIuN0DL2hjYujVAVDdI0jgN5wGwB5"; openssh.authorizedKeys.keys = adminKeys; }; # https://github.com/NixOS/nixpkgs/blob/master/nixos/modules/profiles/installation-device.nix#L23 nixos = lib.mkIf (config.system.nixos.variant_id == "installer") { openssh.authorizedKeys.keys = adminKeys; }; root.openssh.authorizedKeys.keys = adminKeys; }; }; }; }