I'm using Postfix as MTA and relay. Users that wish to send e-mail from a remote system authenticates and Postfix hands that to Dovecot, and this works well. But how can I limit which users can use SMTP+Authentication, without limiting access to POP or IMAP?

To me it doesn't matter if the block is in Dovecot's SASL authentication, or by Postfix looking it up in a table.

Using Postfix 2.9.6 for SMTP, Dovecot 2.0.19 for POP, IMAP and SASL. Virtual users are stored in MySQL 5.5.40.

root@mx1:~# postconf -n
alias_database = hash:/etc/aliases
alias_maps = hash:/etc/aliases
append_dot_mydomain = no
biff = no
config_directory = /etc/postfix
home_mailbox = Maildir/
inet_interfaces = all
mailbox_size_limit = 0
message_size_limit = 51200000
mydestination = localhost, mx1.mydomain.tld
myhostname = virtmx.mydomain.tld
mynetworks = /etc/postfix/mynetworks
myorigin = /etc/mailname
policy-spf_time_limit = 3600s
readme_directory = no
recipient_delimiter = +
relay_domains = proxy:mysql:/etc/postfix/mysql_relay_domains_maps.cf
setgid_group = vmail
smtp_tls_mandatory_ciphers = medium
smtp_tls_mandatory_protocols = !SSLv2,!SSLv3
smtp_tls_note_starttls_offer = yes
smtp_tls_protocols = !SSLv2,!SSLv3
smtp_tls_session_cache_database = btree:${data_directory}/smtp_scache
smtpd_banner = $myhostname ESMTP $mail_name
smtpd_client_restrictions = permit_mynetworks, permit_sasl_authenticated
smtpd_recipient_restrictions = permit_mynetworks, permit_sasl_authenticated, reject_non_fqdn_hostname, reject_non_fqdn_sender, reject_non_fqdn_recipient, reject_unauth_destination, reject_unauth_pipelining, check_policy_service unix:private/policy-spf, reject_rbl_client zen.spamhaus.org, reject_rhsbl_reverse_client dbl.spamhaus.org, reject_rhsbl_helo dbl.spamhaus.org, reject_rhsbl_sender dbl.spamhaus.org
smtpd_sasl_auth_enable = yes
smtpd_sasl_authenticated_header = yes
smtpd_sasl_local_domain = $myhostname
smtpd_sasl_path = private/auth
smtpd_sasl_security_options = noanonymous
smtpd_sasl_tls_security_options = $smtpd_sasl_security_options
smtpd_sasl_type = dovecot
smtpd_sender_restrictions = reject_unknown_sender_domain
smtpd_tls_auth_only = yes
smtpd_tls_cert_file = /etc/postfix/mydomain.tld-virtmx.pem
smtpd_tls_key_file = /etc/postfix/mydomain.tld-virtmx.key
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_database = btree:${data_directory}/smtpd_scache
smtpd_use_tls = yes
tls_medium_cipherlist = AES128+EECDH:AES128+EDH
transport_maps = proxy:mysql:/etc/postfix/mysql_transports_maps.cf
virtual_alias_maps = proxy:mysql:/etc/postfix/mysql_virtual_alias_maps.cf
virtual_gid_maps = static:88
virtual_mailbox_base = /srv/mailbox
virtual_mailbox_domains = proxy:mysql:/etc/postfix/mysql_virtual_domains_maps.cf
virtual_mailbox_maps = proxy:mysql:/etc/postfix/mysql_virtual_mailbox_maps.cf
virtual_minimum_uid = 999
virtual_transport = virtual
virtual_uid_maps = proxy:mysql:/etc/postfix/mysql_virtual_uid_maps.cf

If it helps, these are the SQL queries used:

query = SELECT address FROM mailnetworks WHERE address='%s' and active='Y'

query = SELECT domain FROM maildomains WHERE domain='%s' AND backupmx = 1 AND active = 1

query = SELECT address FROM mailsender WHERE username='%s'

query = SELECT transport FROM maildomains WHERE domain='%s' AND transport != '' AND active=1

query = SELECT goto FROM mailaliases AS a LEFT JOIN maildomains AS dom ON dom.domain=a.domain WHERE address='%s' AND dom.active=1 and a.active=1

query = SELECT domain FROM maildomains WHERE domain='%s' AND backupmx='0' AND active=1

query = SELECT maildir FROM mailboxes AS box LEFT JOIN maildomains AS dom ON dom.domain=box.domain WHERE username='%s' AND dom.active=1 AND box.active=1

query = SELECT uid FROM mailboxes AS box LEFT JOIN maildomains AS dom ON box.domain=dom.domain WHERE username='%s' AND box.active=1 and dom.active=1

This feature was available to postfix version 2.11.

You can use check_sasl_access parameter to enforce restrictions based on SASL username. Of course you need to put it above permit_sasl_authenticated. Please refer to man 5 postconf for complete documentation.

Example configuration, taken from Postfix SASL Howto

# main.cf
smtpd_relay_restrictions = 
    check_sasl_access hash:/etc/postfix/sasl_blacklist,


# sasl_blacklist
# Use this when smtpd_sasl_local_domain is empty.
username   REJECT
# Use this when smtpd_sasl_local_domain=example.com.
username@example.com REJECT
  • Updated the post with my versions. Any idea how to work it out with Dovecot 2.0.19 and Postfix 2.9.6? – Simon Fredriksson Apr 3 '15 at 19:27
  • Can you edit the question and add the output of postconf -n? Maybe we can find a workaround with postfix smtpd_*_restrictions – masegaloeh Apr 3 '15 at 20:34

Some workaround for postfix < 2.11

The author suggested that you need combination of reject_sender_login_mismatch and check_sender_access.

  • Parameter reject_sender_login_mismatch will reject if the sender doesn't defined in their permitted username. Looks like you already have query for this in mysql_sender_maps.cf.

  • Parameter check_sender_access will reject email based on sender.

So, you need something like

smtpd_sender_login_maps = mysql:/etc/postfix/mysql_sender_maps.cf
smtpd_relay_restriction = ...
    check_sender_access hash:/etc/postfix/sasl_reject


username@example.com   REJECT

The alternative is using lightweight postfwd to perform some kind of restriction for SASL username. You can use sasl_username parameter to control this behavior. See this documentation page of postfwd for further information.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.