Dovecot autentikáció Authentik-kel

sziasztok,

a cél, hogy a mail usereket Authentik-ben tároljam és onnan léptessem be őket, plusz egyéb paraméterek is onnan jöjjenek (pl. mail quota). az IMAP szerver egy Dovecot, az SMTP Postfix, utóbbi Dovecot-tal autentikál.

viszonylag kezdő vagyok ezen a területen, de SAML kapcsolatokat már sikerült összelőnöm Authentik-kel, némi tapasztalatom már van, illetve nagyjából tisztában vagyok az alapfogalmakkal.

Az Authentik dokumentáció elég szűkszavú és itt-ott elavult. amit eddig sikerült összeolvasnom a témában, az alapján egy LDAP provider és egy LDAP outpost segítségével tudnám megoldani a feladatot. az Authentik oldal elvileg meg is van, inkább Dovecot oldalon jönne jól a segítség. ez lehet egy jó, kipróbált leírás vagy saját tapasztalat is.

ha másképp is megoldható (vagy csak másképpen), természetesen az is érdekel.

konkrét kérdéseim:

- szükség van ehhez sssd-re Dovecot oldalon, vagy tud direktben kapcsolódni az LDAP outpost-hoz?
- ha utóbbi (nem kell sssd), akkor hogyan, mi a konfig?
- ha sikerül létrehozni a kapcsolatot, és egy új user (akit Authentik-ben hozok létre) először csatlakozik Dovecot-hoz, létrejön automatikusan a maildir-je (user mailbox provisioning), vagy ezt külön konfiguráni kell?
- ha utóbbi, akkor hogyan, mi a konfig? auto = subscribe a mappákra elég? Inbox is létrejön így?

köszi minden építő hozzászólást!

Hozzászólások

Szerkesztve: 2023. 02. 12., v – 16:41

Az egyetlen jó tanács, hogy mielőtt levelezés kiszolgálásba fogsz ismerd meg a szoftver előtte amennyire ezt lehetséges. A "mi a config" jellegű kérdések pedig csak tőled függnek. Érteni kell mit szeretnél és az adott lehetőség mit ad. 

A releváns kérdésekre vonatkozó segítséget itt találod:

https://doc.dovecot.org/configuration_manual/authentication/ldap/

https://doc.dovecot.org/configuration_manual/mail_location/

 

De erősen javasolt teljesen megismerni és development környezetbe kipróbálni. 

a dev környezet adott, a levelezés kiszolgálás fut és működik. az Authentik fut és két alkalmazás számára autentikál sikeresen. értem, hogy mit szeretnék, le is írtam, kérlek pontosítsd, mi nem derül ki belőle.

a linkelt leírásokat már olvastam, megértettem. sajnos nem találok bennük választ az alábbiakra:

- szükség van ehhez sssd-re Dovecot oldalon, vagy tud direktben kapcsolódni az LDAP outpost-hoz?
- ha utóbbi (nem kell sssd), akkor hogyan, mi a konfig?
- ha sikerül létrehozni a kapcsolatot, és egy új user (akit Authentik-ben hozok létre) először csatlakozik Dovecot-hoz, létrejön automatikusan a maildir-je (user mailbox provisioning), vagy ezt külön konfiguráni kell?
- ha utóbbi, akkor hogyan, mi a konfig? auto = subscribe a mappákra elég? Inbox is létrejön így?

a "mi a config" arra vonatkozott, hogy konkrét segítségre lenne szükségem a konkrét kérdésekkel kapcsolatban, azaz melyik daemon konfigjába írjam pl. az outpost token-jét, sssd vagy dovecot, és mi a szintaxis?

nekem slapd van (openldap server), es ez kell hozza:

# apt-show-versions | grep ldapd
libnss-ldapd:amd64/bullseye 0.9.11-1 uptodate
libpam-ldapd:amd64/bullseye 0.9.11-1 uptodate

/etc/nsswitch.conf:

passwd:         compat ldap systemd                                                                                                                                                                        
group:          compat ldap systemd                                                                                                                                                                        
shadow:         compat ldap                   

/etc/pam.d/dovecot:

#%PAM-1.0

auth            required        pam_ldap.so minimum_uid=10000
account         required        pam_ldap.so minimum_uid=10000
session         required        pam_ldap.so minimum_uid=10000

neked aztan fura humorod van...

ne haragudj, hogy szóváteszem, nem a személyeskedés a cél, hanem a jelenség megfejtése: mi a szándék a hozzászólásaid mögött? mert innen úgy tűnik, birtokában vagy a hasznos válaszoknak, de ezeket nem akarod elárulni. most vagy az van, hogy ez csak üres sejtetés, és valójában nincs konkrét tudás, tapasztalat mögötte, vagy valódi segítő szándék helyett csak a kioktatás a cél, hogy "ismerd meg a szoftver" meg "Érteni kell mit szeretnél" meg olvasd el a dokumentációt. konkrét válasz meg semmi.

ha valaki konkrét kérdést tesz fel, nem feltétlenül az az oka, hogy nincs semmi ismerete, lusta utánaolvasni és kész megoldásokat akar összemásolni. olyan is van, hogy valaki olvas, tanul, próbálkozik, de egy adott, konkrét ponton elakad, és konkrét válaszok segítik a továbbhaladást. ilyenkor a fenti válaszok szerintem nem sokat segítenek, maximum ha pedagógust keres magának valaki, de azok lehet, hogy inkább pedagógus-fórumokat látogatnak.

Az a szándék mögötte, hogy a levelezési rendszerek konfigurálása nem játék. Te nem specifikus kérdéseket tettél fel _miután_ megismerted a terméket, hanem megoldást kerestél. Emellett annak ellenére, hogy _konkrét_ válaszokat (link) kaptál amiben megtudhattad volna, hogy tud LDAP -bol authentikálni, kétféleképp is használhatod, valamint, hogy hogy működik az autosubscribe/autocreate teljes megoldást vársz ami nem indikál mást, minthogy nem kívánod megismerni a szoftvert, hanem fogod az első működőnek tűnő példát és használni kezded. Ami óhatatlanul abban fog végződni, hogy más fog szívni vele. 

a hozzáállásod a "segítségnyújtáshoz" egy állatorvosi ló, kb. "na, megint betévedt közénk, profik közé egy kezdő, aki veszi a bátorságot, hogy ezen a nagyon komoly területen rontsa a profik jóhírét. mert ez bizony rakétatudomány, kisbarátom, nem való akárkinek. aztán majd ha érdemi választ adok a kérdéseidre, visszajössz és újabb kérdéseket teszel fel, és nekem kell szívnom a te hülyeségeddel, hát kösz nem. maradj te csak inkább a játékoknál, ez komoly dolog." legalábbis a válaszodból nagyjából ezt lehet leszűrni. hogy mire alapozod, az nem derült ki számomra.

nem gondolom, hogy kikepzo szintű kérdéseket tettem volna fel, amivel rászolgálnék bármilyen kioktatásra. ha a levelezési rendszerek konfigurálását játéknak tartanám, nem kérnék hozzá segítséget egy "szakmai" fórumon.

a szoftvert sok éve ismerem és használom, több éles levelezőrendszert üzemeltetek. ami újdonság és ismeretlen benne számomra, az az LDAP autentikáció, az eddigi rendszereim mysql backenddel működnek. szerettem volna minél kevesebbet keresgélni olyan irányban, ami nem segít a megoldásban, és egyből jó irányban elindulni, ebben kértem itt segítséget. látod, volt is, akinek sikerült értelmes, használható választ adni rá.

ne zavarjon, hogy a kérdéseim között nem szerepelt olyan, hogy tud-e a Dovecot LDAP-ból autentikálni. ha szerinted nem elég specifikus kérdés, hogy hogyan kell Dovecot-ból Authentik LDAP outpost-hoz kapcsolódni, akkor valóban ne erőltessük.

nagyon komoly területen rontsa a profik jóhírét

Baromságokat írsz össze vissza, én értem, hogy így fogod fel, de ettől totálisan rosszul. Az amit adtam pontosan az a segítség amire szükséged volt, de te nem éltél vele, mert úgy gondolod neked nem halat kell fogni, hanem hal kel, és most azonnal.  Ez a te problémád.

Az én problémám meg az, hogy valaki összehákol ilyen rendszereket, majd ezekből a rendszerekből lesznek gyönyörű célpontok amiket arra használnak, hogy adatot lopjanak. 

én értem, hogy triggerelt az "LDAP", "kezdő" és a "mi a konfig", a többit meg el sem olvastad, ennyi elég volt a sztereotípiáidhoz. amit adtál, az megvolt már, és nem segített, max a user provisioning-hoz adott némi plusz infót.

a kérdés továbbra is az, milyen módon, hogyan lehet Authentik LDAP outpost-ból (tehát _NEM_ LDAP-ból) Dovecot-ba autentikálni. világos, hogy erről fogalmad sincs, de akkor nem kell hozzászólni, hogy olvasd el a doksit (nincs róla, de ha tévednék, belinkelheted), meg hogy tudni kéne, mit szeretnél (a kedvedért leírtam újra), és nem kell úgy tenni, hogy "én tudom, de nem árulom el, hidd el, így teszem veled a legjobbat, olvasgass csak, így tanul a gyerek".

hogy a te problémád micsoda, abba ne menjünk bele, messzire vezetne. hogy velem kapcsolatban milyen hallucinációid vannak, az meg csak a te fejedben létezik, megtarthatod.

a kérdés továbbra is az, milyen módon, hogyan lehet Authentik LDAP outpost-ból (tehát _NEM_ LDAP-ból) Dovecot-ba autentikálni. világos, hogy erről fogalmad sincs,

A ragok ilyen szabad használata eléggé érthetetlenné teszi mit, de én óvnálak attól, hogy ilyeneket írj. Szerintem elég sokan tudják itt mi az az Authentik és mi az az LDAP Outpost.  Hogy azok is érték akik nem, az témanyitó az  Authentik(IDP) LDAP Outpost-járól ( LDAP protokoll fordító az Authentik API-jára, azaz leegyszerűsítve, az IDP belső user adatbázisa érhető el LDAP protokollal) beszél, ami egy kvázi LDAP szerver.

Valóban nem küldtem neked konfigurációs segítséget (linket sem) az Authentik-ről mert a következőt írtad ha jól emlékszem, (de idézem is, nehogy úgy legyen hogy nem) hogy azt teljesen érted:

Az Authentik dokumentáció elég szűkszavú és itt-ott elavult. amit eddig sikerült összeolvasnom a témában, az alapján egy LDAP provider és egy LDAP outpost segítségével tudnám megoldani a feladatot. az Authentik oldal elvileg meg is van, inkább Dovecot oldalon jönne jól a segítség

Azaz egyértelműen a Dovecotról kértél segítséget,  és kaptál egy olyan linket ami válaszol a következő kérdéseidre:

- szükség van ehhez sssd-re Dovecot oldalon, vagy tud direktben kapcsolódni az LDAP outpost-hoz?
- ha utóbbi (nem kell sssd), akkor hogyan, mi a konfig?
- ha sikerül létrehozni a kapcsolatot, és egy új user (akit Authentik-ben hozok létre) először csatlakozik Dovecot-hoz, létrejön automatikusan a maildir-je (user mailbox provisioning), vagy ezt külön konfiguráni kell?
- ha utóbbi, akkor hogyan, mi a konfig? auto = subscribe a mappákra elég? Inbox is létrejön így?

A linken megtudhatod, hogy igen, tudsz közvetlenül LDAP-ból authentikálni (rögtön két módon, és neked _kell_ dönteni, melyiket használod mivel mindennek megvan az előnye és hátránya) valamint választ ad (a második link, példákkal) hogy hogyan oldod meg az autosubscribe/autocreate kérdését. Pl.: fontos lenne eldönteni a mailbox formátumot, még mindig meg kellene nézni és érteni miért lehet esetleg jobb userdb/passdb. 

 én tudom, de nem árulom el, hidd el, így teszem veled a legjobbat, olvasgass csak, így tanul a gyerek

Azt tudom, hogy nekem hogy kell, de pont azért vannak különböző konfigurációs lehetőségek, hogy minél több igényt lefedjen. De megint csak azt javaslom, érdemes lenne elolvasnod amit javasoltam.  

leegyszerusitem neked. Tok mindegy mi van a masik felen, ldap vagy akarmi ami ldap-nak hazudja magat, mert amugy az ldap protokollt hasznalja. Az meg standard. A dovecot-nak meg van ldap auth modulja.

Arrol hogy hogyan tudsz dovecot-ot ldappal authentikalni meg kb csak google keresesek olvasgatasa ha mar a dovecot doksi nem eleg jo neked https://doc.dovecot.org/configuration_manual/authentication/ldap_authen…

Szerkesztve: 2023. 02. 13., h – 04:21

- szükség van ehhez sssd-re Dovecot oldalon, vagy tud direktben kapcsolódni az LDAP outpost-hoz?

Tud. Nálam pl. nincs sssd, nem is léteznek a mailbox felhasználók az OS szintjén.

- ha utóbbi (nem kell sssd), akkor hogyan, mi a konfig?

Lásd dovecot wiki.

- ha sikerül létrehozni a kapcsolatot, és egy új user (akit Authentik-ben hozok létre) először csatlakozik Dovecot-hoz, létrejön automatikusan a maildir-je (user mailbox provisioning), vagy ezt külön konfiguráni kell?

Létrejön.

- ha utóbbi, akkor hogyan, mi a konfig? auto = subscribe a mappákra elég? Inbox is létrejön így?

Attól függ. Ha normál user home-ot használsz (minden usernek más UID), akkor az lesz a gond, hogy a user nevében létre kéne tudnod hozni a hiányzó könyvtárakat (erre létezik persze PAM modul) - ha a home könyvtár amúgy már létezik a user tulajdonában, akkor a mail alkönyvtár menni fog automatikusan. Egyébként sajnos 777-tel kéne léteznie a home könyvtárak parentjének, ami egészen kevéssé secure, ha amúgy a felhasználók is bejelentkezhetnek a gépre. Ha viszont nem jelentkezhetnek, akkor meg sokkal több értelme van konstans UID/GID használatának, így pedig teljesen automatikusan létre tud jönni komplett az új user. Ez egyúttal megoldást ad arra is, hogy ne tudják a felhasználók taperolni a dovecot alatt a fájlokat.

Az a helyzet a konfiggal, hogy nem csak egyetlen adatbázis sémával oldható meg a feladat (és funkcionális különbség is tud lenni), így valójában a sémához és kívánt business logichoz kell illeszteni a konfigot. Ergó nincs egyetlen kanonikus konfig (one size fits all).

Egy mintapéldát be tudok rakni, aztán ebből lehet tanulni. A használt séma (sima OpenLDAP-ot használunk szervernek):

- LDAP binddal authentikálunk, clear text jelszót kell adnia az IMAP kliensnek - erre csak SSL felett hajlandóak a kliensek, ezt kötelezően mi is előírjuk, cserébe az LDAP oldalán bármilyen módon hashelt jelszóval fog menni; az LDAP fában bind nélkül keresünk (lásd pass_filter), a megtalált objektumra nyomunk LDAP bindot (lehetne ez másképp is, pl. külön read-only bind usert adni a dovecotnak, ha nem lehet bind nélkül keresni az LDAP-ban, vagy template-ből generálni az objektum DN-t külön keresés nélkül, olyat is lehet, hogy kiolvassuk a hashelt vagy clear text jelszót valamelyik LDAP mezőből, és az IMAP szerver végzi el az összehasonlítást, nem pedig az LDAP szerver)

- a mailbox felhasználó nem létezik UNIX userként sehol, fixen 8:12 a UID/GID, ami nálam mail:mail, így csak a dovecot tudja, hogy melyik fájl kié, és ez a mailbox felhasználó homeDirectory mezőjéből derül ki (lehetne ez másképp is: pl. lehet séma szerint generálni mondjuk a mailbox nevéből)

- a mailbox a felhasználó home-ja alatt (ez jön az LDAP-ból) egy Maildir nevű könyvtárban lakik (ezt meg a mail_location mondja meg); ez lehetne akár a home is közvetlenül, hiszen úgysem tudja rendes felhasználóként elérni ezt a könyvtárat a delikvens

- az LDAP objektumból látszik, hogy ez tényleg egy mailbox user, semmi másra nem használatos, de lehetne ez másképp is

- az IMAP szervernek identitása van (mail1.example.com), az adott LDAP-ban megtalálható felhasználók nem feltétlenül ezen a szerveren laknak, erre való a mailHost mező - amúgy van az egész előtt egy frontent reverse proxy, ami ugyaninnen authentikál, és a mailHost szerinti backendre továbbítja az IMAP usereket

- a Local Delivery Agent is a dovecot, mégpedig LMTP-n kapja a levelet a hasonlóan előtte lakó eximtől, ami szintén ugyanezen LDAP adatbázisból (meg a mailHost mezőből) tudja, hogy hova kell küldeni a befele jövő leveleket

- a ManageSieve a leírt konfiggal működik

- a mail quota még nincs teljesen felkonfigurálva, hiányzik pl. az attribútum kiolvasása is az ldap.conf-ból, ezzel a konfiggal így még nem csinál semmit

mailbox objektum az LDAP-ban:

dn: mailLocalAddress=mancika@example.com,ou=Mailboxes,dc=example,dc=com
objectClass: inetOrgPerson
objectClass: inetMailRecipient
objectClass: inetMailbox
objectClass: posixAccount
uid: mancika@example.com
cn: mancika@example.com
sn: mancika@example.com
uidNumber: 8
gidNumber: 12
homeDirectory: /home/vmail/example.com/m/ma/mancika
userPassword: xxxxxx
mail: mancika@example.com
mailLocalAddress: mancika@example.com
mailHost: mail1.example.com

ldap.conf:

hosts = 127.0.0.1
base = ou=Mailboxes,dc=example,dc=com
auth_bind = yes
pass_attrs = =user=%{ldap:mailLocalAddress}
pass_filter = (&(objectClass=inetMailbox)(mailLocalAddress=%u)(mailHost=mail1.example.com))
user_attrs = =home=%{ldap:homeDirectory}
user_filter = (&(objectClass=inetMailbox)(mailLocalAddress=%u)(mailHost=mail1.example.com))
iterate_attrs = mailLocalAddress=user
iterate_filter = (&(objectClass=inetMailbox)(mailHost=mail1.example.com))

dovecot.conf:

instance_name = mail1
base_dir = /run/dovecot/
state_dir = /var/lib/dovecot
protocols = lmtp imap sieve
syslog_facility = mail
ssl_cipher_list = ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-SHA:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA:ECDHE-RSA-AES256-SHA384:DHE-RSA-AES128-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES256-SHA:DHE-RSA-AES256-SHA256:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA:AES128-SHA256:AES256-SHA:AES256-SHA256:DES-CBC3-SHA:HIGH:!aNULL:!eNULL:!PSK:!EXPORT:!RC4:!MD5:!DES:!ADK:!CAMELLIA
ssl_cert = </etc/dovecot/mail.example.com.fullchain.crt
ssl_key = </etc/dovecot/mail.example.com.key
ssl_dh = </etc/dovecot/dh.pem
ssl_min_protocol = TLSv1
ssl_prefer_server_ciphers = yes
ssl_options = no_compression
ssl = required
disable_plaintext_auth = yes
auth_username_format = %Lu
auth_mechanisms = plain login
login_greeting = Mail server ready
mail_uid = 8
mail_gid = 12
first_valid_uid = 8
last_valid_uid = 8
first_valid_gid = 12
last_valid_gid = 12
mail_location = maildir:~/Maildir
managesieve_notify_capability = mailto
managesieve_sieve_capability = fileinto envelope encoded-character copy body variables vacation vacation-seconds relational imap4flags subaddress reject enotify mailbox environment date regex editheader ihave spamtest virustest include 
passdb ldap {
  driver = ldap
  args = /etc/dovecot/ldap.conf
}
userdb ldap {
  driver = ldap
  args = /etc/dovecot/ldap.conf
}
service auth {
  unix_listener auth-userdb {
    mode = 0777
  }
  user = mail
}
service auth-worker {
  unix_listener auth-worker {
    mode = 0666
    user = mail
  }
  user = dovecot
}
service managesieve {
  executable = /usr/libexec/dovecot/managesieve
}
service managesieve-login {
  inet_listener sieve {
    address = 172.16.1.1
    port = 4190
  }
  executable = /usr/libexec/dovecot/managesieve-login
  process_limit = 200
  process_min_avail = 8
}
service imap-login {
  inet_listener imap {
    address = 172.16.1.1
    port = 143
  }
  inet_listener imaps {
    address = 172.16.1.1
    port = 993
    ssl = yes
  }
  process_limit = 200
  process_min_avail = 8
}
service lmtp {
  inet_listener lmtp {
    address = 172.16.1.1
    port = 24
  }
  process_limit = 200
  process_min_avail = 8
  user = mail
}
protocol sieve {
  managesieve_max_line_length = 65536
}
protocol imap {
  mail_plugins = quota imap_quota
  mail_max_userip_connections = 30
}
protocol lmtp {
  postmaster_address = discard@example.com
  hostname = mail1.example.com
  submission_host = 172.26.0.15:587
  mail_plugins = quota sieve
  lda_mailbox_autocreate = yes
  lda_mailbox_autosubscribe = no
  lmtp_save_to_detail_mailbox = yes
  lmtp_rcpt_check_quota = yes
  recipient_delimiter = +
}
plugin {
  quota = maildir:User quota
  quota_rule = Trash:ignore
  sieve = ~/.sieve
}

végre megint volt egy kis időm foglalkozni ezzel, és sikerült összelőni az autentikációt. a Dovecot Authentik-ből autentikál, az új usereknek automatikusan létrejön a mailbox-uk első csatlakozáskor, küldés fogadás működik. további kérdéseim, illetve a tapasztalatok, hátha másnak is hasznára válnak:

- mint kiderült, ugyanúgy kell kapcsolódni az Authentik LDAP outpost-hoz, mint egy akármilyen LDAP szerverhez. engem először megzavart a doksiban emlegetett outpost token, illetve az sssd-hez adott konfig, ahol használva van ez a token, de végül kiderült, hogy - legalábbis az én esetemben, ahol az outpost a szerver oldalra van deploy-olva - nincs szükség a tokenre.

- nem sikerült eddig ldaps-sel csatlakoznom (sima ldap-val megy szépen):

dovecot: auth-worker(840469): Error: LDAP /etc/dovecot/ldap.conf: ldap_start_tls_s() failed: Can't contact LDAP server

erre még keresem a megoldást, ha valakinek van jó ötlete, merre keresgéljek, köszönöm ha megosztja velem. wildcard letsencrypt tanúsítványt használok, ugyanazt mindkét oldalon, érvényes.

- Authentik oldalon nem sikerült eddig LDAP property mapping-et összehozni (jó eséllyel nincs is erre lehetőség jelenleg, ami van, az LDAP source-hoz van), jön minden, ami jöhet (azaz a doksiban felsorolt attribútumok: https://goauthentik.io/docs/providers/ldap/). jön még ezeken felül az összes user custom attribute, amit felveszek, nem jön viszont semmilyen group custom attribute, hiába van beállítva group binding az application-re.

- nem szűr az Authentik user "is_active" status-ra, ez azt jelenti, hogy az inaktívra állított userek is szerepelnek a találatok között. van egy "goauthentik.io/ldap/active" attribútum, aminek "true/false" állapota jelzi, mi a helyzet, de nem sikerült szűrni rá, jó eséllyel a "/" karakterek miatt.(goauthentik.io/ldap/active=true)

ldap_search_ext: Bad search filter (-7)

ha van tipp, hogyan tudom escape-elni a slash-eket (többféleképpen is próbálkoztam, sehogy nem ette meg), vagy bármilyen egyéb módon szűrni erre az attribútumra, köszönettel fogadom. sikerült workaroundolni, de szebb és praktikusabb lenne erre szűrni.

- ha ékezet van a displayName-ben, akkor az ldap search eredményben nem az jön name-ben és displayName-ben, hanem valami krixkrax, amiben egyetlen karakter sem stimmel. ékezet nélkül hibátlan.

a konfig file-ok:

ldap.conf

hosts = localhost
#uris = ldaps://auth.example.com
#tls = yes
#tls_key_file = /etc/letsencrypt/live/mail.example.com/privkey.pem
#tls_cert_file = /etc/letsencrypt/live/mail.example.com/cert.pem
#tls_require_cert = demand
base = ou=users,dc=auth,dc=example,dc=com
dn = cn=ldapservice,dc=auth,dc= example,dc=com
dnpass = ldapsecret
auth_bind = yes
blocking = yes
pass_attrs = =user=%{ldap:mailbox}
pass_filter = (&(objectClass=user)(memberOf=cn=Mail,ou=groups,dc=auth,dc=example,dc=com)(mailbox=%u))
user_attrs = =quota=%{ldap:mail_quota}
user_filter = (&(objectClass=user)(memberOf=cn=Mail,ou=groups,dc=auth,dc=example,dc=com)(mailbox=%u))
iterate_attrs = mailbox=user
iterate_filter = (objectClass=user)
debug_level = -1

dovecot.conf

protocols = imap pop3
auth_mechanisms = plain login
disable_plaintext_auth = yes
passdb ldap {
  driver = ldap
  args = /etc/dovecot/ldap.conf
}
userdb ldap {
  driver = ldap
  args = /etc/dovecot/ldap.conf
}
service auth {
  unix_listener /var/spool/postfix/private/auth {
     group = postfix
     mode = 0660
     user = postfix
  }
  user = root
}
mail_home = /home/vmail/%d/%u
mail_location = maildir:~
mail_uid = 5000
mail_gid = 5000
first_valid_uid = 5000
last_valid_uid = 5000
first_valid_gid = 5000
last_valid_gid = 5000
ssl = yes
ssl_cert = </etc/letsencrypt/live/mail.example.com/cert.pem
ssl_key = </etc/letsencrypt/live/mail.example.com/privkey.pem
ssl_min_protocol = TLSv1.2
ssl_dh = </etc/ssl/private/pure-ftpd-dhparams.pem

itt tartok, hátravan még a quota, alias, forward ügyek konfigurálása, úgyhogy folyt.köv., úgy tapasztalatok, mint kérdések terén :)

köszi mindenkinek az eddigi érdemi segítséget, elsősorban vl-nek!

- nem sikerült eddig ldaps-sel csatlakoznom (sima ldap-val megy szépen):

dovecot: auth-worker(840469): Error: LDAP /etc/dovecot/ldap.conf: ldap_start_tls_s() failed: Can't contact LDAP server
erre még keresem a megoldást, ha valakinek van jó ötlete, merre keresgéljek, köszönöm ha megosztja velem. wildcard letsencrypt tanúsítványt használok, ugyanazt mindkét oldalon, érvényes.

Azt kötve hiszem :D

Ugyanis...

hosts = localhost

kizártnak tartom, hogy a "localhost" szerepelne a letsencrypt tanúsítványodban, mint alternatív hostnév.

Lehetséges opciók:

- csinálsz saját CA-t, azzal csinálsz az LDAP-nak tanúsítványt, és csak azt fogadod el a dovecotban
- publikus root CA-val aláírt tanúsítványt használsz - de akkor az ott levő hostnevekkel csatlakozhatsz csak

Személy szerint a második megoldást nem tartom annyira szerencsésnek (ha a dovecotos gép egyúttal nem DNS szervere a domainnek, akkor kifejezetten necces biztonsági szempontból), a domain eltérítésével a securityt is fel tudják törni.

- ha ékezet van a displayName-ben, akkor az ldap search eredményben nem az jön name-ben és displayName-ben, hanem valami krixkrax, amiben egyetlen karakter sem stimmel. ékezet nélkül hibátlan.

Ez szerintem csak egy interface encoding, azaz csak az ldap* parancsok interfészein látod így kódolva az adatot, amúgy base64, és a :: jelzi, hogy ez van.

ha van tipp, hogyan tudom escape-elni a slash-eket (többféleképpen is próbálkoztam, sehogy nem ette meg), vagy bármilyen egyéb módon szűrni erre az attribútumra, köszönettel fogadom. sikerült workaroundolni, de szebb és praktikusabb lenne erre szűrni.

Filterben szerintem bármit lehet használni, sima magyar UTF-8 ékezetes betűkkel megy a keresés - nyilván a szintaxis miatti karaktereket escape-elni kell, viszont szerintem nem backslash + karakter, hanem backslash + hexa kód. Itt van némi okosság összeszedve:  http://www.ldapexplorer.com/en/manual/109010000-ldap-filter-syntax.htm

ldap_start_tls_s() failed: Can't contact LDAP server

Ez a hibaüzenet valamilyen SSL handshake problémát jelent. A leggyakoribbak: invalid a tanúsítvány, pl. lejárt; nem jó a szerver vagy a kliens órája (a tanúsítvány lejárati idején kívül vagyunk az óra szerint); nincs benne a meghívott hostnév a tanúsítványban; hiányzik a szerverből az intermediate tanúsítvány; custom root CA-val készült a tanúsítvány, és az nincs felvéve a kliensen; új publikus root CA-val készült a tanúsítvány, a kliensen pedig túl régi a root CA-k listája; olyan ciphert/protokollt kér a szerver kötelezően, amit a kliens nem tud vagy le van rajta tiltva. Elvileg ha lesniffeled az SSL forgalmat, akkor a wiresharkban a lezáró üzenetben kéne látni, hogy mit mond a lezáró fél, miért nem tetszik neki a handshake.

Lehet tesztelni ldapsearchből, ott ki lehet mókolni, hogy milyen beállításokkal fog menni. Ami engem >1 alkalommal megszopatott, hogy az ldap.conf TLS_* konfigváltozói egyébként env változóként is megadhatóak, de akkor máshogy kell őket hívni (konkrétan az LDAP prefixet elé kell pakolni).

igen, valami ilyen oka lehet, valószínűleg a tls konfig beállításokkal kell játszani. az érdekes az, hogy ldapsearch paranccsal megy, ldaps-sel, 636-os porton, minden extra paraméter nélkül.

ezt a részét egyelőre félretettem, majd ha minden más működik tls nélkül, összelövöm azt is.

alias/forward ügyben ott tartok, hogy vagy az egyik, vagy a másik működik. ezeket a virtual_alias_maps paraméterben linkelt file-ban tudom konfigurálni. a problémám, hogy míg mysql-ben a source rekord tartalmazta alias esetében az alias-t, forward esetén a maildrop-ot, a destination pedig alias esetén a maildrop-ot, forward esetén a forward-ot, így egyetlen query-vel megvolt az összes alias és forward egyben, LDAP-ban külön rekord az alias, a maildrop és a forward, más rekordra kell szűrnöm és más rekordot kell visszaadnom egyik és másik esetben. ha több query-t és result-ot teszek a virtual_alias_maps.cf-be, akkor warning-ot kapok, hogy a második felülírta az elsőt. a kérdés:

hogyan tudom összefűzni egyetlen virtual_alias_maps-ba az alias-t és a forwardot is, vagy hogyan másképp tudom megoldani, hogy mindkettő működjön?

#query_filter = (&(objectClass=user)(memberOf=cn=Mail,ou=groups,dc=auth,dc=example,dc=com)(mail_alias=%s))
#result_attribute = mailbox
query_filter = (&(objectClass=user)(memberOf=cn=Mail,ou=groups,dc=auth,dc=example,dc=com)(mailbox=%s))
result_attribute = mail_forward

annyira én sem sajnos, de szinte biztosan lehet. viszont a probléma másik fele továbbra is fennáll, hogy melyik rekord értéke szerepeljen a result-ban, maildrop (mailbox) vagy forward (mail_forward). és az attól függ, melyik rekordra volt match.

próbáltam két különböző alias.cf-et megadni vesszővel, de úgy sem.

Nálam erre a problémára (nem postfixet használok) az a megoldás, hogy van egy forward szabály, ami kiolvassa a forwarding szabályokat, és egy vagy több új targetet határoz meg, plusz van egy local user szabály, ami viszont a mailboxokat olvassa ki, és az ott levő mailHost mező alapján LMTP-vel küldi a dovecotnak. A forwarding szabályból kieső célcímeket automatikusan kezeli az exim, és ha ott olyan célcím van, ami nem local domain, akkor az automatikusan "kifelé" fog menni. Ha local domainbeli a célcím (azaz valójában local copyt is szeretnénk), akkor azt a példányt a local user szabály alapján fogja kézbesíteni (ugyanezt történik, ha nincs forwarding szabály).

Kicsit lebutítva az exim konfig:

LDAP_Q_LDOMAIN=ldap:://localhost/ou=MailDomains,dc=example,dc=com?mailAccessDomain?sub?(&(objectClass=inetMailDomain)(mailAccessDomain=${quote_ldap:$domain}))
LDAP_Q_MAILACCOUNTHOST=ldap://localhost/ou=Mailboxes,dc=example,dc=com?mailHost?sub?(&(objectClass=inetMailbox)(mailLocalAddress=${quote_ldap:$local_part@$domain}))
LDAP_Q_MAILALIASTARGET=ldap://localhost/ou=MailRouting,dc=example,dc=com?mailForwardingAddress?sub?(&(objectClass=inetMailForwarding)(mailLocalAddress=${quote_ldap:$local_part@$domain}))

domainlist local_domains = ldap;LDAP_Q_LDOMAIN

forward:
  driver = redirect
  domains = +local_domains
  data = ${lookup ldapm{LDAP_Q_MAILALIASTARGET}{$value}fail}

local:
  driver = manualroute
  domains = +local_domains
  route_data = ${lookup ldap{LDAP_Q_MAILACCOUNTHOST}{$value}fail}
  host_find_failed = defer
  transport = remote_lmtp

A Postfix main.cf-be a virtual_alias_maps értéke lehet vesszővel elválasztott felsorolás, és oda írhatsz több olyan akármi.cf-et is, ami mind egy-egy LDAP szűrést és eredményt ad vissza (melyekben a szűrés és az eredmény mező különböző).

Pl. Zentyal-ból kiollózott példa:

main cf:

virtual_alias_maps = ldap:/etc/postfix/valiases.cf,ldap:/etc/postfix/useraliases.cf,ldap:/etc/postfix/groupaliases.cf

valiases.cf:

server_host = localhost:389
version = 3
search_base = cn=alias,cn=mail,cn=zentyal,cn=configuration,DC=domain,DC=org
query_filter = (&(|(mail=%s)(mail=@%s))(objectClass=CourierMailAlias))
result_attribute = maildrop
bind = yes
bind_dn = CN=zentyal-mail-dc,CN=Users,DC=domain,DC=org
bind_pw = ***

useraliases.cf

server_host = localhost:389
version = 3
search_base = DC=domain,DC=org
query_filter = (&(otherMailbox=%s)(objectClass=user))
result_attribute = mail
bind = yes
bind_dn = CN=zentyal-mail-dc,CN=Users,DC=domain,DC=org
bind_pw = ***

groupaliases.cf:

server_host = localhost:389
version = 3
search_base = DC=domain,DC=org
query_filter = (&(mail=%s)(objectClass=group))
leaf_result_attribute = mail
special_result_attribute = member
bind = yes
bind_dn = CN=zentyal-mail-dc,CN=Users,DC=domain,DC=org
bind_pw = ***

Az LDAP-nál az ÉS (&), VAGY (|), NEM (!) amolyan "Polish notation" formában vannak megadva, mind pl. (egyik feltétel ÉS másik feltétel) LDAP-ül: (&(egyik feltétel)(másik feltétel)) Kicsi nehéz írni és olvasni annak, aki modernebb nyelvekhez szokott, de működik.
Pl. a valiases.cf filter-e "leforedítva": ((mail=%s VAGY mail=@%s) ÉS (objectClass=CourierMailAlias))

igen, közben én is arra jutottam, hogy ennek így mennie kellene. viszont az alias még mindig nem megy, aminek az oka innentől valószínűleg az alias cf-ben keresendő:

query_filter = (&(objectClass=user)(memberOf=cn=Mail,ou=groups,dc=auth,dc=example,dc=com)(mail_alias=%s))
result_attribute = mailbox

az LDAP user object:

# test, users, auth.example.com
dn: cn=test,ou=users,dc=auth,dc=example,dc=com
mailbox: test@example.com
mail_alias: testalias@example.com
mail_quota: 1GB
mail_forward: user@otherdomain.com
mail_forward: user@yetanotherdomain.com
mail_forward: otheruser@example.com
gidNumber: xxxx
goauthentik.io/ldap/active: true
mail: something@example.com
cn: test
sAMAccountName: test
uid: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
name: test
displayName: test
objectClass: user
objectClass: organizationalPerson
objectClass: inetOrgPerson
objectClass: goauthentik.io/ldap/user
memberOf: cn=Mail,ou=groups,dc=auth,dc=example,dc=com
goauthentik.io/ldap/superuser: false
uidNumber: xxxx

a forward működik ezzel:

query_filter = (&(objectClass=user)(memberOf=cn=Mail,ou=groups,dc=auth,dc=homebaselab,dc=hu)(mailbox=%s))
result_attribute = mail_forward

hibaüzenet:

<testalias@example.com>: Temporary lookup failure; from=<something@example.com> to=<testalias@example.com> proto=ESMTP helo=<smtpclient.apple>

vagyis nem találja meg az alias-t. mit rontok el?

jogos, belenéztem. az aláhúzással ("_") volt baja a mail_alias-ban a query-ben. pedig ez nem szerepel a doksikban a speciális karakterek között. nem világos, hogy ez LDAP vagy Authentik hülyeség, de nem is érdekel annyira, ezzel már együtt tudok élni.

nagyon köszi a tippet!

felkészül a quota :)

Igazából: https://www.rfc-editor.org/rfc/rfc4512#section-1.4 (descr és keystring), ezzel együtt kb ugyanaz van benne nyilván. Viszont egyrészt a vicces, hogy result_attributeban már működött :) Másrészt annyira jók ezek, hogy hol az underscore nem jó, de kötőjelet szabad, hol fordítva, hol mindkettő, hol egyik se. Folyamatos szívás

jobb későn, mint soha:

DANGER

The use of the goauthentik.io/ldap/active and goauthentik.io/ldap/superuser attributes is deprecated as of authentik 2023.3. They will be removed completely in a future release. Use the replacements fields above instead.

goauthentik.io/ldap/active => ak-active
goauthentik.io/ldap/superuser => ak-superuser

https://goauthentik.io/docs/providers/ldap/

quota tapasztalatok: könnyebb volt, mint vártam. igaz egyelőre csak ennyi van:

dovecot.conf

mail_plugins=quota
plugin {
  quota = maildir:User quota
  quota_rule = *:storage=1G
  quota_rule2 = Trash:storage=+100M
}
protocol imap {
        mail_plugins = $mail_plugins imap_quota
        mail_plugin_dir = /usr/lib/dovecot/modules
}

ldap.conf

user_attrs = =quota_rule=*:storage=%{ldap:mailquota}

a kérdéseim is ezzel függnek össze:

- indokolt ezen túl bármit konfigurálni, ha csak méretkorlátot szeretnék a maildir-ekre? (se warning, se grace, se semmi extra)
- van értelme a postfix quota-t is beállítani? nem világos, mit nyernék vele.

Annyit szeretnék ehhez hozzátenni, hogy a Dovecot 2.2.19 óta a qouta nyilvántartáshoz a count backend a javasolt kvóta kezelési mód (ilyenkor a Dovecot index állományban tartja nyilván a kvótát), és ha máshová is kell az aktuális kvóta állás (pl. DB-be, mert pl. egy webadmin onnan gyorsabban olvassa ki, mint a Dovecot-ot lekérdezve, vagy LDAP-ba kell beírni akármiért), akkor használható a quota_clone plugin a quota mellé (ami a kvótát bármi más nyilvántartásba is bevezeti, de a Dovecot nem onnan olvassa majd ki).

mail_plugins = quota quota_clone

plugin{
  quota = count:User quota
  quota_clone_dict = ... (bármi, ami eddig az előző sorban úgy kezdődött, hogy dict:)

  quota_vsizes = yes (ez szükséges a count backend-hez)
}

Nekem ez úgy került elő nemrég, hogy dict:file:... volt kvóta nyilvántartás helye (ISPconfig default), de olykor nem számolta, vagy nem volt pontos az érték minden fiókra. Az a magyarázat, hogy "igen, nem teljesen biztos a quota dict, nem is ez a javasolt egy jó ideje, hanem a count backend".