Postfix as relay to a SMTP requiring authentication

Sometimes you may in need to use an external SMTP provider to send your emails, and usually ISPs give instruction on how to configure mail clients such as Outlook or Thunderbird. But what if you are already using an internal SMTP server such as Postfix?

These guidelines are for Debian (but may be helpful with other systems as well) and are related to Postfix. The SMTP provider in the example is AuthSMTP which is a well known provider for SMTP relaying.

Given you already have a working Postfix environment, first of all edit your main.cf and add these lines:

relayhost = [mail.authsmtp.com]
smtp_sasl_auth_enable=yes
smtp_sasl_password_maps=hash:/etc/postfix/sasl-passwords
smtp_sasl_mechanism_filter = digest-md5
smtp_sasl_security_options=

then, create with $EDITOR a file called /etc/postfix/sasl-passwords and fill it with something like this:

[mail.authsmtp.com] yourusername:yourpassword

then, compile the map file

# postmap hash:/etc/postfix/sasl-passwords

now we are almost done, just restart postfix and it should work.

Now, probably it won’t really work and you’ll start to see messages like these in your postfix log:

warning: SASL authentication failure: No worthy mechs found
SASL authentication failed; cannot authenticate to server mail.authsmtp.com

that’s because you are missing some SASL packages from Debian. Issue

# aptitude install libsasl2-modules

and it should install all the missing packages and make the thing work :)

Advertisements

Domainkeys/Dkim with Postfix

Hello,

If you want to use postfix to use domainkeys or dkim you can do it using dkimproxy http://dkimproxy.sourceforge.net

In this setup, we only want that outgoing mail are signed. As we known, yahoo and gmail uses it with spam checks.

http://dkimproxy.sourceforge.net/postfix-outbound-howto.html

First, change your master.cf from postfix file
master.cf:
submission inet n – y – – smtpd
-o smtpd_etrn_restrictions=reject
-o content_filter=dksign:[127.0.0.1]:10027
-o receive_override_options=no_address_mappings
-o smtpd_recipient_restrictions=permit_mynetworks,reject

// put this in the same file, for example, at bottom is a good place
dksign unix – – n – 10 smtp
-o smtp_send_xforward_command=yes
-o smtp_discard_ehlo_keywords=8bitmime,starttls

127.0.0.1:10028 inet n – n – 10 smtpd
-o content_filter=
-o receive_override_options=no_unknown_recipient_checks,no_header_body_checks
-o smtpd_helo_restrictions=
-o smtpd_client_restrictions=
-o smtpd_sender_restrictions=
-o smtpd_recipient_restrictions=permit_mynetworks,reject

Now, is time to setup dkimproxy, since we are only interested in outgoin mail, we use dkimproxy.out instead, please, use devel version, at moment, stable version can’t sign both signatures at the same time. Tested using dkimproxy-1.0beta1.tar.gz
This example show how to sing more than one domain.

Create a new file.
/etc/postfix/ssl/domainkeys/domainkeyfile:
# sign both mydom1.com and mydom2.com mail with both a domainkeys and dkim signature (put a new domain for each line)
mydom1.com domainkeys(a=rsa-sha1,c=nofws), dkim(a=rsa-sha256,c=relaxed)
mydom2.com domainkeys(a=rsa-sha1,c=nofws), dkim(a=rsa-sha1,c=relaxed)

As user root, is time to launch dkimproxy (change your values if necessary), in this case we run dkimproxy with user/group dkim
# groupadd -g 4321 dkim
# useradd -u 4321 -s /bin/false -d /dev/null -g dkim dkim

// launch it as a daemon
# dkimproxy.out –user=dkim –group=dkim –keyfile=/etc/postfix/etc/ssl/domainkeys/private.key –selector=yourselector –sender_map=/etc/postfix/ssl/domainkeys/domainkeyfile –daemonize –pidfile=/var/run/dkim.pid 127.0.0.1:10027 127.0.0.1:10028

Of course, it’s very important that you keep you port 25 for ‘normal’ mail and change it to port 587 if you want to use dkimproxy, check your mail client how to do that.

Now, your mail uses domainkeys/dkim headers :)

this is a mail headers example:
———-

DomainKey-Signature: a=rsa-sha1; c=nofws; d=mydom1.com; h=date:subject:from:to:mime-version:content-type:message-id:content-transfer-encoding; q=dns; s=ireth; b=

KPaZ5d7olrcJ62GwFyOAGGuiWe/+6ffW+b+ne24t3+mlUyUgU7kYHRedPphfTa4e

AtdKW/l9B+TFnZs3WOFpaB1fkkwohQIHUJrINhMlm6NVgcEy3wolOXx2QKmDQdzl

4cRo0x6q8DTjl9ThVwaOdL89Xj6gG8RecOx9wCKjnXO=

DKIM-Signature: v=1; a=rsa-sha256; c=relaxed; d=mydom1.com; h=

date:subject:from:to:mime-version:content-type:message-id:

content-transfer-encoding; q=dns/txt; s=myhost1; bh=gbf05R7SXafOIY

pmOvZ6JHiCsUiIu94mbMnHdz31av0=; b=jh8AB9KJUF2yarL9etKNcdCsICPssS

Hz314WM/0KliaooehfanU+dxn/FIbvdeVc+ztTA9OkefWCj2SBfx/xi3sMDTy6gj

ue+BYGvS9GJ9tYCKUvW4lk5wwk70JcCSpwQAbjsyf1pPBW3I6NFPtk2G5LrykEs+

yizGa5g3x9rdg=

———-

This setup assumes that you have created you private/public cryptographic keys, also you have configured your dns, if not, then check main site for how to do it.

http://dkimproxy.sourceforge.net/ (read about openssl)

See you!

Maildrop and the automatic maildirmake problem

If you are using a vanilla maildrop in a classic postfix (or another MTA) environment, you will have your master.cf to look like this:

maildrop unix - n n - - pipe
flags=DRhu user=vmail:vmail argv=/usr/bin/maildrop -d ${user}@${nexthop} ${user} ${nexthop} ${sender}

for example. And with this configuration, maildrop will not elaborate at all your /etc/maildroprc directive file. Why? Very simple (once you discover it): because we are using the -d switch which implies the Delivery mode. And it’s even written in the maildrop man page! Look:

Delivery mode

maildrop is the mail server’s mail delivery agent. maildrop runs in delivery mode when no filename is specified on the command line. maildrop
changes the current directory to the user’s home directory, then reads /etc/maildroprc, then $HOME/.mailfilter.

so, what’s happening here? Maildrop check if the ${user}@${nexthop} home directory exists and since it doesn’t, it simply exits spitting in your face :) So, no maildroprc rule applies, so you cannot create on-the-fly the homedir.
Now, there are two solutions:

  1. create manually (well, in the user-creation script) the home directory plus the Maildir with something like this:
    mkdir -p /home/vmail/domains/$DOMAIN/$USER
    maildirmake /home/vmail/domains/$DOMAIN/$USER/Maildir
    chown -R vmail:vmail /home/vmail/domains/$DOMAIN/$USER
  2. edit master.cf to be like this (in the maildrop part):

    maildrop unix - n n - - pipe
    flags=DRhu user=vmail:vmail argv=/usr/bin/maildrop /etc/maildroprc ${user} ${nexthop} ${sender}
    then give 0600 permissions and vmail ownership to /etc/maildroprc and finally append this to it (if you want to enable maildrop filter capabilities)
    USERMAILDIRFILTER="/home/vmail/domains/$DOMAIN/$USER/.mailfilter"
    DEFAULT="/home/vmail/domains/$DOMAIN/$USER/Maildir/."
    `[ -f $USERMAILDIRFILTER ]`
    if ( $RETURNCODE == 0 )
    {
    include $USERMAILDIRFILTER
    }

PS: Gentoo maildrop version is affected by this “problem”. On the other hand, Debian’s one seems to be “immune”

Postfix in a multi-IP environment

If you have to install postfix in a multi-IP environment, say, if you need it to listen to two or more IP (for example a real IP and an alias on the same NIC), there is a cute directive in main.cf that let you decide which IP should postfix (well, it’s parts like smtp, virtual/maildrop etc) use when contacting an external server.

inet_interfaces = 192.168.1.200, 192.168.1.201, localhost
smtp_bind_address = 192.168.1.201

with inet_interfaces your postfix will listen to these 3 IPs, and with smtp_bind_address you will tell postfix to specifically use 192.168.1.201 when contacting an external address.

HOWTO: on vacation autoreply with Postfix/LDAP and Gnarwl

If your users are asking for an autoreply feature when they’re on vacation, and you are currently using postfix as MTA with a LDAP backend for authentication, IMO the best solution is to use Gnarwl and configure it following these simple steps:

  • download the most recent Gnarwl’s tarball in a place of choice
  • unpack it and install it with
    ./configure
    make
    make install
    make perm

    this will install Gnarwl under /usr/local and do all the dirty work (creating the gnarwl local user for example, check your /etc/passwd )
  • edit /usr/local/etc/gnarwl.cfg to look like this:
    map_sender $sender
    map_receiver $recepient
    map_subject $subject
    map_field $fullname cn
    server your.ldap.server.com
    port 389
    scope sub
    protocol 3
    base ou=Users,dc=YOURCOMPANY,dc=com
    queryfilter (&(mail=$recepient)(vacationActive=active))
    result vacationInfo
    blockfiles /usr/local/var/lib/gnarwl/block/
    umask 0644
    blockexpire 6
    mta /usr/sbin/sendmail -t $recepient
    maxreceivers 64
    maxheader 512
    charset ISO8859-15
    badheaders /usr/local/var/lib/gnarwl/badheaders.db
    blacklist /usr/local/var/lib/gnarwl/blacklist.db
    forceheader /usr/local/var/lib/gnarwl/header.txt
    forcefooter /usr/local/var/lib/gnarwl/footer.txt
    recvheader To Cc

    vacationActive and vacationInfo are two attibutes that have to exist in the LDAP schema you’re using for your users. Obviously you can use whatever attribute you prefer, you simple have to literally change the vacationActive/vacationInfo in this config with your own attributes, keeping in mind that vacationActive is used to check if autoreply is enabled or not for that particular user and vacationInfo it’s the text that is being used as a reply (note: you can use CR/LF in it, to obtain a multiline text). The other parameter that deserves a comment is blockexpire: here you can put the amount of time (in hours) during wich an autoreply to the same sender will not be sent. For example, if john@foo.com tries to send a mail to duke@yourcompany.com, he will receive the vacation message. But, as in our config example, john sends another message within 3 hours, he won’t get any message at all. He has to wait 3 more hours to get notified again (blockexpire was set to 6 hours, remember)
  • as the doc/INSTALL file in Gnarwl says, the quick-and-dirty way to enable Gnarwl in a postfix installation (this is the method I’m using, too :) is to edit /etc/postfix/main.cf and simply add the linealways_bcc=gnarwlThis works by delivering every message to the local gnarwl user (even if you are in a virtual environment), which has a .forward file that pipes everything to the gnarwl binary program, which takes care of everything
  • Now, the final step: to activate the vacation message for one of your customer, simply edit your LDAP data, add a vacationActive attribute with an “active” value to the user you want, and add vacationInfo with the text you want. That’s all.

For more info and more detailed configuration instructions, please refer to the doc/INSTALL file in your gnarwl tarball.