August 27, 2011

Postfix smarthost with SMTP authentication

The problem I’m facing is that emails from my Debian box are not sent outside of my local network. Glad I found the solution, and here is how to go about it. This solution applies to the following issues

Assumptions:

Debian/Ubuntu package Exim4 as the default MTA (Mail Transfer Agent), since I’m not a full-time administrator, I prefer a quick, easy, understandable, & secure solution and found Postfix as a quick win. First thing to do is to uninstall Exim4 and install Postfix. Below is one way to go about it using apt.

    # i have used --purge to remove any configurations that exim4 came with.
    # if you are not sure, drop --purge from the command.  
    $ sudo apt-get remove --purge exim4 exim4-base exim4-config exim4-daemon-light`


    # installing postfix
    $ sudo apt-get install postfix

During the installation of Postfix, you will be asked a series of questions.
Mark them as below

Please select the mail server configuration type that best meets your needs.

The “mail name” is the domain name used to “qualify” ALL mail addresses without a domain name.

Please specify a domain, host, host:port, [address] or [address]:port. Use the form [destination] to turn off MX lookups.

Mail for the ‘postmaster’, ‘root’, and other system accounts needs to be redirected to the user account of the actual system administrator.

Please give a comma-separated list of domains for which this machine should consider itself the final destination.

If synchronous updates are forced, then mail is processed more slowly.

Please specify the network blocks for which this host should relay mail.

Please choose whether you want to use procmail to deliver local mail.

Please specify the limit that Postfix should place on mailbox files to prevent runaway software errors.

Please choose the character that will be used to define a local address extension.

Internet protocols to use

Once installation is complete, Postfix MTA is started up automatically as a service. Stop the service as we still need to configure some vital options. To begin with, all configuration files of Postfix in Debian/Ubuntu are stored under /etc/postfix. One file we would be most interested in is /etc/postfix/main.cf. It’s the main configuration file for Postfix, and this is how it looks just after installation.

    # See /usr/share/postfix/main.cf.dist for a commented, more complete version
    # Debian specific: Specifying a filename will cause the first
    # line of that file to be used as the name. The Debian default
    # is /etc/mailname.
    #myorigin = /etc/mailname

    smtpd_banner = $myhostname ESMTP $mail_name (Debian/GNU)
    biff = no  # appending .domain is the MUA's job.
    append_dot_mydomain = no

    # Uncomment the next line to generate "delayed mail" warnings
    #delay_warning_time = 4h
    readme_directory = no # TLS parameters
    smtpd_tls_cert_file=/etc/ssl/certs/ssl-cert-snakeoil.pem
    smtpd_tls_key_file=/etc/ssl/private/ssl-cert-snakeoil.keys
    mtpd_use_tls=yes
    smtpd_tls_session_cache_database = btree:${data_directory}/smtpd_scache
    smtp_tls_session_cache_database = btree:${data_directory}/smtp_scache 
    # See /usr/share/doc/postfix/TLS_README.gz in the postfix-doc package for
    # information on enabling SSL in the smtp client.
    myhostname = saraswathi.om.loc
    alias_maps = hash:/etc/aliases
    alias_database = hash:/etc/aliases
    myorigin = /etc/mailname
    mydestination = saraswathi.om.loc, localhost.om.loc, localhost
    relayhost = smtp.gmail.com:587
    mynetworks = 127.0.0.0/8 [::ffff:127.0.0.0]/104 [::1]/128
    mailbox_command = procmail -a "$EXTENSION"
    mailbox_size_limit = 0  
    recipient_delimiter = +
    inet_interfaces = all  
    inet_protocols = ipv4

The next step is to configure your service provider’s SMTP credentials, which will be kept in a separate file and will be hashed. Later, you might wish to remove the plain text file for additional security. To achieve this, follow the steps below

    # if the folder "sasl" doesn't exist, create it
    $ cd /etc/postfix/sasl

    # your smtp configuration should match exactly as it's described 
    # in main.cf file
    $ sudo sh -c "echo 'smtp.gmail.com:587 username:password' >> passwd"

    # make the file "passwd" root read/write
    $ sudo chmod 600 ./passwd

    # let's hash the file
    $ sudo postmap hash:passwd

    # you should see a second file in the folder named "passwd.db"
    # to test if the file was created correctly, you can delete the normal text
    # file and run this command, note it would print username:password
    $ sudo postmap -q smtp.gmail.com:587 username:password

After we have added SMTP credentials, we have to configure Postfix to use those credentials to send your emails. Append /etc/postfix/main.cf like

    ### BEGIN NON DEBCONF ENTRIES ###
    smtp_sasl_auth_enable = yes
    smtp_sasl_password_maps = hash:/etc/postfix/sasl/passwd
    smtp_sasl_security_options = noanonymous
    ....

As most of the SMTP service providers use TLS security, we need to configure it in /etc/postifx/main.cf as

    ...
    # TLS
    smtp_sasl_tls_security_options = noanonymous
    smtp_use_tls = yes
    smtp_tls_CAfile = /etc/ssl/certs/ca-certificates.crt
    ...

Hang on, I know it’s been a long journey, we are almost there. When your server sends an email, it sends from the logged-in user. So in my case if I am logged in as “natarajmb” to box “saraswathi.om.loc” any mail that’s sent from me will be sent as “[email protected]” which is correct but, SMTP servers (outside Gmail, AOL or Yahoo!! and so on) don’t accept emails sent from other user or domain apart from the logged in SMTP user. Hence, before the mail is left by Postfix, it needs to rewrite the email headers, mostly the “From” field, to satisfy SMTP servers. Note: Most MTAs offer this functionality.

    # create a file named "generic" to hold user / domain mapping
    $ cd /etc/postfix
    $ sudo sh -c "echo '[email protected] [email protected]' >> generic"

    # hash the file
    $ sudo postmap hash:generic

Now we need to configure this mapping file in the main.cf, which is done by adding the “smtp_generic_maps” property.

    ...
    smtp_generic_maps = hash:/etc/postfix/generic
    ...

Last but not least, most SMTP servers block accounts if they are sending emails continuously, so to avoid any such incidents, you’d better prepare Postfix to behave by adding these lines to the main.cf

    ...
    smtp_destination_rate_delay = 60
    relay_destination_rate_delay = 60
    ...

We are at the end of the tunnel. Start your Postfix server and fire some emails to test. You might be interested in the following commands to do your tests.

    # to send some test mails
    $ mail -s "Syslog file" [email protected] < /var/log/syslog

    # check mail queue
    $ sudo mailq

    # postfix log to troubleshoot errors
    $ sudo tail -f /var/log/mail.log

© Nataraj Basappa 2025