diff --git a/config/fudo/backplane/dns.nix b/config/fudo/backplane/dns.nix index e6dee50..068cc2f 100644 --- a/config/fudo/backplane/dns.nix +++ b/config/fudo/backplane/dns.nix @@ -82,12 +82,21 @@ in { default = 53; }; - listen-addresses = mkOption { + listen-v4-addresses = mkOption { type = with types; listOf str; - description = "IP addresses on which to listen for dns requests."; + description = "IPv4 addresses on which to listen for dns requests."; default = [ "0.0.0.0" ]; }; + listen-v6-addresses = mkOption { + type = with types; listOf str; + description = "IPv6 addresses on which to listen for dns requests."; + example = [ + "[abcd::1]" + ]; + default = []; + }; + required-services = mkOption { type = with types; listOf str; description = "A list of services required before the DNS server can start."; @@ -152,7 +161,8 @@ in { backplane-powerdns = let configDir = pkgs.writeTextDir "pdns.conf" '' - local-address=${lib.concatStringsSep ", " cfg.listen-addresses} + local-address=${lib.concatStringsSep ", " cfg.listen-v4-addresses} + local-ipv6=${lib.concatStringsSep ", " cfg.listen-v6-addresses} local-port=${toString cfg.port} launch= include-dir=${powerdns-conf-dir}/ diff --git a/config/fudo/client/dns.nix b/config/fudo/client/dns.nix index 7a9d348..a1db07e 100644 --- a/config/fudo/client/dns.nix +++ b/config/fudo/client/dns.nix @@ -86,6 +86,19 @@ in { }; }; + services.backplane-dns-client-pw-file = { + enable = true; + requiredBy = [ "backplane-dns-client.services" ]; + reloadIfChanged = true; + serviceConfig = { + Type = "oneshot"; + }; + script = '' + chmod 600 ${cfg.password-file} + chown ${cfg.user} ${cfg.password-file} + ''; + }; + services.backplane-dns-client = { enable = true; serviceConfig = { @@ -94,6 +107,7 @@ in { User = cfg.user; }; path = [ pkgs.openssh ]; + reloadIfChanged = true; script = '' ${pkgs.backplane-dns-client}/bin/backplane-dns-client ${optionalString cfg.ipv4 "-4"} ${optionalString cfg.ipv6 "-6"} ${optionalString cfg.sshfp "-f"} ${optionalString (cfg.external-interface != null) "--interface=${cfg.external-interface}"} --domain=${cfg.domain} --server=${cfg.server} --password-file=${cfg.password-file} ''; diff --git a/config/fudo/dns.nix b/config/fudo/dns.nix index 9de4805..4d04546 100644 --- a/config/fudo/dns.nix +++ b/config/fudo/dns.nix @@ -33,6 +33,18 @@ let A list of DNS SSHFP records for this host. ''; }; + + description = mkOption { + type = with types; nullOr str; + description = "Description of this host for a TXT record."; + default = null; + }; + + rp = mkOption { + type = with types; nullOr str; + description = "Responsible person."; + default = null; + }; }; }; @@ -125,9 +137,12 @@ let }; }; - hostARecords = host: data: + hostRecords = host: data: join-lines ((map (ip: "${host} IN A ${ip}") data.ip-addresses) ++ - (map (ip: "${host} IN AAAA ${ip}") data.ipv6-addresses)); + (map (ip: "${host} IN AAAA ${ip}") data.ipv6-addresses) ++ + (map (sshfp: "${host} IN SSHFP ${sshfp}") data.ssh-fingerprints) ++ + (optional (data.rp != null) "${host} IN RP ${data.rp}") ++ + (optional (data.description != null) "${host} IN TXT ${data.description}")); makeSrvRecords = protocol: type: records: join-lines (map (record: "_${type}._${protocol} IN SRV ${toString record.priority} ${toString record.weight} ${toString record.port} ${toString record.host}.") @@ -137,8 +152,6 @@ let cnameRecord = alias: host: "${alias} IN CNAME ${host}"; - hostSshFpRecords = host: data: join-lines (map (sshfp: "${host} IN SSHFP ${sshfp}") data.ssh-fingerprints); - mxRecords = mxs: concatStringsSep "\n" (map (mx: "@ IN MX 10 ${mx}.") mxs); @@ -207,8 +220,7 @@ in { ${dmarcRecord dom-cfg.dmarc-report-address} ${join-lines (mapAttrsToList makeSrvProtocolRecords dom-cfg.srv-records)} - ${join-lines (mapAttrsToList hostARecords dom-cfg.hosts)} - ${join-lines (mapAttrsToList hostSshFpRecords dom-cfg.hosts)} + ${join-lines (mapAttrsToList hostRecords dom-cfg.hosts)} ${join-lines (mapAttrsToList cnameRecord dom-cfg.aliases)} ${join-lines dom-cfg.extra-dns-records} ''; diff --git a/fudo/users.nix b/fudo/users.nix index b7c943e..07e7c63 100644 --- a/fudo/users.nix +++ b/fudo/users.nix @@ -75,7 +75,8 @@ uid = 10035; group = "selby"; common-name = "Ken Selby"; - hashed-password = "{SSHA}X8DxUcwH2Fzel5UKbGVNhC5B2vg0Prsc"; + hashed-password = "{SSHA}wUGV/9dr8inz/HyqSF/OWKxy0DCy5AI3"; + # hashed-password = "{SSHA}X8DxUcwH2Fzel5UKbGVNhC5B2vg0Prsc"; }; reaper = { diff --git a/hosts/france.nix b/hosts/france.nix index 73c6e46..911f0d1 100644 --- a/hosts/france.nix +++ b/hosts/france.nix @@ -7,7 +7,7 @@ let mail-hostname = "mail.${domain}"; host_ipv4 = "208.81.3.117"; # Use a special IP for git.fudo.org, since it needs to be SSH-able - git_ipv4 = "208.81.3.126"; + link_ipv4 = "208.81.3.126"; all-hostnames = []; acme-private-key = hostname: "/var/lib/acme/${hostname}/key.pem"; @@ -40,6 +40,7 @@ in { lxd multipath-tools nix-prefetch-docker + powerdns tshark ]; @@ -259,9 +260,18 @@ in { # TODO: not used yet fudo.acme.hostnames = all-hostnames; + fudo.client.dns = { + enable = true; + ipv4 = true; + ipv6 = true; + user = "fudo-client"; + external-interface = "extif0"; + password-file = "/srv/client/secure/client.passwd"; + }; + fudo.mail-server = import ../fudo/email.nix { inherit config; } // { enableContainer = true; - debug = true; + # debug = true; monitoring = true; hostname = mail-hostname; @@ -392,7 +402,7 @@ in { repository-dir = /srv/git/repo; state-dir = /srv/git/state; ssh = { - listen-ip = git_ipv4; + listen-ip = link_ipv4; listen-port = 2222; }; }; @@ -438,7 +448,7 @@ in { macAddress = "02:6d:e2:e1:ad:ca"; ipv4.addresses = [ { - address = git_ipv4; + address = link_ipv4; prefixLength = 28; } ]; diff --git a/hosts/france/backplane.nix b/hosts/france/backplane.nix index 8ce0ca8..0d98b60 100644 --- a/hosts/france/backplane.nix +++ b/hosts/france/backplane.nix @@ -58,8 +58,12 @@ in { databases = { backplane_dns = { access = "CONNECT"; + # entity-access = { + # "ALL TABLES IN SCHEMA public" = "SELECT"; + # }; entity-access = { - "ALL TABLES IN SCHEMA public" = "SELECT"; + "ALL TABLES IN SCHEMA public" = "SELECT,INSERT,UPDATE,DELETE"; + "ALL SEQUENCES IN SCHEMA public" = "SELECT,UPDATE"; }; }; }; @@ -70,7 +74,7 @@ in { backplane_dns = { access = "CONNECT"; entity-access = { - "ALL TABLES IN SCHEMA public" = "SELECT,INSERT,UPDATE"; + "ALL TABLES IN SCHEMA public" = "SELECT,INSERT,UPDATE,DELETE"; "ALL SEQUENCES IN SCHEMA public" = "SELECT,UPDATE"; }; }; @@ -87,8 +91,8 @@ in { backplane.dns = { enable = true; - port = 353; - listen-addresses = [ "208.81.3.117" ]; + listen-v4-addresses = [ "208.81.3.126" ]; + listen-v6-addresses = [ "[2605:e200:d200:1:6d:e2ff:fee1:adca]" ]; required-services = [ "fudo-passwords.target" ]; user = "backplane-dns"; group = "backplane-dns"; diff --git a/hosts/france/jabber.nix b/hosts/france/jabber.nix index df4c16b..b900bad 100644 --- a/hosts/france/jabber.nix +++ b/hosts/france/jabber.nix @@ -4,6 +4,9 @@ with lib; let backplane-auth = "/etc/nixos/static/backplane-auth.scm"; + host-passwd-file = "/srv/jabber/secret/hosts-passwd.scm"; + service-passwd-file = "/srv/jabber/secret/services-passwd.scm"; + cert-basedir = "/var/lib/ejabberd/certs"; target-certs = ["key" "cert" "chain" "fullchain"]; @@ -50,30 +53,67 @@ in { security.acme.certs."fudo.im".email = "admin@fudo.org"; security.acme.certs."backplane.fudo.org".email = "admin@fudo.org"; - systemd.services = { - ejabberd-generate-certs = { - enable = true; - description = "Generate required SSL certs for ejabberd."; - wantedBy = [ "ejabberd.service" ]; - after = [ - "acme-backplane.fudo.org.service" - "acme-fudo.im.service" - ]; + systemd = { + services = { + ejabberd-generate-certs = { + enable = true; + description = "Generate required SSL certs for ejabberd."; + wantedBy = [ "ejabberd.service" ]; + after = [ + "acme-backplane.fudo.org.service" + "acme-fudo.im.service" + ]; + serviceConfig = { + Type = "oneshot"; + ExecStart = "${move-server-certs ["fudo.im" "backplane.fudo.org"]}"; + RemainAfterExit = true; + ExecStop = remove-server-certs; + StandardOutput = "journal"; + }; + }; - serviceConfig = { - Type = "oneshot"; - ExecStart = "${move-server-certs ["fudo.im" "backplane.fudo.org"]}"; - RemainAfterExit = true; - ExecStop = remove-server-certs; - StandardOutput = "journal"; + ejabberd = { + requires = [ "ejabberd-generate-certs.service" ]; + environment = { + FUDO_HOST_PASSWD_FILE = host-passwd-file; + FUDO_SERVICE_PASSWD_FILE = service-passwd-file; + }; + }; + + ejabberd-hostfile-watcher = { + description = "Watch the ejabberd host file and restart if changes occur."; + serviceConfig.Type = "oneshot"; + after = [ "ejabberd.service" ]; + script = '' + SYSCTL=${pkgs.systemd}/bin/systemctl + if $SYSCTL is-active --quiet ejabberd.service; then + echo "restarting ejabberd.service because hostfile has changed." + $SYSCTL restart ejabberd.service + fi + ''; + }; + + ejabberd-servicefile-watcher = { + description = "Watch the ejabberd service file and restart if changes occur."; + serviceConfig.Type = "oneshot"; + after = [ "ejabberd.service" ]; + script = '' + SYSCTL=${pkgs.systemd}/bin/systemctl + if $SYSCTL is-active --quiet ejabberd.service; then + echo "restarting ejabberd.service because servicefile has changed." + $SYSCTL restart ejabberd.service + fi + ''; }; }; - ejabberd = { - requires = [ "ejabberd-generate-certs.service" ]; - environment = { - FUDO_HOST_PASSWD_FILE = "/srv/jabber/secret/hosts-passwd.scm"; - FUDO_SERVICE_PASSWD_FILE = "/srv/jabber/secret/services-passwd.scm"; + paths = { + ejabberd-hostfile-watcher = { + pathConfig.PathChanged = host-passwd-file; + }; + + ejabberd-servicefile-watcher = { + pathConfig.PathChanged = service-passwd-file; }; }; }; diff --git a/packages/backplane-dns.nix b/packages/backplane-dns.nix index 85287bb..10d08c2 100644 --- a/packages/backplane-dns.nix +++ b/packages/backplane-dns.nix @@ -9,8 +9,8 @@ in stdenv.mkDerivation { src = fetchgit { url = url; - rev = "543df72f3962cf91b0e0508d15cdc083a3cd7ed4"; - sha256 = "0hda1wjf9wd4rvxchdlxw0af3i2cvl5plg37ric3ckma6gfzkmm0"; + rev = "c552394e55816541a9426974c5f8e6f1f83bf195"; + sha256 = "0r61bwj5a2dvzl41cwdf2pdnhdsmp3kzfyxa5x5hsg67al6s7vi8"; fetchSubmodules = false; }; diff --git a/static/backplane-auth.scm b/static/backplane-auth.scm index e017da5..f23ee80 100644 --- a/static/backplane-auth.scm +++ b/static/backplane-auth.scm @@ -16,8 +16,8 @@ (format (current-error-port "FUDO_SERVICE_PASSWD_FILE not set~%")) (exit 1)) -(define host-regex "^host-([a-zA-Z][a-zA-Z0-9_-]+)") -(define service-regex "^service-([a-zA-Z][a-zA-Z0-9_-]+)") +(define host-regex "^host-([a-zA-Z][a-zA-Z0-9_-]+)$") +(define service-regex "^service-([a-zA-Z][a-zA-Z0-9_-]+)$") (define (make-verifier passwd-file) (let ((passwds (load passwd-file)))