I have a mail server that can receive mail for users that are in a MySQL database, and lets them download those message via POP3s. This is all working fine. My PostFix version is 2.7.0, on Ubuntu Server 10.04.

The problem is sending mail. There are several issues:

1. The server listens on port 25, but ISPs block 25 so I need to add a listen port. Should this be 465 or 587? or both? How do I add an additional port for secure SMTP?

I need to accept all connections on 25 without authentication, but accept mail only for valid recipients/domains on the system and block relaying. This is currently working.

Port 587 or 465 should allow relaying to any address/domain but only for valid users who authenticate.

The top of my master.cf file is:

smtp      inet  n       -       -       -       -       smtpd
#submission inet n       -       -       -       -       smtpd
#  -o smtpd_tls_security_level=encrypt
#  -o smtpd_sasl_auth_enable=yes
#  -o smtpd_client_restrictions=permit_sasl_authenticated,reject
#  -o milter_macro_daemon_name=ORIGINATING
#smtps     inet  n       -       -       -       -       smtpd
#  -o smtpd_tls_wrappermode=yes
#  -o smtpd_sasl_auth_enable=yes
#  -o smtpd_client_restrictions=permit_sasl_authenticated,reject
#  -o milter_macro_daemon_name=ORIGINATING

I'm guessing I can uncomment one of those lines, but I don't know which one or which options to uncomment.

Also, why doesn't the SMTP have a reject restriction? Is it because it always accepts everything on port 25 and then decides whether to keep them later on? Where do messages go that come in on port 25 but don't have a valid domain here? I have a catchall for the domain we serve. Would they bounce them back? I read bouncing was bad because it could make you look like a spammer.

2. My users are already in a MySQL database for incoming mail, and I'd like to use this same database for allowing outgoing messages.

main.cf looks like:

smtpd_banner = $myhostname ESMTP $mail_name
biff = no
append_dot_mydomain = no    
readme_directory = no

# TLS parameters
smtpd_sasl_auth_enable = yes
broken_sasl_auth_clients = yes
smtpd_sasl_authenticated_header = yes
smtpd_recipient_restrictions = permit_mynetworks, permit_sasl_authenticated, reject_unauth_destination
smtpd_use_tls = yes
smtpd_tls_cert_file = /etc/ssl/certs/mail.crt
smtpd_tls_key_file = /etc/ssl/private/mail.key.insecure 

myhostname = mysite.com
alias_maps = hash:/etc/aliases
alias_database = hash:/etc/aliases
myorigin = /etc/mailname
mydestination =
relayhost =
mynetworks = [::ffff:]/104 [::1]/128

mailbox_size_limit = 0
recipient_delimiter = +
inet_interfaces = all

virtual_alias_domains =
virtual_alias_maps = proxy:mysql:/etc/postfix/mysql-forwards.cf, mysql:/etc/postfix/mysql-email.cf
virtual_mailbox_domains = proxy:mysql:/etc/postfix/mysql-domains.cf
virtual_mailbox_maps = proxy:mysql:/etc/postfix/mysql-mailboxes.cf
virtual_mailbox_base = /home/vmail
virtual_uid_maps = static:5000
virtual_gid_maps = static:5000

proxy_read_maps = $local_recipient_maps $mydestination $virtual_alias_maps $virtual_alias_domains $virtual_mailbox_maps $virtual_mailbox_domains $relay_recipient_maps $relay_domains $canonical_maps $sender_canonical_maps $recipient_can$

What do I change to make it authenticate senders from the existing users database?

3. Currently mail from this server created by PHP's mail() command is only being delivered to users that are in the mysql database of valid users. I need PHP to be able to send mail to any user anywhere. Should I setup PHP to authenticate with SMTPs once its working?


I've changed my master.cf to look like this and opened 587 in the Firewall.

smtp      inet  n       -       -       -       -       smtpd
submission inet n       -       -       -       -       smtpd
  -o smtpd_tls_security_level=encrypt
  -o smtpd_sasl_auth_enable=yes
  -o smtpd_client_restrictions=permit_sasl_authenticated,reject

Now I cant telnet in on 587:

telnet xxx.xxx.xxx.xx 587
Trying xxx.xxx.xxx.xx...
Connected to xxx.xxx.xxx.xx.
Escape character is '^]'.
220 mydomain.com ESMTP Postfix
EHLO you
250-SIZE 10240000
250 DSN
MAIL FROM: <me@example.com>
530 5.7.0 Must issue a STARTTLS command first
220 2.0.0 Ready to start TLS

OK, so I have to use TLS which is good, but I don't know how to test further once TLS is running?

When I EHLO on port 25, I get:


I don't want users to be able to send clear text passwords, can I disable plain logins?


My original /etc/postfix/sasl/smtpd.conf :

pwcheck_method: saslauthd
allow_plaintext: true
auxprop_plugin: mysql
sql_user: mailusr
sql_passwd: secret
sql_database: mail
sql_select: select password from users where email = '%u'

The above does this when trying to authenticate:

Feb 27 09:40:00 MyHOSTNAME postfix/smtpd[27274]: < c-65-34-234-133.hsd1.fl.comcast.net[65.34.xxx.xxx]: dGVzdEBhcsEZ2Vdci1jb20=
Feb 27 09:40:00 MyHOSTNAME postfix/smtpd[27274]: xsasl_cyrus_server_next: decoded response: test@mydomain.com
Feb 27 09:40:00 MyHOSTNAME postfix/smtpd[27274]: xsasl_cyrus_server_auth_response: uncoded server challenge: Password:
Feb 27 09:40:00 MyHOSTNAME postfix/smtpd[27274]: > c-65-34-234-133.hsd1.fl.comcast.net[65.34.xxx.xxx]: 334 UGFzc3dvcmQ6
Feb 27 09:40:20 MyHOSTNAME postfix/smtpd[27274]: < c-65-34-234-133.hsd1.fl.comcast.net[65.34.xxx.xxx]: dGVzdGluZw==
Feb 27 09:40:20 MyHOSTNAME postfix/smtpd[27274]: xsasl_cyrus_server_next: decoded response: testing
Feb 27 09:40:20 MyHOSTNAME postfix/smtpd[27274]: warning: c-65-34-234-133.hsd1.fl.comcast.net[65.34.xxx.xxx]: SASL LOGIN authentication failed: authentication failure
Feb 27 09:40:20 MyHOSTNAME postfix/smtpd[27274]: > c-65-34-234-133.hsd1.fl.comcast.net[65.34.xxx.xxx]: 535 5.7.8 Error: authentication failed: authentication failure

I also tried changing the file to the following based on this tutorial that was suggested:

pwcheck_method: authdaemond
mech_list: PLAIN LOGIN
authdaemond_path: courier-authdaemon-socket

But I was unable to create a hard link in the last step of the guide:

ln /var/run/courier/authdaemon/socket courier-authdaemon-socket

Because /var/run is on a separate partition. I created a soft link instead, but auth still failed. I'm think the first example with MySQL seems more correct.


To make smtpd listen on an alternate port, you modify master.cf copy the existing smtpd entry and just change the first field from smtp to 587 or whatever port you want to listen on. If you want to use port 465, uncomment the smtps entry. I would not advise using unecrypted smtp on this port as it will likely just cause confusion and problems with mail clients (since 465 is designated as an ssl port).
The option your looking for to enable authentication is smtpd_sasl_auth_enable=yes and smtpd_recipient_restrictions=permit_sasl_authenticated (which you already have, so you just need to configure it). As you have these settings in your main.cf, they are enabled for all ports. There is no reason to only allow them on ports other than 25. If the mail comes through unauthenticated, then it will only be accepted for local delivery. If it comes through authenticated, it can go anywhere.

I'm not sure what you mean by 'why doesn't the SMTP have a reject restriction?'.

You have to use SASL for authentication. So authentication is provided by an external service which postfix talks to. You can still use your existing MySQL database, you just need to configure an SASL service to use it. Cyrus SASL is the default provider in postfix. More can be read here.

You already have smtpd_recipient_restrictions = permit_mynetworks, and mynetworks =, so anything from localhost will be accepted, including PHP.

NOTE I advise looking at all the options available for smtpd_recipient_restrictions. Just setting this to the values provided here and nothing else can cause undesired behavior. I'd read the postconf man page on all the settings I mentioned so that you understand what theyre doing before you implement them.

| improve this answer | |
  • Thanks, I've changed master.cf and can telnet in on 587 as shown in my update above. But once I issue STARTTLS, I don't know how to test any further. I read that man page this morning but I don't understand the role of Cyrus in this. I need to setup an IMAP server just to authenticate SMTP? PostFix is already using MySQL to determine if incoming mail should be accepted, so something must already be connecting the two? There's something called "Courier" with an "authmysqlrc" file... maybe that it? I think Courier is what's serving the mail as POP3. – Nick Feb 26 '12 at 18:38
  • Cyrus SASL != Cyrus IMAP. 2 separate things. Courier is the same thing, theres Courier IMAP and Courier authdaemon (SASL). If you want to manually test through STARTTLS, you can use openssl. openssl s_client -tls1 -starttls smtp -connect localhost:587 – Patrick Feb 26 '12 at 18:46
  • OK, I can access the server with OpenSSL client. STARTTLS isn't an option anymore, it's just AUTH LOGIN PLAIN- I'm guessing that it figured out it was already encrypted and AUTH LOGIN PLAIN is plain text in a secure tunnel? I have both Courier mail and auth installed. Is it possible to keep using courier auth since I already have it? – Nick Feb 26 '12 at 18:59
  • When trying to login over ssl I get 535 5.7.8 Error: authentication failed: authentication failure. I'm using the correct username and password, base 64 encoded. I think I'm missing something somewhere. Some setting to make Postfix use Courier SASL+MySQL for SMTP auth? – Nick Feb 26 '12 at 18:59
  • I think I need something like: smtp_sasl_password_maps = proxy:mysql:/etc/postfix/mysql-mailboxes.cf but that didn't work. – Nick Feb 26 '12 at 19:08

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.