Postfix + SMTP-AUTH (without MySQL)

This short walkthrough will show you how to install Postfix and get SMTP-AUTH working without having to mess with a MySQL database, all those extra .cf files under /etc/postfix, or pretty much any of the other stuff that's in the Gentoo Mailhosting Guide. To be fair, it's not that the guide is bad; it's just overkill for many Postfix admins who just need a couple of mail accounts under a single domain. If you fall into that category, read on.

Postfix

Ok, so we're using Postfix -- the über-sick mail server of doom. It's about simplicity. Postfix has relatively few moving parts and strikes me as nothing less than beautiful. Anyway, I assume that if you're reading this you don't need to be sold on Postfix. We'll move on.

SMTP-AUTH

I prefer SMTP-AUTH because I tend to travel a lot and don't want face issues with sending mail from continuously changing locations. Essentially, to avoid spammers using your shiny new mail server as a spam relay, you have to lock down who can send mail out of your box. Here are the basic rules:

  1. Anyone can send mail to your domain (incoming)
  2. Only authorized people can send email to other domains (outgoing)
Basically, preventing your system from being a relay means controlling who can send mail from your server to any system other than your own. So anyone should be able to telnet to your box and craft an email that gets delivered locally, but if they can do that and send it to ibm.com then you have a problem.

The most basic way to avoid this in Postfix is to configure the mynetworks option in your main.cf file.

mynetworks = 127.0.0.0/8

What this says is that only people from 127.0.0.0/8 can send mail out of your system, which gets tedious for those that travel. If you use this method then you have to SSH into your box and edit this line every time you want to check your mail from a new IP. Bad form.

That's where SMTP-AUTH comes in. Using it you can just connect in from wherever you are and send your mail normally. This is because the authentication is based on who you are, not where you are connecting from. When this method is used you send username and password credentials when sending mail to let your mail server know it's you. And yes, it's encrypted.

Getting Started

So now that we have all that out of the way, let's get this all up and running. I use Gentoo, but most distros should work without too much trouble.

