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/";
+ };
+ };
+ };
+}