From d429825817ad5881950eae0525c524b04bdab54f Mon Sep 17 00:00:00 2001 From: "root@procul" Date: Thu, 25 Jun 2020 22:38:50 -0500 Subject: [PATCH] Informis Checkin --- config/fudo/acme-for-hostname.nix | 44 +++--- config/fudo/dns.nix | 218 ++++++++++++++++++++++++++++++ config/fudo/mail.nix | 19 +++ config/fudo/mail/dovecot.nix | 133 +++++++++++------- config/fudo/mail/postfix.nix | 38 +++--- config/local.nix | 1 + defaults.nix | 1 + fudo/profiles/server.nix | 2 + fudo/sites/joes.nix | 27 +--- hosts/procul.nix | 218 +++++++++++++++++++++++++++--- informis/informis.land.nix | 98 ++++++++++++++ informis/users.nix | 14 ++ 12 files changed, 688 insertions(+), 125 deletions(-) create mode 100644 config/fudo/dns.nix create mode 100644 informis/informis.land.nix create mode 100644 informis/users.nix diff --git a/config/fudo/acme-for-hostname.nix b/config/fudo/acme-for-hostname.nix index 4dd5f2e..0451170 100644 --- a/config/fudo/acme-for-hostname.nix +++ b/config/fudo/acme-for-hostname.nix @@ -6,26 +6,28 @@ with lib; let cfg = config.fudo.acme; - wwwRoot = hostname: - pkgs.writeTextFile { - name = "index.html"; + # wwwRoot = hostname: + # pkgs.writeTextFile { + # name = "index.html"; - text = '' - - - ${hostname} - - -

${hostname} - - - ''; - destination = "/www"; - }; + # text = '' + # + # + # ${hostname} + # + # + #

