mirror of
https://github.com/oddlama/nix-config.git
synced 2025-10-10 23:00:39 +02:00
feat: finish stalwart setup
This commit is contained in:
parent
01660a3389
commit
4e717fab96
8 changed files with 58 additions and 141 deletions
|
@ -1,4 +1,8 @@
|
|||
{config, ...}: let
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
...
|
||||
}: let
|
||||
mailDomains = config.repo.secrets.global.domains.mail;
|
||||
primaryDomain = mailDomains.primary;
|
||||
idmailDomain = "alias.${primaryDomain}";
|
||||
|
@ -13,6 +17,12 @@ in {
|
|||
# }
|
||||
#];
|
||||
|
||||
age.secrets.idmail-admin-hash = {
|
||||
rekeyFile = ./secrets/idmail-admin-hash.age;
|
||||
mode = "440";
|
||||
group = "stalwart-mail";
|
||||
};
|
||||
|
||||
globals.services.idmail.domain = idmailDomain;
|
||||
globals.monitoring.http.idmail = {
|
||||
url = "https://${idmailDomain}";
|
||||
|
@ -28,24 +38,12 @@ in {
|
|||
enable = true;
|
||||
users.admin = {
|
||||
admin = true;
|
||||
# FIXME: 8e8e1c2eb2f1b8c84f1ef294d2fd746b
|
||||
password_hash = "$argon2id$v=19$m=4096,t=3,p=1$c29tZXJhbmRvbXNhbHQ$Hf0sBCqn5Zp5+7LalZNLKhG0exNsXN2M5T+y3QAjpMM";
|
||||
password_hash = "%{file:${config.age.secrets.idmail-admin-hash.path}}%";
|
||||
};
|
||||
# users.test.password_hash = "$argon2id$v=19$m=4096,t=3,p=1$YXJnbGluYXJsZ2luMjRvaQ$DXdfVNRSFS1QSvJo7OmXIhAYYtT/D92Ku16DiJwxn8U";
|
||||
# domains."example.com" = {
|
||||
# owner = "admin";
|
||||
# public = true;
|
||||
# };
|
||||
# mailboxes."me@example.com" = {
|
||||
# password_hash = "$argon2id$v=19$m=4096,t=3,p=1$YXJnbGluYXJsZ2luMjRvaQ$fiD9Bp3KidVI/E+mGudu6+h9XmF9TU9Bx4VGX0PniDE";
|
||||
# owner = "test";
|
||||
# api_token = "%{file:${pkgs.writeText "token" token}}%";
|
||||
# };
|
||||
# aliases."somealias@example.com" = {
|
||||
# target = "me@example.com";
|
||||
# owner = "me@example.com";
|
||||
# comment = "Used for xyz";
|
||||
# };
|
||||
domains = lib.genAttrs mailDomains.all (_: {
|
||||
owner = "admin";
|
||||
public = true;
|
||||
});
|
||||
};
|
||||
};
|
||||
systemd.services.idmail.serviceConfig.RestartSec = "60"; # Retry every minute
|
||||
|
|
BIN
hosts/envoy/secrets/idmail-admin-hash.age
Normal file
BIN
hosts/envoy/secrets/idmail-admin-hash.age
Normal file
Binary file not shown.
|
@ -1,11 +1,11 @@
|
|||
age-encryption.org/v1
|
||||
-> X25519 4dtyNzQ1aoj+se7IxhCnN9A8bOmhPxm3bibijfCNjVw
|
||||
PoRE6VrM+shoneZJAS+Fh/kIjn9tX6mw9Kr2vD3xOSE
|
||||
-> piv-p256 xqSe8Q AwvKCfsTHQh3Z05VZ3kRtaa90pqyR3tY+wKwwibfdvzF
|
||||
dFjn+siQjWdhMVCGsiZyFNBykTrCIrHr9zt3aRxtSQc
|
||||
-> A'xo-grease KM'D
|
||||
4D/ij+JrWVbUTv75EljIaE8L9JhFP3Dz
|
||||
--- inyuu2A3QIBGnRj8WyQKX8+XdVDBCmANdyaHkQ0ZS7s
|
||||
”_hð”u‘㳊ÏPÖ?I'ó°Fi�ñÙÞ¶3»ÓÊý¸e‰t)ÚÃàEñ‡›à,�¯ ·÷ê«3ŸrQ”X?mo¬ÃÕ—YuÒHi90öÆ7€áé*•§ßÕZH—]z¨:XzÖ
|
||||
oóT™3(DšØþ7¨à�ð®÷á
|
||||
×ô@¯�fšû³UúÝZ„<ñη(©E‘ï–TG:¹sÇÑ‚—Æ‘“4€<â5UÞšÖª²·½‘R*_`BoŒ˜æ
|
||||
-> X25519 t0FJIrbn5q7oX4+1tHvjDnWDCiD6NMkNw7Aq2MfSXw4
|
||||
W6aq9jnVOH9W+pjsrSCZG1BJXSNojhiUrTgzANFpM9w
|
||||
-> piv-p256 xqSe8Q A3qjOwYgwBFDf0beUSyw3nHhkO9ZhsJzGHBh4BTw7+tS
|
||||
ffyaSOMoOHiIXfXvCJY/apYkEc7wZgkhOGTNT9O7oJ0
|
||||
-> n[k#S-grease /{ w79 (TV$':-8 4E
|
||||
hxVz/9v74X2gEt9y0yvKMClVgId3mAl5PVisyL0r8WUn4extTHoh8qj2fSFl++54
|
||||
c0aRZZ5Y+Pdqu/7FyignIhV4WbUtverMWhWdRAhGsXqFm/8ejLqPfELQ54w
|
||||
--- rTgyJNg/7gotGoTSMt5jDxSFE0tM8CP+azNlDTRjCow
|
||||
LiÀºÝ“kþÃñ.?�N@1�l·H΢æÐ�m°@8N�^òU•u• Ô
|
||||
¦Ïƒ/íò¬ØÇ³§FIHÍÂk+*è+;#3ÒvÖx×~¯3¢Ú‚VZ߯‡ïî¿oó£Ñ’ZC|ñßÂÕ›T*ˆÛ‡“^-ªÑ .71Ñé€cÐ÷+g¬±‘†»Å�
|
|
@ -44,10 +44,6 @@ in {
|
|||
|
||||
services.stalwart-mail = {
|
||||
enable = true;
|
||||
package = pkgs.stalwart-mail.overrideAttrs (old: {
|
||||
patches = old.patches ++ [./stalwart.patch];
|
||||
});
|
||||
|
||||
settings = let
|
||||
case = field: check: value: data: {
|
||||
"if" = field;
|
||||
|
@ -64,7 +60,7 @@ in {
|
|||
lib.mkForce {
|
||||
authentication.fallback-admin = {
|
||||
user = "admin";
|
||||
secret = "%{file:/run/stalwart-mail/admin-hash}%";
|
||||
secret = "%{file:${config.age.secrets.stalwart-admin-hash.path}}%";
|
||||
};
|
||||
|
||||
tracer.stdout = {
|
||||
|
@ -336,9 +332,8 @@ in {
|
|||
default = true;
|
||||
};
|
||||
|
||||
lookup.default.hostname = config.networking.fqdn;
|
||||
lookup.default.hostname = stalwartDomain;
|
||||
server = {
|
||||
hostname = config.networking.fqdn;
|
||||
tls = {
|
||||
certificate = "default";
|
||||
ignore-client-order = true;
|
||||
|
@ -366,7 +361,8 @@ in {
|
|||
# jmap, web interface
|
||||
protocol = "http";
|
||||
bind = "[::]:8080";
|
||||
url = "https://${stalwartDomain}/jmap";
|
||||
url = "https://${stalwartDomain}";
|
||||
use-x-forwarded = true;
|
||||
};
|
||||
sieve = {
|
||||
protocol = "managesieve";
|
||||
|
@ -376,19 +372,6 @@ in {
|
|||
};
|
||||
};
|
||||
|
||||
#queue.outbound.next-hop = [
|
||||
# (case "rcpt_domain" "in-list" "default/domains" "local")
|
||||
# (otherwise false)
|
||||
#];
|
||||
|
||||
#queue.schedule = {
|
||||
# retry = ["2m" "5m" "10m" "15m" "30m" "1h" "2h"];
|
||||
# notify = ["1d" "3d"];
|
||||
# expire = "5d";
|
||||
#};
|
||||
|
||||
# XXX: needed? jmap.directory = "idmail";
|
||||
|
||||
imap = {
|
||||
request.max-size = 52428800;
|
||||
auth = {
|
||||
|
@ -443,7 +426,6 @@ in {
|
|||
};
|
||||
|
||||
session.rcpt = {
|
||||
# XXX: needed? directory = "idmail";
|
||||
catch-all = true;
|
||||
relay = [
|
||||
(is-authenticated true)
|
||||
|
@ -456,23 +438,31 @@ in {
|
|||
|
||||
services.nginx = {
|
||||
upstreams.stalwart = {
|
||||
servers."localhost:8080" = {};
|
||||
servers."127.0.0.1:8080" = {};
|
||||
extraConfig = ''
|
||||
zone stalwart 64k;
|
||||
keepalive 2;
|
||||
'';
|
||||
};
|
||||
virtualHosts.${stalwartDomain} = {
|
||||
forceSSL = true;
|
||||
useACMEWildcardHost = true;
|
||||
extraConfig = ''
|
||||
client_max_body_size 512M;
|
||||
'';
|
||||
locations."/" = {
|
||||
proxyPass = "http://stalwart";
|
||||
proxyWebsockets = true;
|
||||
};
|
||||
};
|
||||
virtualHosts =
|
||||
{
|
||||
${stalwartDomain} = {
|
||||
forceSSL = true;
|
||||
useACMEWildcardHost = true;
|
||||
extraConfig = ''
|
||||
client_max_body_size 512M;
|
||||
'';
|
||||
locations."/" = {
|
||||
proxyPass = "http://stalwart";
|
||||
proxyWebsockets = true;
|
||||
};
|
||||
};
|
||||
}
|
||||
// lib.genAttrs ["autoconfig.${primaryDomain}" "autodiscover.${primaryDomain}" "mta-sts.${primaryDomain}"] (_: {
|
||||
forceSSL = true;
|
||||
useACMEWildcardHost = true;
|
||||
locations."/".proxyPass = "http://stalwart";
|
||||
});
|
||||
};
|
||||
|
||||
systemd.services.stalwart-mail = let
|
||||
|
@ -482,9 +472,6 @@ in {
|
|||
in {
|
||||
preStart = lib.mkAfter ''
|
||||
cat ${configFile} > /run/stalwart-mail/config.toml
|
||||
${pkgs.gnugrep}/bin/grep -v '^\s*$\|^\s*#' \
|
||||
< ${config.age.secrets.stalwart-admin-hash.path} \
|
||||
| tr -d '\n' > /run/stalwart-mail/admin-hash
|
||||
'';
|
||||
serviceConfig = {
|
||||
RuntimeDirectory = "stalwart-mail";
|
||||
|
|
|
@ -1,76 +0,0 @@
|
|||
diff --git a/crates/directory/src/backend/sql/lookup.rs b/crates/directory/src/backend/sql/lookup.rs
|
||||
index e49c5dab..18c9005e 100644
|
||||
--- a/crates/directory/src/backend/sql/lookup.rs
|
||||
+++ b/crates/directory/src/backend/sql/lookup.rs
|
||||
@@ -25,6 +25,7 @@ impl SqlDirectory {
|
||||
QueryBy::Name(username) => {
|
||||
account_name = username.to_string();
|
||||
|
||||
+ tracing::info!(context = "directory", event = "sql lookup", username = username, "Name -> query_name");
|
||||
self.store
|
||||
.query::<NamedRows>(&self.mappings.query_name, vec![username.into()])
|
||||
.await?
|
||||
@@ -37,6 +38,7 @@ impl SqlDirectory {
|
||||
}
|
||||
account_id = Some(uid);
|
||||
|
||||
+ tracing::info!(context = "directory", event = "sql lookup", username = account_name, "Id -> query_name");
|
||||
self.store
|
||||
.query::<NamedRows>(
|
||||
&self.mappings.query_name,
|
||||
@@ -53,6 +55,7 @@ impl SqlDirectory {
|
||||
account_name = username.to_string();
|
||||
secret = secret_.into();
|
||||
|
||||
+ tracing::info!(context = "directory", event = "sql lookup", username = username, "Credentials -> query_name");
|
||||
self.store
|
||||
.query::<NamedRows>(&self.mappings.query_name, vec![username.into()])
|
||||
.await?
|
||||
@@ -112,6 +115,7 @@ impl SqlDirectory {
|
||||
|
||||
// Obtain emails
|
||||
if !self.mappings.query_emails.is_empty() {
|
||||
+ tracing::info!(context = "directory", event = "sql lookup", principal_name = principal.name, "Query emails");
|
||||
principal.emails = self
|
||||
.store
|
||||
.query::<Rows>(
|
||||
@@ -126,6 +130,7 @@ impl SqlDirectory {
|
||||
}
|
||||
|
||||
pub async fn email_to_ids(&self, address: &str) -> crate::Result<Vec<u32>> {
|
||||
+ tracing::info!(context = "directory", event = "sql lookup", address = address, "Query recipients");
|
||||
let names = self
|
||||
.store
|
||||
.query::<Rows>(&self.mappings.query_recipients, vec![address.into()])
|
||||
@@ -143,6 +148,7 @@ impl SqlDirectory {
|
||||
}
|
||||
|
||||
pub async fn rcpt(&self, address: &str) -> crate::Result<bool> {
|
||||
+ tracing::info!(context = "directory", event = "sql lookup", address = address, "Query rcpt");
|
||||
self.store
|
||||
.query::<bool>(
|
||||
&self.mappings.query_recipients,
|
||||
@@ -153,6 +159,7 @@ impl SqlDirectory {
|
||||
}
|
||||
|
||||
pub async fn vrfy(&self, address: &str) -> crate::Result<Vec<String>> {
|
||||
+ tracing::info!(context = "directory", event = "sql lookup", address = address, "Query vrfy");
|
||||
self.store
|
||||
.query::<Rows>(
|
||||
&self.mappings.query_verify,
|
||||
@@ -164,6 +171,7 @@ impl SqlDirectory {
|
||||
}
|
||||
|
||||
pub async fn expn(&self, address: &str) -> crate::Result<Vec<String>> {
|
||||
+ tracing::info!(context = "directory", event = "sql lookup", address = address, "Query expn");
|
||||
self.store
|
||||
.query::<Rows>(
|
||||
&self.mappings.query_expand,
|
||||
@@ -175,6 +183,7 @@ impl SqlDirectory {
|
||||
}
|
||||
|
||||
pub async fn is_local_domain(&self, domain: &str) -> crate::Result<bool> {
|
||||
+ tracing::info!(context = "directory", event = "sql lookup", domain = domain, "Query is local domain");
|
||||
self.store
|
||||
.query::<bool>(&self.mappings.query_domains, vec![domain.into()])
|
||||
.await
|
Binary file not shown.
Binary file not shown.
|
@ -0,0 +1,8 @@
|
|||
age-encryption.org/v1
|
||||
-> ssh-ed25519 rz300w go7St2w4V+OeN5VgddWbw0WHuMJrZFNAE6ybU9tAbmI
|
||||
sGjDHvZO56PPiIB0CvCuR1tyk2UzObeZk4IRoi+hvWA
|
||||
-> wxzPB1{z-grease {^`is<&c [D`g<
|
||||
Gurn/IfyXKKbuyKJNnlHfxwSOBKyqj3SlW3cxqcw6CwoL9Gc0UXeWlOgEHPzas9L
|
||||
v2un
|
||||
--- dmrjPRsNFeNkTPWOD1MbORG3X2AuOBp1lbFIS64kPyg
|
||||
8¢²(èüyýZ\{j~ãZɨndÖHÊò´UØÆ±þw 3?nÿ
ÅnQº÷ÌóP>P8J0¨Ã"Œ_ÉÒÜcìHt§•üßp¨Nh�=8%ËHÌE¬uÍHÅrÓ.Q+u�ìÈp4\oÎTÆóêN[ŒnXô!ŒtÚ;z�«ù
|
Loading…
Add table
Add a link
Reference in a new issue