Maintaining a (public) service can be sometimes troublesome. In case of email service, often you need to suspend or restrict users for reasons like SPAM, SCAM or Phishing. You have to deal with inactive or even compromised accounts. Protecting your infrastructure is to protect your active users and the service. In this article I’ll propose a way to restrict messages to authorized addresses when sending an email and get a bounce message explaining why their email was not sent.
The reference documentation when having a Directory Service (LDAP) as our user backend and using Postfix:
In this post, we will not get into openldap internals but as reference I’ll show an example user account (this is from my working test lab).
dn: uid=testuser2,ou=People,dc=example,dc=org objectClass: top objectClass: person objectClass: organizationalPerson objectClass: inetOrgPerson objectClass: posixAccount mail: email@example.com smtpd_sender_restrictions: true cn: Evaggelos Balaskas sn: Balaskas givenName: Evaggelos uidNumber: 99 gidNumber: 12 uid: testuser2 homeDirectory: /storage/vhome/%d/%n userPassword: XXXXXXXXXX
as you can see, we have a custom ldap attribute:
keep that in mind for now.
The default value of
smtpd_sender_restrictions is empty, that means by default the mail server has no sender restrictions. Depending on the policy we either can whitelist or blacklist in postfix restrictions, for the purpose of this blog post, we will only restrict (blacklist) specific user accounts.
To do that, let’s create a new file that will talk to our openldap and ask for that specific ldap attribute.
server_host = ldap://localhost server_port = 389 search_base = ou=People,dc=example,dc=org query_filter = (&(smtpd_sender_restrictions=true)(mail=%s)) result_attribute = uid result_filter = uid result_format = REJECT This account is not allowed to send emails, plz talk to firstname.lastname@example.org version = 3 timeout = 5
This is an anonymous bind, as we do not search for any special attribute like password.
The default status code will be:
Take a look here for more info: RFC 3463 - Enhanced Mail System Status Codes
# postmap -q email@example.com ldap:/etc/postfix/ldap_smtpd_sender_restrictions.cf REJECT This account is not allowed to send emails, plz talk to firstname.lastname@example.org
-v to extent verbosity
# postmap -v -q email@example.com ldap:/etc/postfix/ldap_smtpd_sender_restrictions.cf
postmap: fatal: unsupported dictionary type: ldap
Check your postfix setup with
postconf -m . The result should be something like this:
btree cidr environ fail hash internal ldap memcache nis proxy regexp socketmap static tcp texthash unix
If not, you need to setup postfix to support the ldap dictionary type.
Modify the main.cf to add the ldap_smtpd_sender_restrictions.cf
# applied in the context of the MAIL FROM smtpd_sender_restrictions = check_sender_access ldap:/etc/postfix/ldap_smtpd_sender_restrictions.cf
and reload postfix
# postfix reload
If you keep logs, tail them to see any errors.
May 19 13:20:26 centos6 postfix/smtpd: NOQUEUE: reject: RCPT from XXXXXXXX[XXXXXXXX]: 554 5.7.1 <firstname.lastname@example.org>: Sender address rejected: This account is not allowed to send emails, plz talk to email@example.com; from=<firstname.lastname@example.org> to=<email@example.com> proto=ESMTP helo=<[192.168.0.13]>