First attempt at ldap for mail

This commit is contained in:
Lyes Saadi 2026-02-15 03:41:52 +01:00
parent e2946c9fb7
commit b6352c36c1
Signed by: lyes
GPG key ID: 55A1D803917CF39A
9 changed files with 118 additions and 174 deletions

View file

@ -13,6 +13,7 @@
./users.nix
../../users/lyes
../../users/lyes/server
../../modules
../../modules/server

View file

@ -3,7 +3,7 @@
{
security.acme = {
acceptTerms = true;
defaults.email = "security@lyes.eu";
defaults.email = "root.security@lyes.eu";
};
services.nginx = {

View file

@ -14,7 +14,7 @@ in
# package = pkgs.kanidmWithSecretProvisioning_1_7;
enableServer = true;
serverSettings = {
server.settings = {
bindaddress = "127.0.0.1:${port}";
ldapbindaddress = "0.0.0.0:636";
domain = hostname;

View file

@ -1,5 +1,20 @@
{ config, ... }:
{ config, lib, ... }:
let
alias = ''
@lyes.eu lyes
lyes@mail.lyes.eu lyes
abuse@taf.lyes.eu lyes
abuse@mail.lyes.eu lyes
abuse@minish.fr lyes
abuse@minish.link lyes
postmaster@taf.lyes.eu lyes
postmaster@mail.lyes.eu lyes
postmaster@minish.fr lyes
postmaster@minish.link lyes
'';
aliasFile = lib.toFile "alias" alias;
in
{
mailserver = {
enable = true;
@ -7,7 +22,10 @@
fqdn = "taf.lyes.eu";
domains = [
"lyes.eu"
"taf.lyes.eu"
"mail.lyes.eu"
"minish.fr"
"minish.link"
];
localDnsResolver = false;
@ -15,175 +33,85 @@
# debug.all = true;
# ldap = {
# enable = true;
ldap = {
enable = true;
# uris = [ "ldaps://auth.lyes.eu:636" ];
# searchBase = "dc=auth,dc=lyes,dc=eu";
# searchScope = "sub";
uris = [ "ldaps://auth.lyes.eu:636" ];
searchBase = "dc=auth,dc=lyes,dc=eu";
searchScope = "sub";
# bind = {
# # dn = "dn=token,dc=auth,dc=lyes,dc=eu";
# dn = "dn=token";
# passwordFile = config.age.secrets.taf-token.path;
# };
bind = {
# dn = "dn=token,dc=auth,dc=lyes,dc=eu";
dn = "dn=token";
passwordFile = config.age.secrets.taf-token.path;
};
# dovecot = {
# userFilter = "(name=%u)";
# passFilter = "(name=%u)";
# };
dovecot = {
userFilter = "(&(memberof=taf_users)(mail=%u))";
passFilter = "(&(memberof=taf_users)(mail=%u))";
};
# postfix = {
# filter = "(name=%s)";
# mailAttribute = "mail";
# uidAttribute = "name";
# };
# };
loginAccounts = {
"lyes@mail.lyes.eu" = {
hashedPasswordFile = config.age.secrets.lyes-mail-passwd.path;
aliases = [
"@lyes.eu"
];
quota = "1T";
sieveScript = ''
require ["include", "fileinto", "mailbox", "copy", "regex", "variables", "imap4flags"];
include :personal "hiddensieve";
# lyes.eu filters
if address :is :domain "X-Original-To" "lyes.eu" {
# If the mail comes from my crans mailbox
if address :is :localpart "X-Original-To" "crans" {
# Aurore Support
if header :contains "List-Id" "<support.aurore.lists.crans.org>" {
fileinto :create "Crans.aurore.support";
}
# Mailman moderation request
elsif address :matches :all "To" "*-owner@lists.crans.org" {
fileinto :create "Crans.moderation";
}
# Crans Bureau
elsif anyof (
header :contains "List-Id" "<bureau.lists.crans.org>",
header :contains "List-Id" "<achats-crans.lists.crans.org>",
header :contains "List-Id" "<tresorerie.lists.crans.org>"
) {
fileinto :create "Crans.crans.bureau";
}
# Crans CA
elsif header :contains "List-Id" "<ca.lists.crans.org>" {
fileinto :create "Crans.crans.ca";
}
# Crans Root Postmaster
elsif address :is :all "To" "postmaster@crans.org" {
addflag "\\Seen";
fileinto :create "Crans.crans.root.postmaster";
}
# Crans Root Mailer
elsif address :is :all "From" "MAILER-DAEMON@crans.org" {
fileinto :create "Crans.crans.root.mailer";
}
# Crans Nounou
elsif anyof (
header :contains "List-Id" "<nounou.lists.crans.org>",
header :contains "List-Id" "<apprenti-es.lists.crans.org>",
address :is :all "To" "contact@crans.org",
address :is :all "From" "contact@crans.org"
) {
fileinto :create "Crans.crans.nounou";
}
# Crans Root
elsif anyof (
address :is :all "To" "root@crans.org",
address :is :all "From" "root@crans.org",
address :is :all "From" "www-data@crans.org"
) {
fileinto :create "Crans.crans.root";
}
# Crans Gitlab
elsif address :is :all "From" "gitlab@crans.org" {
fileinto :create "Crans.crans.gitlab";
}
# Crans Wiki
elsif address :is :all "From" "wiki@crans.org" {
fileinto :create "Crans.crans.wiki";
}
# Aurore CA
elsif header :contains "List-Id" "<ca.aurore.lists.crans.org>" {
fileinto :create "Crans.aurore.ca";
}
# BDL
elsif anyof (
header :contains "List-Id" "<bdl-bureau.lists.crans.org>",
header :contains "List-Id" "<bdl.lists.crans.org>"
) {
fileinto :create "Crans.asso.bdl";
}
# Med
elsif anyof (
header :contains "List-Id" "<med-bureau.lists.crans.org>",
header :contains "List-Id" "<med.lists.crans.org>"
) {
fileinto :create "Crans.asso.med";
}
# NL BDE
elsif header :contains "List-Id" "<evenements.lists.crans.org>" {
fileinto :create "Crans.asso.nl.bde";
}
# NL BDA
elsif header :contains "List-Id" "<evenement.bda.lists.crans.org>" {
fileinto :create "Crans.asso.nl.bda";
}
# Any other associative mail
elsif anyof (
header :contains "List-Id" "<la5emeparallele-bureau.lists.crans.org>",
header :contains "List-Id" "<la5emeparallele.lists.crans.org>",
header :matches "List-Id" "<*.lists.crans.org>"
) {
fileinto :create "Crans.asso";
}
# Otherwise it's for the generic mailbox
else {
fileinto :create "Crans";
}
}
# Otherwise it's for my different accounts
# It's automatically sorted using the localpart
elsif address :localpart :regex "X-Original-To" "^(([a-zA-Z]+\\.)*([a-zA-Z]+))(-([a-zA-Z0-9_.\\-]*))?''$" {
set :lower "sub_folder" "''${1}";
set "mbox_candidate" "INBOX.''${sub_folder}";
fileinto :create "''${mbox_candidate}";
}
# Other unknown origin
else {
fileinto :create "INBOX.other";
}
}
# It's destined to my main inbox
elsif address :is "X-Original-To" "lyes@mail.lyes.eu" {
fileinto :create "INBOX";
}
# Other unknown origin
else {
fileinto :create "INBOX.other";
}
'';
postfix = {
filter = "(&(memberof=taf_users)(mail=%s))";
mailAttribute = "mail";
uidAttribute = "name";
};
};
# fullTextSearch = {
# enable = true;
# autoIndex = true;
# enforced = "body";
# };
# loginAccounts = {
# "lyes@mail.lyes.eu" = {
# # hashedPasswordFile = config.age.secrets.lyes-mail-passwd.path;
# # aliases = [
# # "@lyes.eu"
# # ];
# # quota = "1T";
# };
# };
# extraVirtualAliases = {
# "@lyes.eu" = "lyes@mail.lyes.eu";
# "@lyes.eu" = "lyes";
# "abuse@mail.lyes.eu" = "lyes";
# # "abuse@minish.fr" = "lyes";
# # "abuse@minish.link" = "lyes";
# "postmaster@mail.lyes.eu" = "lyes";
# # "postmaster@minish.fr" = "lyes";
# # "postmaster@minish.link" = "lyes";
# };
x509.useACMEHost = config.mailserver.fqdn;
};
services.postfix = {
mapFiles."valias" = lib.mkForce aliasFile;
mapFiles."vaccounts" = lib.mkForce aliasFile;
virtual = lib.mkForce alias;
settings = {
main = {
# local_recipient_maps = "";
# virtual_alias_maps = lib.mkForce "ldap:/run/postfix/ldap-virtual-mailbox-map.cf";
maximal_queue_lifetime = "31d";
relay_domains = [
"skaven.org"
"agreg.info"
];
smtpd_recipient_restrictions = [
"permit_mynetworks"
"permit_sasl_authenticated"
];
};
};
};
# services.dovecot2.extraConfig = ''
# userdb {
# driver = ldap
@ -200,7 +128,10 @@
# }
# '';
services.dovecot2.sieve.extensions = [ "imap4flags" ];
services.dovecot2 = {
# enableQuota = lib.mkForce false;
sieve.extensions = [ "imap4flags" ];
};
services.roundcube = {
enable = true;
@ -217,21 +148,12 @@
age.secrets = {
taf-token = {
owner = "postfix";
file = ../../../secrets/zora/services/taf-token.age;
};
lyes-mail-passwd = {
owner = "postfix";
file = ../../../secrets/lyes/mail-passwd.age;
};
lyes-hidden-sieve = {
file = ../../../secrets/lyes/hidden-sieve.age;
path = "/var/sieve/lyes@mail.lyes.eu/scripts/hiddensieve.sieve";
owner = "virtualMail";
group = "virtualMail";
mode = "660";
};
# lyes-mail-passwd = {
# owner = "postfix";
# file = ../../../secrets/lyes/mail-passwd.age;
# };
};
}

View file

@ -8,7 +8,7 @@ in
{
# Lyes
"secrets/lyes/mail-passwd.age".publicKeys = [ lyes zora ];
"secrets/lyes/hidden-sieve.age".publicKeys = [ lyes zora ];
"secrets/lyes/sieve.age".publicKeys = [ lyes zora ];
# Zora
"secrets/zora/services/kanidm-admin-password.age".publicKeys = all;

Binary file not shown.

BIN
secrets/lyes/sieve.age Normal file

Binary file not shown.

View file

@ -0,0 +1,8 @@
{ ... }:
{
imports =
[
./sieve.nix
];
}

View file

@ -0,0 +1,13 @@
{ ... }:
{
age.secrets = {
lyes-sieve = {
file = ../../../secrets/lyes/sieve.age;
path = "/var/sieve/lyes@taf.lyes.eu/default.sieve";
owner = "virtualMail";
group = "virtualMail";
mode = "660";
};
};
}