Postfix smarthost with SMTP authentication | Day in my life

August 27, 2011

Postfix smarthost with SMTP authentication

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

Assumptions:

Debian/Ubuntu package Exim4 as the default MTA (Mail Transfer Agent) since I’m not a full time administrator I prefer quick, easy, understandable & secure solution and found Postfix as 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 of the command.  
    $ sudo apt-get remove --purge exim4 exim4-base exim4-config exim4-daemon-light`


    # installing postfix
    $ sudo apt-get install postfix

During installation of Postfix you will be asked series of question, 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 is stored under /etc/postfix. One file we would be most interested in is /etc/postfix/main.cf. Its 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

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 plain text file for additional security. To achieve this following below steps

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

    # your smtp configuration should match exactly as its 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

    # lets 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 mails. 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 its a been a long journey we are almost there. When your server sends an email it would send as 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 “natarajmb@saraswathi.om.loc” 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 from Postfix it needs to rewrite the email headers mostly “From” field to satisfy SMTP servers. Note: Most MTA’s offer this functionality.

    # create a file named "generic" to hold user / domain mapping
    $ cd /etc/postfix
    $ sudo sh -c "echo 'natarajmb@saraswathi.om.loc test@gmail.com' >> generic"

    # hash the file
    $ sudo postmap hash:generic

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

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

Last but not the least, most SMTP servers block accounts if they are sending emails continuously, so to avoid any such incidents you better prepare Postfix to behave by adding this to lines to 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" me@gmail.com < /var/log/syslog

    # check mail queue
    $ sudo mailq

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

© Nataraj Basappa 2021