diff --git a/config/fudo/backplane/dns.nix b/config/fudo/backplane/dns.nix index beeeaa3..e6dee50 100644 --- a/config/fudo/backplane/dns.nix +++ b/config/fudo/backplane/dns.nix @@ -191,17 +191,22 @@ in { }; }; - backplane-dns-config-generator = { - description = "Generate postgres configuration for backplane DNS server."; - requiredBy = [ "backplane-powerdns.service" ]; - requires = cfg.required-services; - serviceConfig.Type = "oneshot"; - restartIfChanged = true; - partOf = [ "backplane-dns.target" ]; + backplane-dns-config-generator = { + description = "Generate postgres configuration for backplane DNS server."; + requiredBy = [ "backplane-powerdns.service" ]; + requires = cfg.required-services; + serviceConfig.Type = "oneshot"; + restartIfChanged = true; + partOf = [ "backplane-dns.target" ]; - # This builds the config in a bash script, to avoid storing the password - # in the nix store at any point - script = '' + preStart = '' + mkdir -p ${powerdns-conf-dir} + chown backplane-powerdns:backplane-powerdns ${powerdns-conf-dir} + ''; + + # This builds the config in a bash script, to avoid storing the password + # in the nix store at any point + script = '' if [ ! -d ${powerdns-conf-dir} ]; then mkdir ${powerdns-conf-dir} fi @@ -231,40 +236,40 @@ in { exit 0 ''; + }; + + backplane-dns = { + description = "Fudo DNS Backplane Server"; + restartIfChanged = true; + + serviceConfig = { + ExecStartPre = "${pkgs.lispPackages.quicklisp}/bin/quicklisp init"; + ExecStart = "${pkgs.sbcl}/bin/sbcl --load ${launchScript}"; + Restart = "on-failure"; + PIDFile = "/run/backplane-dns.$USERNAME.pid"; + User = cfg.user; + Group = cfg.group; }; - backplane-dns = { - description = "Fudo DNS Backplane Server"; - restartIfChanged = true; + environment = { + LD_LIBRARY_PATH = "${pkgs.openssl_1_1.out}/lib"; - serviceConfig = { - ExecStartPre = "${pkgs.lispPackages.quicklisp}/bin/quicklisp init"; - ExecStart = "${pkgs.sbcl}/bin/sbcl --load ${launchScript}"; - Restart = "on-failure"; - PIDFile = "/run/backplane-dns.$USERNAME.pid"; - User = cfg.user; - Group = cfg.group; - }; + FUDO_DNS_BACKPLANE_XMPP_HOSTNAME = cfg.backplane.host; + FUDO_DNS_BACKPLANE_XMPP_USERNAME = cfg.backplane.role; + FUDO_DNS_BACKPLANE_XMPP_PASSWORD_FILE = cfg.backplane.password-file; + FUDO_DNS_BACKPLANE_DATABASE_HOSTNAME = cfg.backplane.database.host; + FUDO_DNS_BACKPLANE_DATABASE_NAME = cfg.backplane.database.database; + FUDO_DNS_BACKPLANE_DATABASE_USERNAME = cfg.backplane.database.username; + FUDO_DNS_BACKPLANE_DATABASE_PASSWORD_FILE = cfg.backplane.database.password-file; - environment = { - LD_LIBRARY_PATH = "${pkgs.openssl_1_1.out}/lib"; - - FUDO_DNS_BACKPLANE_XMPP_HOSTNAME = cfg.backplane.host; - FUDO_DNS_BACKPLANE_XMPP_USERNAME = cfg.backplane.role; - FUDO_DNS_BACKPLANE_XMPP_PASSWORD_FILE = cfg.backplane.password-file; - FUDO_DNS_BACKPLANE_DATABASE_HOSTNAME = cfg.backplane.database.host; - FUDO_DNS_BACKPLANE_DATABASE_NAME = cfg.backplane.database.database; - FUDO_DNS_BACKPLANE_DATABASE_USERNAME = cfg.backplane.database.username; - FUDO_DNS_BACKPLANE_DATABASE_PASSWORD_FILE = cfg.backplane.database.password-file; - - CL_SOURCE_REGISTRY = lib.concatStringsSep ":" (map (pkg: "${pkg}//") - (lisp-libs ++ [pkgs.backplane-dns])); - }; - - requires = cfg.required-services; - partOf = [ "backplane-dns.target" ]; - wantedBy = [ "multi-user.target" ]; + CL_SOURCE_REGISTRY = lib.concatStringsSep ":" (map (pkg: "${pkg}//") + (lisp-libs ++ [pkgs.backplane-dns])); }; + + requires = cfg.required-services; + partOf = [ "backplane-dns.target" ]; + wantedBy = [ "multi-user.target" ]; + }; }; }; }; diff --git a/config/fudo/password.nix b/config/fudo/password.nix index 8381df1..2322d9e 100644 --- a/config/fudo/password.nix +++ b/config/fudo/password.nix @@ -31,7 +31,15 @@ let }; generate-passwd-file = file: user: group: pkgs.writeShellScriptBin "generate-passwd-file.sh" '' + mkdir -p $(dirname ${file}) + if touch ${file}; then + chown ${user}${optionalString (group != null) ":${group}"} ${file} + if [ $? -ne 0 ]; then + rm ${file} + echo "failed to set permissions on ${file}" + exit 4 + fi ${pkgs.pwgen}/bin/pwgen 30 1 > ${file} else echo "cannot write to ${file}" @@ -43,14 +51,6 @@ let exit 3 fi - chown ${user}${optionalString (group != null) ":${group}"} ${file} - - if [ $? -ne 0 ]; then - rm ${file} - echo "failed to set permissions on ${file}" - exit 4 - fi - ${if (group != null) then "chmod 640 ${file}" else @@ -90,10 +90,12 @@ in { systemd.services = fold (a: b: a // b) {} (mapAttrsToList (name: opts: { "file-generator-${name}" = { + enable = true; partOf = [ "fudo-passwords.target" ]; serviceConfig.Type = "oneshot"; description = "Generate password file for ${name}."; script = "${generate-passwd-file opts.file opts.user opts.group}/bin/generate-passwd-file.sh"; + reloadIfChanged = true; }; "file-generator-watcher-${name}" = mkIf (! (opts.restart-services == [])) { diff --git a/config/fudo/webmail.nix b/config/fudo/webmail.nix index cf93502..9c8a5cd 100644 --- a/config/fudo/webmail.nix +++ b/config/fudo/webmail.nix @@ -329,6 +329,7 @@ in { wantedBy = [ "multi-user.target" ]; description = "Change ownership of the phpfpm socket for webmail once it's started."; requires = [ "phpfpm-webmail.service" ]; + after = [ "phpfpm.target" ]; serviceConfig = { ExecStart = '' ${pkgs.coreutils}/bin/chown ${webmail-user}:${webmail-group} ${config.services.phpfpm.pools.webmail.socket} @@ -337,8 +338,10 @@ in { }; nginx = { - requires = [ "webmail-init.service" ]; - wantedBy = [ "phpfpm-webmail-socket-perm.service" ]; + requires = [ + "webmail-init.service" + "phpfpm-webmail-socket-perm.service" + ]; }; }; }; diff --git a/defaults.nix b/defaults.nix index 89e36e1..daa666a 100644 --- a/defaults.nix +++ b/defaults.nix @@ -222,4 +222,19 @@ }; }; + systemd.services.fudo-environment-init = { + enable = true; + description = "Fudo common settings."; + wantedBy = [ "default.target" ]; + + # Careful, this WILL run many times + script = '' + # Create a directory for system user homedirs if it doesn't already exist + if [ ! -d /var/home ]; then + mkdir -p /var/home + chmod +x /var/home + fi + ''; + }; + } diff --git a/fudo/selby.ca.nix b/fudo/selby.ca.nix new file mode 100644 index 0000000..8d62144 --- /dev/null +++ b/fudo/selby.ca.nix @@ -0,0 +1,81 @@ +{ host_ipv4, config }: + +{ + dnssec = true; + + mx = ["mail.fudo.org"]; + + hosts = { + forum = { + ip-addresses = [ "208.81.3.117" ]; + }; + }; + + default-host = "208.81.3.117"; + + srv-records = { + tcp = { + domain = [{ + host = "ns1.fudo.org"; + port = "53"; + }]; + ssh = [{ + host = "france.fudo.org"; + port = 22; + }]; + submission = [{ + host = "mail.fudo.org"; + port = 587; + }]; + kerberos = [{ + host = "auth.fudo.org"; + port = 88; + }]; + imaps = [{ + host = "mail.fudo.org"; + port = 993; + }]; + pop3s = [{ + host = "mail.fudo.org"; + port = 995; + }]; + http = [{ + host = "forum.selby.ca"; + port = 80; + }]; + https = [{ + host = "forum.selby.ca"; + port = 80; + }]; + }; + udp = { + domain = [{ + host = "auth.fudo.org"; + port = 53; + }]; + kerberos = [{ + host = "auth.fudo.org"; + port = 88; + }]; + }; + }; + + aliases = { + pop = "mail.fudo.org."; + smtp = "mail.fudo.org."; + imap = "mail.fudo.org."; + mail = "mail.fudo.org."; + ns1 = "ns1.fudo.org."; + ns2 = "ns2.fudo.org."; + webmail = "france.fudo.org."; + forum = "frankfurt.fudo.org."; + }; + + extra-dns-records = [ + ''_kerberos IN TXT "FUDO.ORG"'' + ''@ IN TXT "v=spf1 mx ip4:${host_ipv4}/29 -all"'' + ''@ IN SPF "v=spf1 mx ip4:${host_ipv4}/29 -all"'' + ]; + + dmarc-report-address = "dmarc-report@selby.ca"; +} diff --git a/hosts/france.nix b/hosts/france.nix index 72f8aec..73c6e46 100644 --- a/hosts/france.nix +++ b/hosts/france.nix @@ -32,6 +32,7 @@ in { ../hardware-configuration.nix ../defaults.nix ./france/jabber.nix + ./france/backplane.nix ]; environment.systemPackages = with pkgs; [ @@ -42,15 +43,6 @@ in { tshark ]; - # services.openssh = { - # listenAddresses = [ - # { - # addr = host_ipv4; - # port = 22; - # } - # ]; - # }; - fudo.common = { # Sets some server-common settings. See /etc/nixos/fudo/profiles/... profile = "server"; @@ -122,44 +114,94 @@ in { users = { fudo_git = { - password = fileContents "/srv/git/secure/db.passwd"; + password-file = "/srv/git/secure/db.passwd"; databases = { - fudo_git = "ALL PRIVILEGES"; + fudo_git = { + access = "CONNECT"; + entity-access = { + "ALL TABLES IN SCHEMA public" = "SELECT,INSERT,UPDATE,DELETE"; + "ALL SEQUENCES IN SCHEMA public" = "SELECT,UPDATE"; + }; + }; }; }; grafana = { - password = fileContents "/srv/grafana/secure/db.passwd"; + password-file = "/srv/grafana/secure/db.passwd"; databases = { - grafana = "ALL PRIVILEGES"; + grafana = { + access = "CONNECT"; + entity-access = { + "ALL TABLES IN SCHEMA public" = "SELECT,INSERT,UPDATE,DELETE"; + "ALL SEQUENCES IN SCHEMA public" = "SELECT,UPDATE"; + }; + }; }; }; mattermost = { - password = fileContents "/srv/mattermost/secure/db.passwd"; + password-file = "/srv/mattermost/secure/db.passwd"; databases = { - mattermost = "ALL PRIVILEGES"; + mattermost = { + access = "CONNECT"; + entity-access = { + "ALL TABLES IN SCHEMA public" = "SELECT,INSERT,UPDATE,DELETE"; + "ALL SEQUENCES IN SCHEMA public" = "SELECT,UPDATE"; + }; + }; }; }; webmail = { - password = fileContents "/srv/webmail/secure/db.passwd"; + password-file = "/srv/webmail/secure/db.passwd"; databases = { - webmail = "ALL PRIVILEGES"; + webmail = { + access = "CONNECT"; + entity-access = { + "ALL TABLES IN SCHEMA public" = "SELECT,INSERT,UPDATE,DELETE"; + "ALL SEQUENCES IN SCHEMA public" = "SELECT,UPDATE"; + }; + }; }; }; niten = {}; }; local-users = [ + "niten" "fudo_git" ]; databases = { - fudo_git = ["niten"]; - grafana = ["niten"]; - mattermost = ["niten"]; - webmail = ["niten"]; + fudo_git = { + users = ["niten"]; + }; + grafana = { + users = ["niten"]; + }; + mattermost = { + users = ["niten"]; + }; + webmail = { + users = ["niten"]; + }; }; }; + # fudo.dns = { + # enable = true; + + # dns-hosts = { + # "ns1.fudo.org" = host_ipv4; + # "ns2.fudo.org" = ""; + # }; + + # listen-ips = [host_ipv4]; + + # domains = { + # "selby.ca" = import ../fudo.org/selby.ca.nix { + # inherit host_ipv4 config; + # }; + # }; + # }; + # Not all users need access to france; don't allow LDAP-user access. fudo.authentication.enable = false; diff --git a/hosts/france/backplane.nix b/hosts/france/backplane.nix new file mode 100644 index 0000000..8ce0ca8 --- /dev/null +++ b/hosts/france/backplane.nix @@ -0,0 +1,117 @@ +{ pkgs, lib, config, ... }: + +with lib; +let + +in { + config = { + users = { + users = { + backplane-powerdns = { + isSystemUser = true; + }; + backplane-dns = { + isSystemUser = true; + }; + }; + + groups = { + backplane-powerdns = { + members = [ "backplane-powerdns" ]; + }; + backplane-dns = { + members = [ "backplane-dns" ]; + }; + }; + }; + + fudo = { + password.file-generator = { + dns_backplane_powerdns = { + file = "/srv/backplane/dns/secure/db_powerdns.passwd"; + user = config.services.postgresql.superUser; + group = "backplane-powerdns"; + restart-services = [ + "backplane-dns-config-generator.service" + "postgresql-password-setter.service" + "backplane-powerdns.service" + ]; + }; + dns_backplane_database = { + file = "/srv/backplane/dns/secure/db_backplane.passwd"; + user = config.services.postgresql.superUser; + group = "backplane-dns"; + restart-services = [ + "backplane-dns.service" + "postgresql-password-setter.service" + ]; + }; + }; + + postgresql = { + enable = true; + required-services = [ "fudo-passwords.target" ]; + + users = { + backplane_powerdns = { + password-file = "/srv/backplane/dns/secure/db_powerdns.passwd"; + databases = { + backplane_dns = { + access = "CONNECT"; + entity-access = { + "ALL TABLES IN SCHEMA public" = "SELECT"; + }; + }; + }; + }; + backplane_dns = { + password-file = "/srv/backplane/dns/secure/db_backplane.passwd"; + databases = { + backplane_dns = { + access = "CONNECT"; + entity-access = { + "ALL TABLES IN SCHEMA public" = "SELECT,INSERT,UPDATE"; + "ALL SEQUENCES IN SCHEMA public" = "SELECT,UPDATE"; + }; + }; + }; + }; + }; + + databases = { + backplane_dns = { + users = ["niten"]; + }; + }; + }; + + backplane.dns = { + enable = true; + port = 353; + listen-addresses = [ "208.81.3.117" ]; + required-services = [ "fudo-passwords.target" ]; + user = "backplane-dns"; + group = "backplane-dns"; + database = { + username = "backplane_powerdns"; + database = "backplane_dns"; + # Uses an IP to avoid cyclical dependency...not really relevant, but + # whatever + host = "127.0.0.1"; + password-file = "/srv/backplane/dns/secure/db_powerdns.passwd"; + }; + backplane = { + host = "backplane.fudo.org"; + role = "service-dns"; + password-file = "/srv/backplane/dns/secure/backplane.passwd"; + database = { + username = "backplane_dns"; + database = "backplane_dns"; + host = "127.0.0.1"; + password-file = "/srv/backplane/dns/secure/db_backplane.passwd"; + }; + }; + }; + }; + }; +} diff --git a/packages/backplane-dns.nix b/packages/backplane-dns.nix index 0f437e6..85287bb 100644 --- a/packages/backplane-dns.nix +++ b/packages/backplane-dns.nix @@ -9,8 +9,8 @@ in stdenv.mkDerivation { src = fetchgit { url = url; - rev = "bfad36c9d223c7c8949fab50424c32a11164cd3a"; - sha256 = "0s8g5cm9mdjr9wb8w6a8lc1dv5cg85hxp8bdcgr1xd6hs4fnr745"; + rev = "543df72f3962cf91b0e0508d15cdc083a3cd7ed4"; + sha256 = "0hda1wjf9wd4rvxchdlxw0af3i2cvl5plg37ric3ckma6gfzkmm0"; fetchSubmodules = false; }; diff --git a/static/backplane-auth.scm b/static/backplane-auth.scm index f23ee80..e017da5 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)))