${hostname} + # + # + # ''; + # destination = "/www"; + # }; in { options.fudo.acme = { + enable = mkEnableOption "Fetch ACME certs for supplied local hostnames."; + hostnames = mkOption { type = with types; listOf str; description = "A list of hostnames mapping to this host, for which to acquire SSL certificates."; @@ -35,9 +37,15 @@ in { "alt.hostname.com" ]; }; + + admin-address = mkOption { + type = types.str; + description = "The admin address in charge of these addresses."; + default = "admin@fudo.org"; + }; }; - config = { + config = mkIf cfg.enable { services.nginx = { enable = true; @@ -49,13 +57,13 @@ in { { enableACME = true; forceSSL = true; - root = (wwwRoot hostname) + ("/" + "www"); + # root = (wwwRoot hostname) + ("/" + "www"); }) cfg.hostnames); }; security.acme.certs = listToAttrs - (map (hostname: nameValuePair hostname { email = "admin@fudo.org"; }) + (map (hostname: nameValuePair hostname { email = cfg.admin-address; }) cfg.hostnames); }; } diff --git a/config/fudo/dns.nix b/config/fudo/dns.nix new file mode 100644 index 0000000..9de4805 --- /dev/null +++ b/config/fudo/dns.nix @@ -0,0 +1,218 @@ +{ lib, config, pkgs, ... }: + +with lib; + +let + cfg = config.fudo.dns; + + ip = import ../../lib/ip.nix { lib = lib; }; + + join-lines = concatStringsSep "\n"; + + hostOpts = { host, ...}: { + options = { + ip-addresses = mkOption { + type = with types; listOf str; + description = '' + A list of IPv4 addresses assigned to this host. + ''; + default = []; + }; + + ipv6-addresses = mkOption { + type = with types; listOf str; + description = '' + A list of IPv6 addresses assigned to this host. + ''; + default = []; + }; + + ssh-fingerprints = mkOption { + type = with types; listOf str; + description = '' + A list of DNS SSHFP records for this host. + ''; + }; + }; + }; + + srvRecordOpts = with types; { + options = { + weight = mkOption { + type = int; + description = "Weight relative to other records."; + default = 1; + }; + + priority = mkOption { + type = int; + description = "Priority to give this record."; + default = 0; + }; + + port = mkOption { + type = port; + description = "Port to use while connecting to this service."; + }; + + host = mkOption { + type = str; + description = "Host that provides this service."; + example = "my-host.my-domain.com"; + }; + }; + }; + + domainOpts = { domain, ... }: with types; { + options = { + hosts = mkOption { + type = loaOf (submodule hostOpts); + default = {}; + description = "A map of hostname to { host_attributes }."; + }; + + dnssec = mkEnableOption "Enable DNSSEC security for this zone."; + + mx = mkOption { + type = listOf str; + description = "A list of mail servers serving this domain."; + default = []; + }; + + srv-records = mkOption { + type = attrsOf (attrsOf (listOf (submodule srvRecordOpts))); + description = "Map of traffic type to srv records."; + default = {}; + example = { + tcp = { + kerberos = { + port = 88; + host = "auth-host.my-domain.com"; + }; + }; + }; + }; + + aliases = mkOption { + type = loaOf str; + default = {}; + description = "A mapping of host-alias => hostnames to add to DNS."; + example = { + "music" = "host.dom.com."; + "mail" = "hostname"; + }; + }; + + extra-dns-records = mkOption { + type = listOf str; + description = "Records to be inserted verbatim into the DNS zone."; + example = ["some-host IN CNAME base-host"]; + default = []; + }; + + dmarc-report-address = mkOption { + type = nullOr str; + description = "The email to use to recieve DMARC reports, if any."; + example = "admin-user@domain.com"; + default = null; + }; + + default-host = mkOption { + type = nullOr str; + description = "IP of the host which will act as the default server for this domain, if any."; + default = null; + }; + }; + }; + + hostARecords = host: data: + join-lines ((map (ip: "${host} IN A ${ip}") data.ip-addresses) ++ + (map (ip: "${host} IN AAAA ${ip}") data.ipv6-addresses)); + + makeSrvRecords = protocol: type: records: + join-lines (map (record: "_${type}._${protocol} IN SRV ${toString record.priority} ${toString record.weight} ${toString record.port} ${toString record.host}.") + records); + + makeSrvProtocolRecords = protocol: types: join-lines (mapAttrsToList (makeSrvRecords protocol) types); + + 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); + + dmarcRecord = dmarc-email: + optionalString (dmarc-email != null) + ''_dmarc IN TXT "v=DMARC1;p=quarantine;sp=quarantine;rua=mailto:${dmarc-email};"''; + + nsRecords = ns-hosts: + join-lines ((mapAttrsToList (host: _: "@ IN NS ${host}.") ns-hosts) ++ + (mapAttrsToList (host: ip: "${host} IN A ${ip}") ns-hosts)); + +in { + + options.fudo.dns = with types; { + enable = mkEnableOption "Enable master DNS services."; + + # FIXME: This should allow for AAAA addresses too... + dns-hosts = mkOption { + type = loaOf str; + description = "Map of domain nameserver FQDNs to IP."; + example = { "ns1.domain.com" = "1.1.1.1"; }; + }; + + domains = mkOption { + type = loaOf (submodule domainOpts); + default = {}; + description = "A map of domain to domain options."; + }; + + listen-ips = mkOption { + type = listOf str; + description = "A list of IPs on which to listen for DNS queries."; + example = ["1.2.3.4"]; + }; + }; + + config = mkIf cfg.enable { + services.nsd = { + enable = true; + identity = "procul.informis.land"; + interfaces = cfg.listen-ips; + zones = mapAttrs' (dom: dom-cfg: + nameValuePair "${dom}." { + dnssec = dom-cfg.dnssec; + + data = '' + $ORIGIN ${dom}. + $TTL 12h + + @ IN SOA ns1.${dom}. hostmaster.${dom}. ( + ${toString builtins.currentTime} + 5m + 2m + 6w + 5m) + + ${optionalString (dom-cfg.default-host != null) "@ IN A ${dom-cfg.default-host}"} + + ${mxRecords dom-cfg.mx} + + $TTL 6h + + ${nsRecords cfg.dns-hosts} + + ${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 cnameRecord dom-cfg.aliases)} + ${join-lines dom-cfg.extra-dns-records} + ''; + }) cfg.domains; + }; + }; +} diff --git a/config/fudo/mail.nix b/config/fudo/mail.nix index 7b664a8..ba350fd 100644 --- a/config/fudo/mail.nix +++ b/config/fudo/mail.nix @@ -104,6 +104,7 @@ in { user-aliases = mkOption { type = with types; loaOf(listOf str); description = "A map of real user to list of aliases."; + default = {}; example = { someuser = ["alias0" "alias1"]; }; @@ -167,4 +168,22 @@ in { ./mail/rspamd.nix ./mail/clamav.nix ]; + + config = mkIf cfg.enable { + users = { + users = { + mailuser = { + isSystemUser = true; + uid = cfg.mail-user-id; + group = "mailgroup"; + }; + }; + + groups = { + mailgroup = { + members = ["mailuser"]; + }; + }; + }; + }; } diff --git a/config/fudo/mail/dovecot.nix b/config/fudo/mail/dovecot.nix index 6c5d4fd..9d8f1cf 100644 --- a/config/fudo/mail/dovecot.nix +++ b/config/fudo/mail/dovecot.nix @@ -23,61 +23,86 @@ let ''; }; - ldap-conf = filename: uris: - pkgs.writeText filename '' - uris = ${concatStringsSep " " uris} + ldap-conf = filename: config: + let + ssl-config = if config.ca == null then '' + tls = no + tls_require_cert = try + '' else '' + tls_ca_cert_file = ${config.ca} + tls = yes + tls_require_cert = try + ''; + + in + pkgs.writeText filename '' + uris = ${concatStringsSep " " config.server-urls} ldap_version = 3 - dn = ${cfg.dovecot.ldap-reader-dn} - dnpass = ${cfg.dovecot.ldap-reader-passwd} + dn = ${config.reader-dn} + dnpass = ${config.reader-passwd} auth_bind = yes auth_bind_userdn = uid=%u,ou=members,dc=fudo,dc=org base = dc=fudo,dc=org - # tls_ca_cert_file = ${cfg.dovecot.ldap-ca} - # FIXME: turn back on when certs work - tls = no - tls_require_cert = try + ${ssl-config} ''; - dovecot-user = config.services.dovecot2.user; + ldap-passwd-entry = ldap-config: '' + passdb { + driver = ldap + args = ${ldap-conf "ldap-passdb.conf" ldap-config} + } + ''; -in { - options.fudo.mail-server.dovecot = { - ssl-private-key = mkOption { - type = types.str; - description = "Location of the server SSL private key."; - }; - - ssl-certificate = mkOption { - type = types.str; - description = "Location of the server SSL certificate."; - }; - - ldap-ca = mkOption { - type = types.str; + ldapOpts = with types; { + ca = mkOption { + type = str; description = "The path to the CA cert used to sign the LDAP server certificate."; }; - ldap-urls = mkOption { - type = with types; listOf str; - description = "The urls of LDAP servers."; + server-urls = mkOption { + type = listOf str; + description = "A list of LDAP server URLs used for authentication."; }; - ldap-reader-dn = mkOption { - type = types.str; + reader-dn = mkOption { + type = str; description = '' DN to use for reading user information. Needs access to homeDirectory, uidNumber, gidNumber, and uid, but not password attributes. ''; }; - ldap-reader-passwd = mkOption { - type = types.str; + reader-pw = mkOption { + type = str; description = '' Password for the user specified in ldap-reader-dn. ''; }; }; + dovecot-user = config.services.dovecot2.user; + +in { + options.fudo.mail-server.dovecot = with types; { + ssl-private-key = mkOption { + type = str; + description = "Location of the server SSL private key."; + }; + + ssl-certificate = mkOption { + type = str; + description = "Location of the server SSL certificate."; + }; + + ldap = mkOption { + type = nullOr (submodule ldapOpts); + default = null; + description = '' + LDAP auth server configuration. If omitted, the server will use local authentication. + ''; + }; + }; + config = mkIf cfg.enable { services.prometheus.exporters.dovecot = mkIf cfg.monitoring { @@ -93,8 +118,7 @@ in { enableImap = true; enableLmtp = true; enablePop3 = true; - enablePAM = false; - + enablePAM = cfg.dovecot.ldap == null; createMailUser = true; @@ -124,14 +148,16 @@ in { extraConfig = '' #Extra Config - # The prometheus exporter still expects an older style of metrics - mail_plugins = $mail_plugins old_stats - service old-stats { - unix_listener old-stats { - user = dovecot-exporter - group = dovecot-exporter + ${optionalString cfg.monitoring '' + # The prometheus exporter still expects an older style of metrics + mail_plugins = $mail_plugins old_stats + service old-stats { + unix_listener old-stats { + user = dovecot-exporter + group = dovecot-exporter + } } - } + ''} ${lib.optionalString cfg.debug '' mail_debug = yes @@ -170,15 +196,15 @@ in { } # Drop privs, since all mail is owned by one user - user = ${cfg.mail-user} - group = ${cfg.mail-group} + # user = ${cfg.mail-user} + # group = ${cfg.mail-group} + user = root } auth_mechanisms = login plain - passdb { - driver = ldap - args = ${ldap-conf "ldap-passdb.conf" cfg.dovecot.ldap-urls} - } + + ${optionalString (cfg.dovecot.ldap != null) + (ldap-conf cfg.dovecot.ldap)} userdb { driver = static args = uid=${toString cfg.mail-user-id} home=${cfg.mail-directory}/%u @@ -189,8 +215,18 @@ in { unix_listener auth { mode = 0660 user = "${config.services.postfix.user}" - group = ${config.services.postfix.group} + group = ${cfg.mail-group} } + + unix_listener auth-userdb { + mode = 0660 + user = "${config.services.postfix.user}" + group = ${cfg.mail-group} + } + } + + service auth-worker { + user = root } namespace inbox { @@ -236,7 +272,8 @@ in { done chown -R '${dovecot-user}:${cfg.mail-group}' '${state-directory}/imap_sieve' - chown ${cfg.mail-user}:${cfg.mail-group} ${cfg.mail-directory} + chown '${cfg.mail-user}:${cfg.mail-group}' ${cfg.mail-directory} + chmod g+w ${cfg.mail-directory} ''; }; } diff --git a/config/fudo/mail/postfix.nix b/config/fudo/mail/postfix.nix index 776c584..d05bf6d 100644 --- a/config/fudo/mail/postfix.nix +++ b/config/fudo/mail/postfix.nix @@ -6,6 +6,14 @@ let cfg = config.fudo.mail-server; + # The final newline is important + write-entries = filename: entries: + let + entries-string = (concatStringsSep "\n" entries); + in builtins.toFile filename '' + ${entries-string} + ''; + make-user-aliases = entries: concatStringsSep "\n" (mapAttrsToList (user: aliases: @@ -39,25 +47,22 @@ let /^User-Agent:/ IGNORE /^X-Enigmail:/ IGNORE ''); - blacklist-postfix-entry = sender: "${sender} REJECT"; - blacklist-postfix-file = entries: - concatStringsSep "\n" (map blacklist-postfix-entry entries); - sender-blacklist-file = builtins.toFile "reject_senders" - (blacklist-postfix-file cfg.sender-blacklist); - recipient-blacklist-file = builtins.toFile "reject_recipients" - (blacklist-postfix-file cfg.recipient-blacklist); + blacklist-postfix-file = filename: entries: + write-entries filename entries; + sender-blacklist-file = blacklist-postfix-file "reject_senders" + (map blacklist-postfix-entry cfg.sender-blacklist); + recipient-blacklist-file = blacklist-postfix-file "reject_recipients" + (map blacklist-postfix-entry cfg.recipient-blacklist); # A list of domains for which we accept mail - virtual-mailbox-map-file = builtins.toFile "virtual_mailbox_map" - (concatStringsSep "\n" - (map (domain: "@${domain} OK") (cfg.local-domains ++ [cfg.domain]))); + virtual-mailbox-map-file = write-entries "virtual_mailbox_map" + (map (domain: "@${domain} OK") (cfg.local-domains ++ [cfg.domain])); sender-login-map-file = let escapeDot = (str: replaceStrings ["."] ["\\."] str); - in builtins.toFile "sender_login_maps" - (concatStringsSep "\n" - (map (domain: "/^(.*)@${escapeDot domain}$/ \${1}") (cfg.local-domains ++ [cfg.domain]))); + in write-entries "sender_login_maps" + (map (domain: "/^(.*)@${escapeDot domain}$/ \${1}") (cfg.local-domains ++ [cfg.domain])); mapped-file = name: "hash:/var/lib/postfix/conf/${name}"; @@ -106,9 +111,8 @@ in { origin = cfg.domain; hostname = cfg.hostname; destination = ["localhost" "localhost.localdomain"]; - # destination = ["localhost" "localhost.localdomain"] ++ - # (map (domain: "localhost.${domain}") cfg.local-domains) ++ - # cfg.local-domains; + # destination = ["localhost" "localhost.localdomain" cfg.hostname] ++ + # cfg.local-domains;; enableHeaderChecks = true; enableSmtp = true; @@ -133,7 +137,7 @@ in { sslKey = cfg.postfix.ssl-private-key; config = { - virtual_mailbox_domains = builtins.toFile "domain-list" (concatStringsSep "\n" cfg.local-domains); + virtual_mailbox_domains = cfg.local-domains ++ [cfg.domain]; # virtual_mailbox_base = "${cfg.mail-directory}/"; virtual_mailbox_maps = mapped-file "virtual_mailbox_map"; diff --git a/config/local.nix b/config/local.nix index 0cc9309..31d794c 100644 --- a/config/local.nix +++ b/config/local.nix @@ -7,6 +7,7 @@ with lib; ./fudo/authentication.nix ./fudo/chat.nix ./fudo/common.nix + ./fudo/dns.nix ./fudo/git.nix ./fudo/grafana.nix ./fudo/kdc.nix diff --git a/defaults.nix b/defaults.nix index 030d694..5c4242c 100644 --- a/defaults.nix +++ b/defaults.nix @@ -54,6 +54,7 @@ lshw mkpasswd ncurses5 + nix-index nmap oidentd openldap diff --git a/fudo/profiles/server.nix b/fudo/profiles/server.nix index 1011659..7e1b7c3 100644 --- a/fudo/profiles/server.nix +++ b/fudo/profiles/server.nix @@ -51,6 +51,8 @@ in { config = mkIf (config.fudo.common.profile == "server") { environment = { systemPackages = with pkgs; [ + ldns + ldns.examples test-config reboot-if-necessary ]; diff --git a/fudo/sites/joes.nix b/fudo/sites/joes.nix index ad2d576..8f541ed 100644 --- a/fudo/sites/joes.nix +++ b/fudo/sites/joes.nix @@ -2,12 +2,7 @@ with lib; let - admin = "admin@fudo.org"; - - nameservers = [ - "1.1.1.1" - "2606:4700:4700::1111" - ]; + admin = "admin@informis.land"; hostname = config.networking.hostName; @@ -22,31 +17,23 @@ in { }; networking = { - domain = "fudo.org"; - search = ["fudo.org"]; + domain = "informis.land"; + search = ["informis.land" "fudo.org"]; firewall.enable = false; - nameservers = nameservers; defaultGateway = gateway; # defaultGateway6 = gateway6; }; fudo.node-exporter = { - enable = true; + enable = false; hostname = hostname; }; - security.acme.certs.${hostname} = { - email = "admin@fudo.org"; - # plugins = [ - # "fullchain.pem" - # "full.pem" - # "key.pem" - # "chain.pem" - # "cert.pem" - # ]; + security.acme.certs."${hostname}.informis.land" = { + email = "admin@informis.land"; }; - + services.nginx = { enable = true; recommendedGzipSettings = true; diff --git a/hosts/procul.nix b/hosts/procul.nix index ef15a4f..5237977 100644 --- a/hosts/procul.nix +++ b/hosts/procul.nix @@ -3,8 +3,10 @@ with lib; let hostname = "procul"; + domain = "informis.land"; mail-hostname = hostname; host_ipv4 = "172.86.179.18"; + host-fqdn = "${hostname}.${domain}"; all-hostnames = []; acme-private-key = hostname: "/var/lib/acme/${hostname}/key.pem"; @@ -25,37 +27,20 @@ in { ../hardware-configuration.nix ../defaults.nix + + ../informis/users.nix ]; - fudo.common = { - # Sets some server-common settings. See /etc/nixos/fudo/profiles/... - profile = "server"; - - # Sets some common site-specific settings: gateway, monitoring, etc. See /etc/nixos/fudo/sites/... - site = "joes"; - - local-networks = [ - "172.86.179.18/29" - "208.81.1.128/28" - "208.81.3.112/28" - "172.17.0.0/16" - "127.0.0.0/8" - ]; - }; - environment.systemPackages = with pkgs; [ multipath-tools ]; - # Not all users need access to procul; don't allow LDAP-user access. - fudo.authentication.enable = false; - - # TODO: not used yet - fudo.acme.hostnames = all-hostnames; - networking = { hostName = hostname; + # provided by secure-dns-proxy + nameservers = [ "127.0.0.1" ]; + dhcpcd.enable = false; useDHCP = false; @@ -86,4 +71,193 @@ in { }; hardware.bluetooth.enable = false; + + users = { + users = { + gituser = { + isSystemUser = true; + group = "nogroup"; + }; + }; + }; + + fudo = { + + common = { + # Sets some server-common settings. See /etc/nixos/fudo/profiles/... + profile = "server"; + + # Sets some common site-specific settings: gateway, monitoring, etc. See /etc/nixos/fudo/sites/... + site = "joes"; + + domain = domain; + + admin-email = "admin@${domain}"; + + local-networks = [ + "172.86.179.16/29" + "208.81.1.128/28" + "208.81.3.112/28" + "172.17.0.0/16" + "127.0.0.0/8" + ]; + }; + + # Not all users need access to procul; don't allow LDAP-user access. + authentication.enable = false; + + auth.kdc = { + enable = true; + database-path = "/var/heimdal/heimdal"; + realm = "INFORMIS.LAND"; + mkey-file = "/srv/heimdal/secure/m-key"; + acl-file = "/etc/heimdal/kdc.acl"; + bind-addresses = [ + host_ipv4 + "127.0.0.1" + "127.0.1.1" + ]; + }; + + secure-dns-proxy = { + enable = true; + upstream-dns = [ "https://cloudflare-dns.com/dns-query" ]; + bootstrap-dns = "1.1.1.1"; + listen-ips = [ "127.0.0.1" ]; + port = 53; + }; + + dns = { + enable = true; + + dns-hosts = { + "ns1.informis.land" = "172.86.179.18"; + "ns2.informis.land" = "172.86.179.18"; + }; + + listen-ips = [host_ipv4]; + + domains = { + "informis.land" = import ../informis/informis.land.nix { + inherit host_ipv4 config; + }; + }; + }; + + mail-server = { + enable = true; + debug = true; + + domain = domain; + hostname = "${host-fqdn}"; + monitoring = false; + mail-user = "mailuser"; + mail-user-id = 525; + mail-group = "mailgroup"; + clamav.enable = true; + dkim.signing = true; + + dovecot = { + ssl-certificate = acme-certificate "imap.${domain}"; + ssl-private-key = acme-private-key "imap.${domain}"; + }; + + postfix = { + ssl-certificate = acme-certificate "smtp.${domain}"; + ssl-private-key = acme-private-key "smtp.${domain}"; + }; + + # This should NOT include the primary domain + local-domains = [ + host-fqdn + "smtp.${domain}" + ]; + + mail-directory = "/srv/mailserver/mail"; + state-directory = "/srv/mailserver/state"; + + trusted-networks = [ + "172.86.179.16/29" + "127.0.0.0/16" + ]; + + alias-users = { + root = ["niten"]; + postmaster = ["niten"]; + hostmaster = ["niten"]; + webmaster = ["niten"]; + system = ["niten"]; + admin = ["niten"]; + dmarc-report = ["niten"]; + }; + }; + + postgresql = { + enable = true; + ssl-certificate = (acme-certificate host-fqdn); + ssl-private-key = (acme-private-key host-fqdn); + keytab = "/srv/postgres/secure/postgres.keytab"; + + local-networks = [ + "172.86.179.16/29" + "127.0.0.0/16" + ]; + + users = { + gituser = { + password = fileContents "/srv/git/secure/db.passwd"; + databases = { + git = "ALL PRIVILEGES"; + }; + }; + }; + + databases = { + git = ["niten"]; + }; + }; + + git = { + enable = true; + hostname = "git.informis.land"; + site-name = "informis git"; + user = "gituser"; + repository-dir = /srv/git/repo; + state-dir = /srv/git/state; + database = { + user = "gituser"; + password-file = /srv/git/secure/db.passwd; + hostname = "127.0.0.1"; + name = "git"; + }; + }; + + acme = { + enable = true; + + admin-address = "admin@${domain}"; + + hostnames = [ + "imap.informis.land" + "smtp.informis.land" + ]; + }; + }; + + security.acme.certs.${host-fqdn}.email = "admin@${domain}"; + + services.nginx = { + enable = true; + + recommendedGzipSettings = true; + recommendedOptimisation = true; + recommendedTlsSettings = true; + + virtualHosts = { + "${host-fqdn}" = { + enableACME = true; + forceSSL = true; + }; + }; + }; } diff --git a/informis/informis.land.nix b/informis/informis.land.nix new file mode 100644 index 0000000..acce31d --- /dev/null +++ b/informis/informis.land.nix @@ -0,0 +1,98 @@ +{ host_ipv4, config }: + +{ + dnssec = true; + + mx = ["smtp.informis.land"]; + + hosts = { + procul = { + ip-addresses = [ "172.86.179.18" ]; + ssh-fingerprints = [ + "4 1 2a8e086d3589ce50b58c55bc35638af8da23988e" + "4 2 55a9f7c0addf08bb24c62ced954574db6e95eff38ee56d6a2cff312d20eb910e" + "1 1 d089902f60751b3d35b5329bf7b906df254d5fa7" + "1 2 8deebf42bbc40881a327f561bffd5d7bd328a4fc94d4e4ce8c502a9c6cbdfb92" + ]; + }; + }; + + default-host = "172.86.179.18"; + + srv-records = { + tcp = { + domain = [{ + host = "ns1.informis.land"; + port = 53; + }]; + ssh = [{ + host = "procul.informis.land"; + port = 22; + }]; + submission = [{ + host = "procul.informis.land"; + port = 587; + }]; + kerberos = [{ + host = "procul.informis.land"; + port = 88; + }]; + kerberos-adm = [{ + host = "procul.informis.land"; + port = 749; + }]; + imaps = [{ + host = "procul.informis.land"; + port = 993; + priority = 0; + }]; + pop3s = [{ + host = "procul.informis.land"; + port = 995; + priority = 10; + }]; + http = [{ + host = "procul.informis.land"; + port = 80; + }]; + https = [{ + host = "procul.informis.land"; + port = 443; + }]; + }; + + udp = { + domain = [{ + host = "ns1.informis.land"; + port = 53; + }]; + kerberos = [{ + host = "procul.informis.land"; + port = 88; + }]; + kerberos-master = [{ + host = "procul.informis.land"; + port = 88; + }]; + kpasswd = [{ + host = "procul.informis.land"; + port = 464; + }]; + }; + }; + + aliases = { + smtp = "procul.informis.land."; + imap = "procul.informis.land."; + gemini = "procul.informis.land."; + git = "procul.informis.land."; + }; + + extra-dns-records = [ + ''_kerberos IN TXT "INFORMIS.LAND"'' + ''@ 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@informis.land"; +} diff --git a/informis/users.nix b/informis/users.nix new file mode 100644 index 0000000..b858c6e --- /dev/null +++ b/informis/users.nix @@ -0,0 +1,14 @@ +{ config, ... }: + +{ + config = { + users.users = { + viator = { + isNormalUser = true; + description = "Viator"; + createHome = true; + hashedPassword = "$6$a1q2Duoe35hd5$IaZGXPfqyGv9uq5DQm7DZq0vIHsUs39sLktBiBBqMiwl/f/Z4jSvNZLJp9DZJYe5u2qGBYh1ca.jsXvQA8FPZ/"; + }; + }; + }; +}