My Nix Configuration

[prefect] remove old mailserver config

pyrox.dev 70cbd400 95973c29

verified
+1 -2
hosts/prefect/default.nix
···
# ./services/dn42-peerfinder.nix
./services/fail2ban.nix
# ./services/headscale.nix
-
# ./services/mailserver
-
./services/mailserver/stalwart
+
./services/mailserver
# ./services/netdata.nix
# ./services/nginx
./services/prometheus.nix
+204 -105
hosts/prefect/services/mailserver/default.nix
···
-
{ lib, pkgs, ... }:
{
-
imports = [
-
./logins.nix
-
./monitoring.nix
-
./overrides.nix
-
];
-
mailserver = {
-
enable = false;
-
fqdn = "mail.pyrox.dev";
-
systemName = "PyroNet Mail";
-
systemDomain = "mail.pyrox.dev";
-
openFirewall = true;
-
stateVersion = 3;
-
-
# All domains this server runs email for
-
domains = [ "pyrox.dev" ];
-
-
# Enable STARTTLS
-
enableImap = true;
-
enableSubmission = true;
-
-
# Disable POP3, I don't use it and neither should you
-
enablePop3 = false;
-
enablePop3Ssl = false;
-
-
# Enable ManageSieve so that we don't need to change the config to update sieves
-
enableManageSieve = true;
-
-
# Set directories for services
-
mailDirectory = "/srv/mail/vmail";
-
sieveDirectory = "/srv/mail/sieve";
-
indexDir = "/var/lib/dovecot/indices";
-
dkimKeyDirectory = "/srv/mail/dkim";
-
-
# Set all no-reply addresses
-
rejectRecipients = [
-
"no-reply@pyrox.dev"
-
"dmarc-noreply@pyrox.dev"
-
];
-
-
# DKIM Settings
-
dkimKeyBits = 4096;
-
dkimSelector = "mail";
-
dkimSigning = true;
-
-
# DMARC Settings
-
dmarcReporting = {
-
enable = true;
+
config,
+
lib,
+
self,
+
...
+
}:
+
let
+
d = self.lib.data.mail;
+
cfg = config.services.stalwart-mail;
+
sec = config.age.secrets;
+
creds = config.services.stalwart-mail.credentials;
+
credsDir = "/run/credentials/stalwart-mail.service";
+
certDir = config.security.acme.certs."pyroxdev-mail".directory;
+
isAuthenticated = d: {
+
"if" = "!is_empty(authenticated_as)";
+
"then" = d;
+
};
+
otherwise = d: {
+
"else" = d;
+
};
+
ifThen = f: d: {
+
"if" = f;
+
"then" = d;
+
};
+
smSecret = {
+
owner = "stalwart-mail";
+
group = "stalwart-mail";
+
};
+
in
+
{
+
services.stalwart-mail = {
+
credentials = {
+
cert = "${certDir}/cert.pem";
+
key = "${certDir}/key.pem";
};
-
-
# Mailboxes for all users
-
mailboxes = {
-
Drafts = {
-
auto = "subscribe";
-
specialUse = "Drafts";
+
enable = true;
+
dataDir = "/var/lib/stalwart";
+
settings = {
+
tracer.stdout.level = "info";
+
authentication.fallback-admin = {
+
user = "fallback";
+
secret = "%{file:${sec.stalwart-fallback-admin-pw.path}}%";
+
};
+
config = {
+
local-keys = [
+
"asn.*"
+
"auth.*"
+
"authentication.*"
+
"auto-ban.*"
+
"calendar.*"
+
"certificate.*"
+
"changes.*"
+
"cluster.*"
+
"config.*"
+
"contacts.*"
+
"directory.*"
+
"http.*"
+
"imap.*"
+
"jmap.*"
+
"queue.*"
+
"report.*"
+
"resolver.*"
+
"server.*"
+
"session.*"
+
"signature.*"
+
"storage.*"
+
"store.*"
+
"tracer.*"
+
"webadmin.*"
+
"form.*"
+
"email.*"
+
"spam-filter.*"
+
];
+
};
+
certificate = {
+
default = {
+
default = true;
+
cert = "%{file:${credsDir}/cert}%";
+
private-key = "%{file:${credsDir}/key}%";
+
subjects = [
+
"dav.pyrox.dev"
+
"mail.pyrox.dev"
+
"mta-sts.pyrox.dev"
+
"autoconfig.pyrox.dev"
+
"autodiscover.pyrox.dev"
+
];
+
};
+
};
+
server = import ./server.nix { inherit d; };
+
# Use NixOS-generated certs now, since stalwart can't do it on its own
+
# (DeSec API Errors abound)
+
# acme = import ./acme.nix { inherit cfg sec; };
+
# HTTP Configuration
+
# https://stalw.art/docs/http/overview
+
http = {
+
url = "'https://${d.extUrl}'";
+
hsts = true;
+
rate-limit = {
+
account = "10000/1m";
+
};
+
};
+
# Disable HTTP Forms submission
+
# https://stalw.art/docs/http/form-submission
+
form.enable = false;
+
# DKIM Signatures
+
signature = import ./signature.nix { inherit sec; };
+
# Storage Settings
+
# https://stalw.art/docs/storage/overview
+
store = {
+
data = {
+
type = "rocksdb";
+
path = "${cfg.dataDir}/db";
+
purge.frequency = "0 3 *";
+
};
+
blob = {
+
type = "fs";
+
path = "${cfg.dataDir}/blobs";
+
depth = 2;
+
compression = "lz4";
+
purge.frequency = "0 4 *";
+
};
+
db.path = "${cfg.dataDir}/db2";
+
};
+
storage = {
+
data = "data";
+
blob = "blob";
+
fts = "data";
+
lookup = "data";
+
directory = "default";
};
-
Junk = {
-
auto = "subscribe";
-
specialUse = "Junk";
+
directory = {
+
default = {
+
type = "internal";
+
store = "data";
+
};
};
-
Sent = {
-
auto = "subscribe";
-
specialUse = "Sent";
+
# ASN/GeoIP Lookups
+
# https://stalw.art/docs/server/asn
+
asn = {
+
type = "dns";
+
separator = "|";
+
zone.ipv4 = "origin.asn.cymru.com";
+
zone.ipv6 = "origin6.asn.cymru.com";
+
index.asn = 0;
+
index.asn-name = 1;
+
index.country = 2;
};
-
Trash = {
-
auto = "subscribe";
-
specialUse = "Trash";
+
auto-ban = import ./auto-ban.nix;
+
# JMAP Settings
+
# https://stalw.art/docs/email/jmap
+
jmap = {
+
mailbox.max-depth = 10;
+
mailbox.max-name-length = 255;
+
# 50 MB
+
email.max-attachment-size = 50 * 1000 * 1000;
+
# 75 MB
+
email.max-size = 75 * 1000 * 1000;
+
email.parse.max-items = 10;
};
-
};
-
-
# Full-Text-Search Settings
-
fullTextSearch = {
-
enable = true;
-
autoIndex = true;
-
enforced = "body";
-
memoryLimit = 2048;
+
imap = import ./imap.nix;
+
# Maintainance
+
# https://stalw.art/docs/email/maintenance
+
email.auto-expunge = "180d";
+
changes.max-history = 10000;
+
session = import ./session.nix { inherit isAuthenticated otherwise ifThen; };
+
queue = import ./queue.nix { inherit d ifThen otherwise; };
+
# DNS Settings
+
# https://stalw.art/docs/mta/outbound/dns
+
resolver = {
+
custom = [
+
"tls://dns11.quad9.net"
+
"tcp://1.1.1.1"
+
];
+
concurrency = 2;
+
preserve-intermediates = true;
+
timeout = "5s";
+
attempts = 3;
+
edns = true;
+
};
+
report = import ./report.nix { inherit d; };
+
calendar = import ./calendar.nix;
+
# Authentication
+
auth = import ./auth.nix { inherit ifThen otherwise; };
+
# Contacts
+
# https://stalw.art/docs/collaboration/contact
+
contacts = {
+
# 512 KiB
+
max-size = 524288;
+
default.href-name = "default";
+
default.display-name = "Contacts";
+
};
+
# Spam Filtering
+
# https://stalw.art/docs/spamfilter/overview
+
spam-filter = {
+
card-is-ham = true;
+
};
};
-
-
# Certificate Settings
-
certificateScheme = "manual";
-
certificateFile = "/var/lib/mail/mail.crt";
-
keyFile = "/var/lib/mail/mail.key";
};
-
-
services.opendkim = {
-
user = lib.mkForce "virtualMail";
-
group = lib.mkForce "virtualMail";
+
systemd.services.stalwart-mail.serviceConfig = {
+
Restart = lib.mkForce "always";
+
RestartSec = lib.mkForce 1;
};
-
-
# Copy mail certs every month so that they don't expire
-
systemd = {
-
timers."copy-mail-certs" = {
-
wantedBy = [ "timers.target" ];
-
timerConfig = {
-
OnBootSec = "5m";
-
OnCalendar = "daily";
-
Unit = "copy-mail-certs.service";
-
};
+
age.secrets = {
+
stalwart-secret-rsa = smSecret // {
+
file = ../../secrets/stalwart-secret-rsa.age;
};
-
-
services."copy-mail-certs" = {
-
script = ''
-
set -eu
-
cp -fvr /var/lib/caddy/.local/share/caddy/certificates/acme-v02.api.letsencrypt.org-directory/mail.pyrox.dev/mail.pyrox.dev.crt /var/lib/mail/mail.crt
-
chmod a+r /var/lib/mail/mail.crt
-
cp -fvr /var/lib/caddy/.local/share/caddy/certificates/acme-v02.api.letsencrypt.org-directory/mail.pyrox.dev/mail.pyrox.dev.key /var/lib/mail/mail.key
-
chmod a+r /var/lib/mail/mail.key
-
chown -hR virtualMail:virtualMail /var/lib/mail/
-
'';
-
serviceConfig = {
-
Type = "oneshot";
-
User = "root";
-
};
+
stalwart-secret-ed25519 = smSecret // {
+
file = ../../secrets/stalwart-secret-ed25519.age;
+
};
+
stalwart-desec-token = smSecret // {
+
file = ../../secrets/stalwart-desec-token.age;
+
};
+
stalwart-fallback-admin-pw = smSecret // {
+
file = ../../secrets/stalwart-fallback-admin-pw.age;
};
};
-
}
-41
hosts/prefect/services/mailserver/logins.nix
···
-
{
-
mailserver.loginAccounts = {
-
"pyrox@pyrox.dev" = {
-
hashedPassword = "$2b$05$8k04quBe6adg8d1yznEp3uNYM54MOVJTwDGIWvzocQFoWbmcCvebC";
-
aliases = [
-
"pyrox"
-
"postmaster@pyrox.dev"
-
"abuse@pyrox.dev"
-
"domains@pyrox.dev"
-
];
-
};
-
"social@pyrox.dev" = {
-
hashedPassword = "$2b$05$kFDeXvSKU9oXuQXlitA7v.kkbzgCDTrm4O3Nb1kifPe7yAR7.KimO";
-
sendOnly = true;
-
};
-
"auth@pyrox.dev" = {
-
hashedPassword = "$2b$05$O049hbSwRJ5VYeAA8lLR4e6.fqVWf4PotgIUAO356j5K.OoGH5PF.";
-
sendOnly = true;
-
};
-
"vault@pyrox.dev" = {
-
hashedPassword = "$2b$05$MHo03BG3AVpBh4NE97zQ8.gTPx2sCoa6Jsw.DRxHBOBaKZ8DbfPrS";
-
sendOnly = true;
-
};
-
"library@pyrox.dev" = {
-
hashedPassword = "$2b$05$IHsSbEla8KL4gwExvFECFuuoP0ESk66K29R.vawTpbxEpuw1ahii.";
-
sendOnly = true;
-
};
-
"cloud@pyrox.dev" = {
-
hashedPassword = "$2b$05$kmbsJ2X3Y2l0KYO8jjy1SOJP29coEeKFaMqU6qvRzz/dLJp78CAk6";
-
sendOnly = true;
-
};
-
"git@pyrox.dev" = {
-
hashedPassword = "$2b$05$uZoLVdCo48rLVBFdG0.UXua8a.84w1PzmLYOpJ1qTNo25KCdQlflm";
-
sendOnly = true;
-
};
-
"share@pyrox.dev" = {
-
hashedPassword = "$2b$05$LDvYYmxYcTgqPMDvvhA.uO8UFh8yLqPzVuOdeYBq0x/WJ/85X3DEC";
-
sendOnly = true;
-
};
-
};
-
}
-46
hosts/prefect/services/mailserver/monitoring.nix
···
-
{ config, pkgs, ... }:
-
# let
-
# cfg = config.mailserver;
-
# in
-
{
-
mailserver.monitoring = {
-
enable = true;
-
alertAddress = "pyrox@pyrox.dev";
-
config = ''
-
set daemon 120 with start delay 60
-
set mailserver
-
localhost
-
set alert ${config.mailserver.monitoring.alertAddress}
-
-
set httpd port 2812 and use address localhost
-
allow localhost
-
allow admin:obwjoawijerfoijsiwfj29jf2f2jd
-
-
check filesystem root with path /
-
if space usage > 80% then alert
-
if inode usage > 80% then alert
-
-
check system $HOST
-
if cpu usage > 95% for 10 cycles then alert
-
if memory usage > 75% for 5 cycles then alert
-
if swap usage > 20% for 10 cycles then alert
-
if loadavg (1min) > 90 for 15 cycles then alert
-
if loadavg (5min) > 80 for 10 cycles then alert
-
if loadavg (15min) > 70 for 8 cycles then alert
-
-
check process postfix with pidfile /var/lib/postfix/queue/pid/master.pid
-
start program = "${pkgs.systemd}/bin/systemctl start postfix"
-
stop program = "${pkgs.systemd}/bin/systemctl stop postfix"
-
if failed port 25 protocol smtp for 5 cycles then restart
-
-
check process dovecot with pidfile /var/run/dovecot2/master.pid
-
start program = "${pkgs.systemd}/bin/systemctl start dovecot2"
-
stop program = "${pkgs.systemd}/bin/systemctl stop dovecot2"
-
if failed host ${config.mailserver.fqdn} port 993 type tcpssl sslauto protocol imap for 5 cycles then restart
-
-
check process rspamd with matching "rspamd: main process"
-
start program = "${pkgs.systemd}/bin/systemctl start rspamd"
-
stop program = "${pkgs.systemd}/bin/systemctl stop rspamd"
-
'';
-
};
-
}
-21
hosts/prefect/services/mailserver/overrides.nix
···
-
{ lib, ... }:
-
let
-
inherit (lib) mkForce;
-
tlsProtocols = ">=TLSv1.2";
-
excludeCiphers = "MD5, DES, ADH, RC4, PSD, SRP, 3DES, eNULL, aNULL, AES128-SHA, AES256-SHA";
-
in
-
{
-
services.postfix.config = {
-
# only support TLS 1.3/1.2
-
smtpd_tls_protocols = mkForce tlsProtocols;
-
smtp_tls_protocols = mkForce tlsProtocols;
-
smtpd_tls_mandatory_protocols = mkForce tlsProtocols;
-
smtp_tls_mandatory_protocols = mkForce tlsProtocols;
-
-
# Exclude insecure ciphers
-
smtpd_tls_mandatory_exclude_ciphers = mkForce excludeCiphers;
-
smtpd_tls_exclude_ciphers = mkForce excludeCiphers;
-
smtp_tls_mandatory_exclude_ciphers = mkForce excludeCiphers;
-
smtp_tls_exclude_ciphers = mkForce excludeCiphers;
-
};
-
}
hosts/prefect/services/mailserver/stalwart/acme.nix hosts/prefect/services/mailserver/acme.nix
hosts/prefect/services/mailserver/stalwart/auth.nix hosts/prefect/services/mailserver/auth.nix
hosts/prefect/services/mailserver/stalwart/auto-ban.nix hosts/prefect/services/mailserver/auto-ban.nix
hosts/prefect/services/mailserver/stalwart/calendar.nix hosts/prefect/services/mailserver/calendar.nix
-217
hosts/prefect/services/mailserver/stalwart/default.nix
···
-
{
-
config,
-
lib,
-
self,
-
...
-
}:
-
let
-
d = self.lib.data.mail;
-
cfg = config.services.stalwart-mail;
-
sec = config.age.secrets;
-
creds = config.services.stalwart-mail.credentials;
-
credsDir = "/run/credentials/stalwart-mail.service";
-
certDir = config.security.acme.certs."pyroxdev-mail".directory;
-
isAuthenticated = d: {
-
"if" = "!is_empty(authenticated_as)";
-
"then" = d;
-
};
-
otherwise = d: {
-
"else" = d;
-
};
-
ifThen = f: d: {
-
"if" = f;
-
"then" = d;
-
};
-
smSecret = {
-
owner = "stalwart-mail";
-
group = "stalwart-mail";
-
};
-
in
-
{
-
services.stalwart-mail = {
-
credentials = {
-
cert = "${certDir}/cert.pem";
-
key = "${certDir}/key.pem";
-
};
-
enable = true;
-
dataDir = "/var/lib/stalwart";
-
settings = {
-
tracer.stdout.level = "info";
-
authentication.fallback-admin = {
-
user = "fallback";
-
secret = "%{file:${sec.stalwart-fallback-admin-pw.path}}%";
-
};
-
config = {
-
local-keys = [
-
"asn.*"
-
"auth.*"
-
"authentication.*"
-
"auto-ban.*"
-
"calendar.*"
-
"certificate.*"
-
"changes.*"
-
"cluster.*"
-
"config.*"
-
"contacts.*"
-
"directory.*"
-
"http.*"
-
"imap.*"
-
"jmap.*"
-
"queue.*"
-
"report.*"
-
"resolver.*"
-
"server.*"
-
"session.*"
-
"signature.*"
-
"storage.*"
-
"store.*"
-
"tracer.*"
-
"webadmin.*"
-
"form.*"
-
"email.*"
-
"spam-filter.*"
-
];
-
};
-
certificate = {
-
default = {
-
default = true;
-
cert = "%{file:${credsDir}/cert}%";
-
private-key = "%{file:${credsDir}/key}%";
-
subjects = [
-
"dav.pyrox.dev"
-
"mail.pyrox.dev"
-
"mta-sts.pyrox.dev"
-
"autoconfig.pyrox.dev"
-
"autodiscover.pyrox.dev"
-
];
-
};
-
};
-
server = import ./server.nix { inherit d; };
-
# Use NixOS-generated certs now, since stalwart can't do it on its own
-
# (DeSec API Errors abound)
-
# acme = import ./acme.nix { inherit cfg sec; };
-
# HTTP Configuration
-
# https://stalw.art/docs/http/overview
-
http = {
-
url = "'https://${d.extUrl}'";
-
hsts = true;
-
rate-limit = {
-
account = "10000/1m";
-
};
-
};
-
# Disable HTTP Forms submission
-
# https://stalw.art/docs/http/form-submission
-
form.enable = false;
-
# DKIM Signatures
-
signature = import ./signature.nix { inherit sec; };
-
# Storage Settings
-
# https://stalw.art/docs/storage/overview
-
store = {
-
data = {
-
type = "rocksdb";
-
path = "${cfg.dataDir}/db";
-
purge.frequency = "0 3 *";
-
};
-
blob = {
-
type = "fs";
-
path = "${cfg.dataDir}/blobs";
-
depth = 2;
-
compression = "lz4";
-
purge.frequency = "0 4 *";
-
};
-
db.path = "${cfg.dataDir}/db2";
-
};
-
storage = {
-
data = "data";
-
blob = "blob";
-
fts = "data";
-
lookup = "data";
-
directory = "default";
-
};
-
directory = {
-
default = {
-
type = "internal";
-
store = "data";
-
};
-
};
-
# ASN/GeoIP Lookups
-
# https://stalw.art/docs/server/asn
-
asn = {
-
type = "dns";
-
separator = "|";
-
zone.ipv4 = "origin.asn.cymru.com";
-
zone.ipv6 = "origin6.asn.cymru.com";
-
index.asn = 0;
-
index.asn-name = 1;
-
index.country = 2;
-
};
-
auto-ban = import ./auto-ban.nix;
-
# JMAP Settings
-
# https://stalw.art/docs/email/jmap
-
jmap = {
-
mailbox.max-depth = 10;
-
mailbox.max-name-length = 255;
-
# 50 MB
-
email.max-attachment-size = 50 * 1000 * 1000;
-
# 75 MB
-
email.max-size = 75 * 1000 * 1000;
-
email.parse.max-items = 10;
-
};
-
imap = import ./imap.nix;
-
# Maintainance
-
# https://stalw.art/docs/email/maintenance
-
email.auto-expunge = "180d";
-
changes.max-history = 10000;
-
session = import ./session.nix { inherit isAuthenticated otherwise ifThen; };
-
queue = import ./queue.nix { inherit d ifThen otherwise; };
-
# DNS Settings
-
# https://stalw.art/docs/mta/outbound/dns
-
resolver = {
-
custom = [
-
"tls://dns11.quad9.net"
-
"tcp://1.1.1.1"
-
];
-
concurrency = 2;
-
preserve-intermediates = true;
-
timeout = "5s";
-
attempts = 3;
-
edns = true;
-
};
-
report = import ./report.nix { inherit d; };
-
calendar = import ./calendar.nix;
-
# Authentication
-
auth = import ./auth.nix { inherit ifThen otherwise; };
-
# Contacts
-
# https://stalw.art/docs/collaboration/contact
-
contacts = {
-
# 512 KiB
-
max-size = 524288;
-
default.href-name = "default";
-
default.display-name = "Contacts";
-
};
-
# Spam Filtering
-
# https://stalw.art/docs/spamfilter/overview
-
spam-filter = {
-
card-is-ham = true;
-
};
-
};
-
};
-
systemd.services.stalwart-mail.serviceConfig = {
-
Restart = lib.mkForce "always";
-
RestartSec = lib.mkForce 1;
-
};
-
age.secrets = {
-
stalwart-secret-rsa = smSecret // {
-
file = ../../../secrets/stalwart-secret-rsa.age;
-
};
-
stalwart-secret-ed25519 = smSecret // {
-
file = ../../../secrets/stalwart-secret-ed25519.age;
-
};
-
stalwart-desec-token = smSecret // {
-
file = ../../../secrets/stalwart-desec-token.age;
-
};
-
stalwart-fallback-admin-pw = smSecret // {
-
file = ../../../secrets/stalwart-fallback-admin-pw.age;
-
};
-
};
-
}
hosts/prefect/services/mailserver/stalwart/imap.nix hosts/prefect/services/mailserver/imap.nix
hosts/prefect/services/mailserver/stalwart/queue.nix hosts/prefect/services/mailserver/queue.nix
hosts/prefect/services/mailserver/stalwart/report.nix hosts/prefect/services/mailserver/report.nix
hosts/prefect/services/mailserver/stalwart/server.nix hosts/prefect/services/mailserver/server.nix
hosts/prefect/services/mailserver/stalwart/session.nix hosts/prefect/services/mailserver/session.nix
hosts/prefect/services/mailserver/stalwart/signature.nix hosts/prefect/services/mailserver/signature.nix