gerd.stalward: added stalwart mailserver
This commit is contained in:
parent
e3114fb300
commit
eab1162cfd
6 changed files with 165 additions and 3 deletions
|
@ -16,9 +16,7 @@
|
||||||
./gerd/services/hedgedoc.nix
|
./gerd/services/hedgedoc.nix
|
||||||
./gerd/services/cyberchef.nix
|
./gerd/services/cyberchef.nix
|
||||||
./gerd/services/nextcloud.nix
|
./gerd/services/nextcloud.nix
|
||||||
|
./gerd/services/stalwart.nix
|
||||||
|
|
||||||
# ./gerd/services/owncast.nix
|
|
||||||
];
|
];
|
||||||
|
|
||||||
networking.hostName = "gerd";
|
networking.hostName = "gerd";
|
||||||
|
@ -32,6 +30,7 @@
|
||||||
"safe/svcs/forgejo" = { mountpoint = "/srv/forgejo"; extra.options.quota = "5G"; };
|
"safe/svcs/forgejo" = { mountpoint = "/srv/forgejo"; extra.options.quota = "5G"; };
|
||||||
"safe/svcs/hedgedoc" = { mountpoint = "/srv/hedgedoc"; extra.options.quota = "5G"; };
|
"safe/svcs/hedgedoc" = { mountpoint = "/srv/hedgedoc"; extra.options.quota = "5G"; };
|
||||||
"safe/svcs/nextcloud" = { mountpoint = "/srv/nextcloud"; extra.options.quota = "5G"; };
|
"safe/svcs/nextcloud" = { mountpoint = "/srv/nextcloud"; extra.options.quota = "5G"; };
|
||||||
|
"safe/svcs/stalwart" = { mountpoint = "/srv/stalwart"; extra.options.quota = "5G"; };
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
143
machines/gerd/services/stalwart.nix
Normal file
143
machines/gerd/services/stalwart.nix
Normal file
|
@ -0,0 +1,143 @@
|
||||||
|
{ config, lib, pkgs, ... }:
|
||||||
|
|
||||||
|
let
|
||||||
|
svc_domain = "mail.${config.mine.shared.settings.domain}";
|
||||||
|
svc_domain_smtp = "smtp.${config.mine.shared.settings.domain}";
|
||||||
|
svc_domain_imap = "imap.${config.mine.shared.settings.domain}";
|
||||||
|
|
||||||
|
ports = {
|
||||||
|
smtp = 25;
|
||||||
|
submissions = 465;
|
||||||
|
imaptls = 993;
|
||||||
|
|
||||||
|
http_management = 7377;
|
||||||
|
};
|
||||||
|
|
||||||
|
# place data into own zfs dataset
|
||||||
|
stateDir = config.mine.zfsMounts."rpool/safe/svcs/stalwart";
|
||||||
|
|
||||||
|
# user/group
|
||||||
|
stalwart_user = config.users.users.stalwart-mail.name;
|
||||||
|
stalwart_group = config.users.groups.stalwart-mail.name;
|
||||||
|
|
||||||
|
certLocation = config.security.acme.certs."${svc_domain}".directory;
|
||||||
|
in {
|
||||||
|
services.stalwart-mail = {
|
||||||
|
enable = true;
|
||||||
|
openFirewall = true;
|
||||||
|
# package = pkgs.stalwart-mail;
|
||||||
|
|
||||||
|
settings = {
|
||||||
|
lookup.default.hostname = svc_domain;
|
||||||
|
|
||||||
|
# tracer.stdout.level = "trace";
|
||||||
|
store.db.path = "${stateDir}/db";
|
||||||
|
|
||||||
|
directory.ldap = {
|
||||||
|
type = "ldap";
|
||||||
|
url = config.mine.shared.settings.ldap.url;
|
||||||
|
base-dn = config.mine.shared.settings.ldap.dc;
|
||||||
|
tls.enable = false;
|
||||||
|
|
||||||
|
bind = {
|
||||||
|
dn = config.mine.shared.settings.ldap.bind_dn;
|
||||||
|
secret = "%{file:${config.age.secrets.lldap-bind-user-pass.path}}%";
|
||||||
|
|
||||||
|
auth = {
|
||||||
|
enable = true;
|
||||||
|
dn = "cn=?,${config.mine.shared.settings.ldap.search_base}";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
filter = let
|
||||||
|
_mkFilter = attrs: ph: config.mine.shared.lib.ldap.mkFilter (lconfig: llib:
|
||||||
|
llib.mkAnd [
|
||||||
|
(llib.mkGroup lconfig.groups.member)
|
||||||
|
(llib.mkOr (lib.forEach attrs (v: llib.mkSearch v ph)))
|
||||||
|
]
|
||||||
|
);
|
||||||
|
|
||||||
|
attrs = config.mine.shared.settings.ldap.attr // { emailAlias = "mailAlias"; emailList = "mailList"; };
|
||||||
|
in {
|
||||||
|
name = _mkFilter [ attrs.uid ] "?";
|
||||||
|
email = _mkFilter [ attrs.email attrs.emailAlias attrs.emailList ] "?";
|
||||||
|
verify = _mkFilter [ attrs.email attrs.emailAlias ] "*?*";
|
||||||
|
expand = _mkFilter [ attrs.emailList ] "?";
|
||||||
|
domains = _mkFilter [ attrs.email attrs.emailAlias ] "*@?";
|
||||||
|
};
|
||||||
|
|
||||||
|
attributes = {
|
||||||
|
name = "uid";
|
||||||
|
class = "objectClass";
|
||||||
|
description = "givenName";
|
||||||
|
secret = "uid";
|
||||||
|
groups = "memberOf";
|
||||||
|
email = "mail";
|
||||||
|
# email-alias = "mailAlias";
|
||||||
|
# quota = "diskQuota";
|
||||||
|
};
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
storage.directory = "ldap";
|
||||||
|
|
||||||
|
# listeners
|
||||||
|
server.listener = {
|
||||||
|
smtp = { bind = [ "[::]:${builtins.toString ports.smtp}"]; protocol = "smtp"; };
|
||||||
|
submissions = { bind = [ "[::]:${builtins.toString ports.submissions}"]; protocol = "smtp"; tls.implicit = true; };
|
||||||
|
imaptls = { bind = [ "[::]:${builtins.toString ports.imaptls}"]; protocol = "imap"; tls.implicit = true; };
|
||||||
|
|
||||||
|
management = { bind = [ "127.0.0.1:${builtins.toString ports.http_management}" ]; protocol = "http"; };
|
||||||
|
};
|
||||||
|
|
||||||
|
certificate.domain = {
|
||||||
|
cert = "%{file:${certLocation + "/cert.pem"}}%";
|
||||||
|
private-key = "%{file:${certLocation + "/key.pem"}}%";
|
||||||
|
};
|
||||||
|
|
||||||
|
server.tls = {
|
||||||
|
certificate = "domain";
|
||||||
|
enable = true;
|
||||||
|
implicit = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
# authentication
|
||||||
|
authentication.fallback-admin = {
|
||||||
|
user = "admin";
|
||||||
|
secret = "%{file:${config.age.secrets.stalwart-admin-fallback-password.owner}}%";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
# setup so that stalwart can access and write to the directory
|
||||||
|
systemd.services.stalwart-mail.serviceConfig.ReadWritePaths = [ stateDir ];
|
||||||
|
systemd.tmpfiles.rules = [
|
||||||
|
"Z ${stateDir} 0700 ${stalwart_user} ${stalwart_group} -"
|
||||||
|
];
|
||||||
|
|
||||||
|
# setup certs
|
||||||
|
services.nginx.virtualHosts."${svc_domain}" = {
|
||||||
|
forceSSL = true;
|
||||||
|
enableACME = true;
|
||||||
|
serverAliases = [ svc_domain_smtp svc_domain_imap ];
|
||||||
|
root = pkgs.writeTextDir "index.html" "Nothing.";
|
||||||
|
};
|
||||||
|
|
||||||
|
# need to change group to stalwart-mail for cert + add nginx to stalwart-mail group to do HTTP ACME
|
||||||
|
users.users.nginx.extraGroups = [ stalwart_group ];
|
||||||
|
security.acme.certs."${svc_domain}".group = stalwart_group;
|
||||||
|
|
||||||
|
|
||||||
|
# setup secrets for stalwart
|
||||||
|
# setup access to ldap bind user credential
|
||||||
|
users.groups.secrets-lldap-bind-user-pass.members = [ stalwart_user ];
|
||||||
|
age.secrets.stalwart-admin-fallback-password.owner = stalwart_user;
|
||||||
|
|
||||||
|
mine.shared.settings.mail = {
|
||||||
|
domain = svc_domain;
|
||||||
|
domain_smtp = svc_domain_smtp;
|
||||||
|
domain_imap = svc_domain_imap;
|
||||||
|
|
||||||
|
ports = ports;
|
||||||
|
};
|
||||||
|
}
|
|
@ -31,6 +31,9 @@
|
||||||
# nextcloud
|
# nextcloud
|
||||||
nextcloud-admin-pass.file = ./nextcloud/admin-pass.age;
|
nextcloud-admin-pass.file = ./nextcloud/admin-pass.age;
|
||||||
nextcloud-secrets.file = ./nextcloud/secrets.age;
|
nextcloud-secrets.file = ./nextcloud/secrets.age;
|
||||||
|
|
||||||
|
# stalwart
|
||||||
|
stalwart-admin-fallback-password.file = ./stalwart/admin-fallback-password.age;
|
||||||
};
|
};
|
||||||
|
|
||||||
users.groups.secrets-lldap-bind-user-pass = {};
|
users.groups.secrets-lldap-bind-user-pass = {};
|
||||||
|
|
|
@ -35,4 +35,7 @@ in
|
||||||
# nextcloud
|
# nextcloud
|
||||||
"nextcloud/admin-pass.age".publicKeys = defaultAccess;
|
"nextcloud/admin-pass.age".publicKeys = defaultAccess;
|
||||||
"nextcloud/secrets.age".publicKeys = defaultAccess;
|
"nextcloud/secrets.age".publicKeys = defaultAccess;
|
||||||
|
|
||||||
|
# mailserver/stalwart
|
||||||
|
"stalwart/admin-fallback-password.age".publicKeys = defaultAccess;
|
||||||
}
|
}
|
||||||
|
|
9
secrets/stalwart/admin-fallback-password.age
Normal file
9
secrets/stalwart/admin-fallback-password.age
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
age-encryption.org/v1
|
||||||
|
-> ssh-ed25519 QSDXqg KxP3cNdqRorj0JO6SW3FOjcFxgmsspRz/MKnVVviXFM
|
||||||
|
i9SoYa0sQ0E7S2jo9Js5PJsiHB3lMsVqX5bULg255bw
|
||||||
|
-> ssh-ed25519 n8n9DQ BrcbGW2zt6E5QjRz+kN/5vl4AreGuOsR+AUcv8sog3M
|
||||||
|
c+nUCQ9Bifu3bK4R2OgKLbfFFU66/73Oj4y9bMTVJIU
|
||||||
|
-> ssh-ed25519 BTp6UA RngU7oNTzWJRZG6Qr/t9RiAxEeBelHIzOuSp44b3HVc
|
||||||
|
DUrunTXLwjLqkuiuzksaqpSwvmKpps/I6Jftv0dD6p8
|
||||||
|
--- D75A1a96Q1UKHUsAejeydmjqui9+P3e6fRo3Eeb1I0g
|
||||||
|
··çu<> éì>ÝÄ_owxîuýªÓê'<27>ÿ Ÿ7Ÿì?[À5dGTq✛ò¼B¼]0_‡·(Íç:Ķ
|
|
@ -13,6 +13,11 @@ in sources // {
|
||||||
url = "https://github.com/NixOS/nixpkgs/pull/334590.patch";
|
url = "https://github.com/NixOS/nixpkgs/pull/334590.patch";
|
||||||
sha256 = "sha256-5Uf/jLV0CJFbWyPmkpF4kEVISvoG+fujvTAFIR0a2ek=";
|
sha256 = "sha256-5Uf/jLV0CJFbWyPmkpF4kEVISvoG+fujvTAFIR0a2ek=";
|
||||||
})
|
})
|
||||||
|
# stalwart-mail
|
||||||
|
(pkgs.fetchpatch {
|
||||||
|
url = "https://github.com/NixOS/nixpkgs/pull/333507.patch";
|
||||||
|
sha256 = "sha256-HAbfKQRnOjdK/rJ5wuePw4hEVQoFz9N0YujxBxROGo0=";
|
||||||
|
})
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue