Ldap – Emails are bounced with ‘user unknown’ when using LDAP in Postfix virtual config

dovecotldappostfix

I have been tackling this problem for several days and seem to have exhausted all troubleshooting, so thought I'd reach out to the community for any help.

Without introducing OpenLDAP into the mail infrastructure, Postfix and Dovecot have been operating well. For the last several days the Postfix MTA was configured with virtual LDAP settings, but emails are showing a bounced status even though Postfix can read and knows these real mail users, mail aliases and virtual domains exist. Here are the pertinent virtual settings in my Postfix main.cf.

NOTE: There are only 3 virtual LDAP configs

virtual_uid_maps = static:5000
virtual_gid_maps = static:5000
virtual_minimum_uid = 5000
virtual_mailbox_domains = ldap:/etc/postfix/ldap-virtual-domains.cf
virtual_mailbox_maps = ldap:/etc/postfix/ldap-vmailbox.cf
virtual_alias_maps = ldap:/etc/postfix/ldap-aliases.cf
virtual_mailbox_limit = 512000000
virtual_mailbox_base = /home/vmail
transport_maps = hash:/etc/postfix/transport

Here are the contents of each virtual LDAP file.

ldap-virtual-domains.cf

server_host = ldap://ldap.example.net/
search_base = ou=Domains,dc=example,dc=net
version = 3
bind = no
query_filter = (&(ObjectClass=dNSDomain)(dc=%s))
result_attribute = dc

ldap-vmailbox.cf

server_host = ldap://ldap.example.net/
search_base = ou=Mail,dc=example,dc=net
version = 3
bind = no
query_filter = (&(objectclass=inetOrgPerson)(mail=%s))
result_attribute = mail

ldap-aliases.cf

server_host = ldap://ldap.example.net/
search_base = ou=Mail,dc=example,dc=net
version = 3
bind = no
query_filter = (&(objectclass=inetLocalMailRecipient)(mailLocalAddress=%s))
result_attribute = mail

Verifying Postfix can read and process all 3 virtual LDAP files is successful

ldap-virtual-domains.cf:

postmap -q example.net ldap:/etc/postfix/ldap-virtual-domains.cf
example.net
postmap -q example.org ldap:/etc/postfix/ldap-virtual-domains.cf
example.org
postmap -q example.com ldap:/etc/postfix/ldap-virtual-domains.cf
example.com

ldap-vmailbox.cf:

postmap -q user1@example.net ldap:/etc/postfix/ldap-vmailbox.cf
user1@example.net
postmap -q user2@example.net ldap:/etc/postfix/ldap-vmailbox.cf
user2@example.net
postmap -q user3@example.net ldap:/etc/postfix/ldap-vmailbox.cf
user3@example.net

ldap-aliases.cf:

postmap -q alias1@example.org ldap:/etc/postfix/ldap-aliases.cf
user1@example.net
postmap -q alias2@example.org ldap:/etc/postfix/ldap-aliases.cf
user2@example.net

This is what I see in the mail logs:

Oct 26 16:54:17 example.net postfix/cleanup[2789]: 3D26A105CC: info: header Subject: testing virtual LDAP from [REDACTED]; from=tony@macbook-air.moon to=user1@example.net proto=ESMTP helo=macbook-air.moon
Oct 26 16:54:17 example.net postfix/cleanup[2789]: 3D26A105CC: message-id=20151026235417.139081C7F821@macbook-air.moon
Oct 26 16:54:17 example.net opendkim[11877]: 3D26A105CC: [REDACTED] not internal
Oct 26 16:54:17 example.net opendkim[11877]: 3D26A105CC: not authenticated
Oct 26 16:54:17 example.net opendkim[11877]: 3D26A105CC: no signature data
Oct 26 16:54:17 example.net postfix/qmgr[26221]: 3D26A105CC: from=tony@macbook-air.moon, size=571, nrcpt=1 (queue active)
Oct 26 16:54:17 example.net postfix/smtpd[2461]: disconnect from [REDACTED] ehlo=1 mail=1 rcpt=1 data=1 quit=1 commands=5
Oct 26 16:54:17 example.net postfix/pipe[2791]: 3D26A105CC: to=user1@example.net, relay=dovecot, delay=0.12, delays=0.08/0.01/0/0.02, dsn=5.1.1, status=bounced (user unknown)
Oct 26 16:54:17 example.net postfix/cleanup[2789]: 55F2B1080A: message-id=20151026235417.55F2B1080A@mail.example.net
Oct 26 16:54:17 example.net postfix/qmgr[26221]: 55F2B1080A: from=, size=2460, nrcpt=1 (queue active)
Oct 26 16:54:17 example.net postfix/bounce[2793]: 3D26A105CC: sender non-delivery notification: 55F2B1080A
Oct 26 16:54:17 example.net postfix/qmgr[26221]: 3D26A105CC: removed
Oct 26 16:54:17 example.net postfix/smtp[2794]: 55F2B1080A: to=tony@macbook-air.moon, relay=none, delay=0.02, delays=0/0.01/0/0, dsn=5.4.4, status=bounced (Host or domain name not found. Name service error for name=macbook-air.moon type=A: Host not found)

Valid mail accounts existing in LDAP show this in the logs:

Oct 26 16:56:14 example.net postfix/pipe[3592]: 457871080A: to=vmail@example.net, orig_to=montest@example.net, relay=dovecot, delay=0.03, delays=0.01/0/0/0.02, dsn=5.1.1, status=bounced (user unknown)

vmail@example.net is a real mail address in LDAP and montest@example.net is a real alias in LDAP. Postfix has no problem finding them when validating with postmap -q.

Here is the full Postfix config:

alias_database = $alias_maps
alias_maps = hash:/etc/postfix/aliases
append_dot_mydomain = no
broken_sasl_auth_clients = yes
command_directory = /usr/bin
compatibility_level = 2
daemon_directory = /usr/lib/postfix/bin
data_directory = /var/lib/postfix
debug_peer_level = 2
debug_peer_list = 127.0.0.1
debugger_command = PATH=/bin:/usr/bin:/usr/local/bin:/usr/X11R6/bin ddd $daemon_directory/$process_name $process_id & sleep 5
header_checks = regexp:/etc/postfix/header_checks
home_mailbox = Maildir/
html_directory = no
inet_interfaces = all
inet_protocols = ipv4
mail_owner = postfix
mail_spool_directory = /var/spool/mail
mailbox_command = /usr/lib/dovecot/deliver
mailq_path = /usr/bin/mailq
manpage_directory = /usr/share/man
message_size_limit = 20480000
meta_directory = /etc/postfix
milter_default_action = accept
milter_protocol = 2
mydestination =
mydomain = example.net
myhostname = mail.$mydomain
mynetworks = 127.0.0.0/8 10.8.0.0/24 192.168.128.0/17 [SERVER IP REDACTED] [::1]/128 [2600:3c01::]/64 [fe80::]/64
myorigin = $mydomain
newaliases_path = /usr/bin/newaliases
non_smtpd_milters = inet:127.0.0.1:8891
queue_directory = /var/spool/postfix
readme_directory = /usr/share/doc/postfix
recipient_delimiter = +
sample_directory = /etc/postfix/sample
sendmail_path = /usr/bin/sendmail
setgid_group = postdrop
shlib_directory = /usr/lib/postfix
smtp_tls_mandatory_protocols = !SSLv2,!SSLv3
smtp_tls_note_starttls_offer = yes
smtp_tls_protocols = !SSLv2,!SSLv3
smtp_tls_security_level = may
smtpd_error_sleep_time = 1s
smtpd_hard_error_limit = 20
smtpd_milters = inet:127.0.0.1:8891
smtpd_recipient_restrictions = permit_sasl_authenticated, permit_mynetworks, reject_unauth_destination, check_policy_service inet:mail.example.net:12340
smtpd_sasl_auth_enable = yes
smtpd_sasl_authenticated_header = yes
smtpd_sasl_local_domain =
smtpd_soft_error_limit = 10
smtpd_tls_CAfile = /etc/postfix/ssl/PositiveSSL.ca-bundle
smtpd_tls_cert_file = /etc/postfix/ssl/STAR_example_net.crt
smtpd_tls_key_file = /etc/postfix/ssl/key.pem
smtpd_tls_loglevel = 1
smtpd_tls_mandatory_protocols = !SSLv2,!SSLv3
smtpd_tls_protocols = !SSLv2,!SSLv3
smtpd_tls_received_header = yes
smtpd_tls_security_level = may
smtpd_tls_session_cache_timeout = 3600s
smtpd_use_tls = yes
tls_random_source = dev:/dev/urandom
transport_maps = hash:/etc/postfix/transport
unknown_local_recipient_reject_code = 550
virtual_alias_maps = ldap:/etc/postfix/ldap-aliases.cf
virtual_gid_maps = static:5000
virtual_mailbox_base = /home/vmail
virtual_mailbox_domains = ldap:/etc/postfix/ldap-virtual-domains.cf
virtual_mailbox_limit = 512000000
virtual_mailbox_maps = ldap:/etc/postfix/ldap-vmailbox.cf
virtual_minimum_uid = 5000
virtual_transport = dovecot
virtual_uid_maps = static:5000

Example of a valid user in LDAP with multiple aliases

LDAP user

It seems I am so close, but maybe another set of eyes can provide some insight towards resolving this problem. Any input is greatly appreciated.

UPDATE 1

I managed to resolve the status=bounced (user unknown) errors by changing the value of virtual_transport in main.cf from

virtual_transport = dovecot

to

virtual_transport = lmtp:unix:private/dovecot-lmtp

In master.cf I changed this line

dovecot unix - n n - - pipe flags=DRhu user=vmail:vmail argv=/usr/lib/dovecot/deliver -d ${recipient}

to this line

dovecot unix - n n - - pipe
flags=DRhu user=vmail:vmail argv=/usr/lib/dovecot/dovecot-lda -f ${sender} -d ${recipient}

I added a new user in LDAP called postmaster@example.net and a quick postmap -q proves Postfix knows about postmaster@example.net, but then I see this error.

Oct 26 23:46:46 example.net dovecot: quota-status(postmaster@example.net): Error: User initialization failed: Namespace '': stat(/home/vmail/postmaster/.Maildir) failed: Permission denied (euid=5003() egid=5000(vmail) missing +x perm: /home/vmail, dir owned by 5000:5000 mode=0700)
Oct 26 23:46:46 example.net postfix/smtpd[25851]: NOQUEUE: reject: RCPT from[REDACTED]: 450 4.7.1 : Recipient address rejected: Invalid user settings. Refer to server log for more information.; from= to= proto=ESMTP helo=

After a bit more research I started looking at my Dovecot LDAP config, specifically dovecot-ldap.conf.ext

hosts = ldap.example.net
auth_bind = no
ldap_version = 3
base = ou=Mail,dc=example,dc=net
deref = never
scope = subtree
user_attrs = uidNumber=uid,gidNumber=gid,mailHomeDirectory=home,quotaBytes=quota_rule=*:bytes=%$
user_filter = (&(objectclass=inetOrgPerson)(mail=%u))
pass_attrs = mail=user,userPassword=password
pass_filter = (&(objectClass=posixAccount)(uid=%u))
default_pass_scheme = SSHA

I no longer see user unknown in the mail logs, but I do see failed login attempts. I don't know for sure, but think this could be from the user_attrs or any other LDAP attributes from my dovecot-ldap.conf.ext.

Oct 27 00:01:19 example.net dovecot: imap-login: Disconnected (auth failed, 1 attempts in 2 secs): user=<vmail@example.net>, method=PLAIN, rip=192.168.176.128, lip=192.168.176.128, TLS: Disconnected, session=<w/r1pBAj0YjAqLCA>

UPDATE 2

I created an admin account in OpenLDAP called Dovecot and gave it read access with this line

by dn="uid=dovecot,ou=System,dc=example,dc=net" read

Dovecot is now successful in reading the userPassword attribute. Here is how dovecot-ldap.conf.ext looks like with binding enabled.

hosts = ldap.example.net
auth_bind = yes
auth_bind_userdn = uid=%u,ou=Mail,dc=example,dc=net
dn = uid=dovecot,ou=System,dc=example,dc=net
dnpass = password
ldap_version = 3
base = ou=Mail,dc=example,dc=net
deref = never
scope = subtree
user_filter = (&(objectclass=inetOrgPerson)(mail=%u))
pass_filter = (&(objectclass=inetOrgPerson)(mail=%u))
default_pass_scheme = SSHA
user_attrs = uidNumber=uid,gidNumber=gid,mailHomeDirectory=,quotaBytes=quota_rule=*:bytes=%$
pass_attrs = mail=uid,userPassword=password

When trying to log into the vmail account I see Dovecot could not find the user from userdb

Oct 27 20:42:47 example.net dovecot: auth: Error: ldap(vmail,192.168.176.128,<8C7h/CEjo5DAqLCA>): user not found from userdb
Oct 27 20:42:47 example.net dovecot: imap: Error: Authenticated user not found from userdb, auth lookup id=4111597569 (client-pid=26724 client-id=1)
Oct 27 20:42:47 example.net dovecot: imap-login: Internal login failure (pid=26724 id=1) (internal failure, 1 successful auths): user=<vmail>, method=PLAIN, rip=192.168.176.128, lip=192.168.176.128, mpid=26726, secured, session=<8C7h/CEjo5DAqLCA>

If I change the user_filter attribute to the below line I can login successfully.

user_filter = (&(objectClass=posixAccount)(uid=%u))

But then messages begin bouncing again.

Oct 27 20:46:09 example.net postfix/smtp[27702]: ECA4F10848: to=<tony@macbook-air.moon>, relay=none, delay=0.16, delays=0.01/0.01/0.14/0, dsn=5.4.4, status=bounced (Host or domain name not found. Name service error for name=macbook-air.moon type=A: Host not found)

Oct 27 20:46:08 example.net postfix/lmtp[27698]: E0994102FA: to=<tony@example.net>, relay=example.net[private/dovecot-lmtp], delay=0.06, delays=0.05/0.01/0/0, dsn=5.1.1, status=bounced (host mail.example.net[private/dovecot-lmtp] said: 550 5.1.1 <tony@example.net> User doesn't exist: tony@example.net (in reply to RCPT TO command))

At this point I think the problem might be the user and pass filters, but I really don't know anymore. This is the current Dovecot config from dovecot -n and the LDAP portion of Dovecot: http://ix.io/lEE

I hope this can all provide clues as to what might be missing or messed up so that user logins and sending/receiving mail are successful.

Best Answer

pass_attrs = mail=user,userPassword=password

is probably wrong. It means "use mail as username ldap attribute name and userPassword as password attribute name".

I believe it should read:

pass_attrs = mail=uid,userPassword=password

You can check it by looking the OpenLDAP logs.

I am also suspicious on the:

user_attrs = mailHomeDirectory=home

because there is a semantic clash. LDAP attribute home is used for the Unix home dir, but now it is used as the maildir location. Could you double check this as well?