The advantage of this system is how simple it is; you can literally get this whole thing up and running (including your IMAP server if you are building your mailserver from scratch) in like 5 - 10 minutes.
  1. Install postfix
    Just install it: emerge postfix. The only thing you might consider is installing it without MySQL support, which you can do in Gentoo by using USE="-mysql" right before your emerge command. I do this because it cleans up the logs a bit in terms of database-related errors.

    I also have sasl in my use variables in /etc/make.conf, so if you don't you're going to want to add that to your command as well (you can do this more permanently by placing mail-mta/postfix -mysql into /etc/portage/package.use).

    # USE="sasl -mysql" emerge postfix

  2. Configure postfix

    # vi /etc/postfix/main.cf
    # Basic Settings
    home_mailbox = .maildir/
    alias_maps = hash:/etc/mail/aliases
    mailbox_command = /usr/bin/maildrop
    myhostname = $host.domain.tld
    mydomain = $domain.tld
    inet_interfaces = all
    mydestination = $host.domain.tld, localhost.$domain.tld, $tld, localhost
    mynetworks = 127.0.0.0/8
    local_destination_concurrency_limit = 2
    default_destination_concurrency_limit = 10
    
    # SMTP-AUTH / Encryption Settings
    smtpd_sasl_auth_enable = yes
    smtpd_sasl_security_options = noanonymous
    broken_sasl_auth_clients = yes
    smtpd_sasl_local_domain =
    smtpd_recipient_restrictions =
            permit_sasl_authenticated,
            permit_mynetworks,
            reject_unauth_destination
    smtp_use_tls = yes
    smtp_tls_note_starttls_offer = yes
    smtpd_use_tls = yes
    smtpd_tls_key_file = /etc/postfix/$your.key
    smtpd_tls_cert_file = /etc/postfix/$your.crt
    smtpd_tls_CAfile = /etc/postfix/$some.crt
    smtpd_tls_loglevel = 3
    smtpd_tls_received_header = yes
    smtpd_tls_session_cache_timeout = 3600s
    tls_random_source = dev:/dev/urandom
    
    # A Few Extras
    smtpd_banner = $myhostname ESMTP (48de8cfaa27694040113a5ef61c85e19744cc48b)
    strict_rfc821_envelopes = yes
    disable_vrfy_command = yes
    smtpd_helo_required = yes
    smtpd_delay_reject = no
    
    These are the settings I have at the bottom of my main.cf file, and they work flawlessly for me. Just as a tip, don't change the stuff up top in your conf file; put it all down in the bottom in one chunk so it's easier to manage.

    The last thing you might want to do to postfix (optional) is uncomment the smtps line in your /etc/postfix/master.cf file. This will allow you to listen on 465/tcp, which is often a good idea when traveling. Many ISPs and hotels block outgoing traffic on port 25/tcp.

    # cat /etc/postfix/master.cf | grep smtps
    smtps    inet  n       -       n       -       -       smtpd
    

  3. Make Certificates For postfix
    I'm currently using the CACert method for my Postfix certificate, but it's not a great solution. There's evidently some sort of issue with self-signed certificates and the current version of Postfix. Anyway, the tutorial I used is here.
    I don't like this method personally, and I'm going to be redoing my cert the right way once this issue is taken care of. But either way, this method does work.
  4. Install cyrus-sasl
    Don't freak out if you've never used this before; it's trivial to set up. The one thing you want to do here is install this with postfix support. Again, in Gentoo we do this by passing options to the emerge command, either in the actual emerge command or via /etc/portage/package.use.

    # USE="postfix" emerge cyrus-sasl

  5. Configure cyrus-sasl
    Ok, so now we need to go and make two configuration changes -- one in /etc/conf.d/saslauthd and one in /etc/sasl2/smtpd.conf:

    # vi /etc/conf.d/saslauthd
    SASLAUTHD_OPTS="${SASLAUTH_MECH} -a rimap -r"
    SASLAUTHD_OPTS="${SASLAUTHD_OPTS} -O localhost"
    
    # vi /etc/sasl2/smtpd.conf
    mech_list: PLAIN LOGIN
    pwcheck_method: saslauthd
    

    ** If you find yourself without an /etc/sasl2/smtpd.conf file make sure you installed cyrus-sasl with Postfix support.


  6. Add SMTP Authentication Accounts
    So this is the important part. It's the piece that replaces all that MySQL craziness in the Gentoo Mailhosting Guide. What we basically have is cyrus-sasl sitting between the user and Postfix, and when you authenticate you have to authenticate using some sort of database. Well, instead of using mysql we're going to use the sasl database, which you can think of as a simple list.

    You add people to this list using the following syntax:

    # saslpasswd2 -c -u dmiessler.com daniel

    It asks you for a password twice and you're done. The credentials you enter don't have to match anything you have on your system (real accounts), but you can make them match if you want to. And that's it -- you now have a separate database of users for authenticating to postfix when you send mail from unknown IP addresses.

    To check what users exist in your database, just run the sasldblistusers command:

    # sasldblistusers
    dmiessler@dmiessler.com: userPassword
    

    ** If you ever need to delete an account from the database, just swap the -c switch to the saslpasswd2 command with -d (delete).


  7. Finishing Up

    Alright, so now we just have to start things up and make sure they come up automatically upon reboot:

    # /etc/init.d/postfix start
    # rc-update add postfix default


    # /etc/init.d/saslauthd start
    # rc-update add saslauthd default


    Now just spin up a mail client from a network that's not listed in your mynetworks paramater, go and change your SMTP settings to point to port 465/tcp (if you did that step), enable SSL, put in your username and password according to what's in the SASL database, and then send an email.

    You're done.

    If it doesn't work for some reason go back through this tutorial and make sure you're not missing anything. If that doesn't fix it, feel free to contact me. I know how frustrating this can be, and if I have the time I'll try and help out: