Showing posts with label postfix. Show all posts
Showing posts with label postfix. Show all posts

Saturday, January 17, 2015

Email fun: 8BITMIME and DKIM body authentication failure

Like most of you who decided to read this post, we use DomainKeys Identified Mail (DKIM) in an attempt to keep email spoofing down. . We noticed that some of the emails we were receiving were marked as spam by spamassassin when they shouldn't. Looking at the email header we saw they were failing the DKIM body integrity test. The entries in the header file looks something like

Authentication-Results mail.example.com (amavisd-new); dkim=softfail 
(fail, body has been altered) header.i=@example.com
or
dkim=neutral (body hash did not verify).
dkim=fail (message has been altered) domainkeys=pass

That would increase the score of those legitimate emails just above the threshold, causing spamassassin to flag them as spam. After some investigating, we found out emails that contained characters above the original ASCII character set, such as Olivenöl, in the body of the message were failing. In other words, DKIM really does not like 8bit (specifically 8BITMIME) encoding.

I was able to duplicate that by sending an email to myself or to a gmail test account using our default mail client, Thunderbird. So I tried to manually (using netcat; telnet would have worked fine) create a properly configured 8Bit email using our SMTP server (As you can clearly see, our MX server (postfix) is setup to handle 8BITMIME):

raub@desktop:/tmp$ nc -t mail.example.com 25
220 mail.example.com Test Mail Server
EHLO desktop.example.com
250-mail.example.com
250-PIPELINING
250-SIZE
250-ETRN
250-STARTTLS
250-ENHANCEDSTATUSCODES
250-8BITMIME
250 DSN
MAIL FROM:<raub@desltop.example.com> BODY=8BITMIME
250 2.1.0 Ok
RCPT TO:<raub@example.com>
250 2.1.5 Ok
DATA
354 End data with <CR><LF>.<CR><LF>
From: "Mauricio Tavares" 
Subject: 8bit test
Date: Mon, 30 Jun 2014 11:10:05 -0400
MIME-Version: 1.0
Content-Transfer-Encoding: 8bit

Olivenöl

.
250 2.0.0 Ok: queued as 2BA1F80041
QUIT
221 2.0.0 Bye
raub@desktop:/tmp$

The above would work while using Thunderbird didn't. After setting Thunderbird to debug mode, we noticed it was not properly indicating the email was 8BITMIME, so postfix would treat it as a 7bit ASCII email and then DKIM would fail. The DKIM signatures of 8BITMIME mail may break unless all SMTP servers in the path implement and announce 8BITMIME support, and as shown above the mail clients do not lie. Since we cannot guarantee that is the case, it is better to down-convert to quoted-printable before DKIM signing.

Solution is to force the MTA to downconvert to 7bit. That can be done in postfix by creating a null filter in master.cf that is called before the rest of the filters. In other words, something like

smtp      inet  n       -       n       -       -       smtpd
   -o content_filter=smtp-downconvert:127.0.0.1:10027
[...]
smtp-downconvert  unix    -       -       -       -       2       smtp
   -o smtp_discard_ehlo_keywords=8bitmime,silent-discard
127.0.0.1:10027 inet  n       -       n       -       -       smtpd
   -o smtpd_authorized_xforward_hosts=127.0.0.1
   -o smtpd_client_restrictions=
   -o smtpd_helo_restrictions=
   -o smtpd_sender_restrictions=
   -o smtpd_relay_restrictions=
   -o smtpd_recipient_restrictions=permit_mynetworks,reject

should do the trick. If we restart the MX (postfix reload will do the trick) and send the test email again, the email now should show something like

Authentication-Results mail.example.com (amavisd-new); dkim=pass header.i=@example.com

in the header, which means DCKIM is successful and life is good... for now

I would like to thank Wietse Venema for pointing me on the right direction regarding downconverting.

Note: HELO vs EHLO

  • HELO: Standard/Original SMTP (7-bit ASCII email) (RFC 821, 5321)
  • EHLO: ESMTP (RFC 1869). Think Enhanced HELO; supports MIME and other exciting extensions. A quick discussion is found at http://cr.yp.to/smtp/ehlo.html.

Tuesday, August 27, 2013

Installing ssmtp in RedHat/CentOS

I like ssmtp, and yes it has an extra "s" compared to smtp server. There are a lot of MTAs out there with tons of features and tweaks and so on. I myself setup and deployed postfix in quite a few organizations and never had reason to regret it. But, postfix, sendmail, and all the others are full-fledged enterprise level MTAs. Sometimes all you need is to be able to send a couple of emails from servers whenever they have something interesting to tell you ("who is banging my ssh port?" "where's my tea?"). Take CentOS, for instance. If you are not careful, it will put postfix in every single desktop you install it on. Who needs postfix in their desktop when they probably have access to a perfectly good server class mail server thingie (which could even be postfix, mind you)?

So, enter ssmtp. It is small. You can even say it is rather limited and not particularly secure. But, if all you want is to know if some machine, say, finished a batch job or added a new user and can work around its limitations, you might want to check it out.

Installing ssmtp

As I mentioned in the title, we will be installing ssmtp in some RedHat/CentOS machine. That will require to configure the box to use additional repositories. You can check if your favourite one has it; I myself like epel and know ssmtp is there. repoforge (used to be called rpmforge) might have it too. How do you add a repository? I will let you figure out.

First thing we need to do is remove postfix just in case it is there:

yum remove postfix

Then we do some ssmtp adding:

yum install ssmtp --enablerepo=epel

Now we need to configure it. To do so you need a real smtp server; all ssmtp does is forward email to a proper MTA. Let's say your mail server is mail.domain.com. If you do not need to authenticate against it (it accepts unauthenticated email only from certain machines or your LAN), you could probable get away with this:

cat > /etc/ssmtp/ssmtp.conf  << EOF
# Config file for sSMTP sendmail  
root=postmaster
mailhub=mail.domain.com
hostname=$(hostname -f)
FromLineOverride=yes
#UseTLSCert=YES
#TLSCert=/etc/pki/tls/private/ssmtp.pem
#Debug=YES
UseSTARTTLS=yes
EOF

I will be rushing over the not-so-many settings in ssmtp because they are well explained somewhere else. What I will do is stop at the ones I think you might find interesting; at least I do:

  • UseSTARTTLS: if your smtp server can do TLS, by all means use it! Or SSL! ssmtp can handle that too; check the man pages!.
  • mailhub: this is as you guessed the address for the smtp server. The nice thing about it is that you can not only define the name but also the port, in case you are not using port 25. Here are a few examples:

    • mailhub=smtp.gmail.com:587
    • mailhub=mail
    • mailhub=host363.hostmonster.com:465
    Bonus points if you recognize the ports. Here is a full example assuming you are a cox customer (I based the setup on their email setup notes) connecting using port 25 (insecure) without any auth whatsoever:
    cat > /etc/ssmtp/ssmtp.conf << EOF
    # Config file for sSMTP sendmail
    root=postmaster
    mailhub=smtp.cox.net
    hostname=$(hostname -f)
    FromLineOverride=yes
    EOF
    
  • hostname: Nothing special here, besides you probably noticed I was lazy and let the computer tell what is its own name. If you do not get the FQDN, you probably need to check your configuration somewhere.

But, what if you need to autenticate to send an email (SMTP Auth)? Well, ssmtp allows some form of authentication. No kerberos or key pairs though, just plain old username and password. If you needed that, you would add something like this

AuthUser=server1
AuthPass=secret_password
to your /etc/ssmtp/ssmtp.conf file. Password will be in plaintext, so make sure only root can read this file. Note I used server1 as the username. Reason for that is I would think either each server would have its own email account or a commom server email account would be used. You decide.

When all of that is done, it is time to do some testing. First quick test would be to send an email to you (username@somedomain.com):

echo test | ssmtp -v username@somedomain.com

The -v option is verbose, so you can see what is going on and perhaps have some clues in case it all goes boink. A fancier ssmtp test (which should give you ideas on how to use it in your own scripts) would be

victim=username@somedomain.com
ssmtp $victim << EOF
From: test@$(hostname)
To: $victim
Subject: A longer test
Hi there!

EOF

Now go check if the email arrived in your mailbox and what your spam filter thought of it. Remember, the fancier example allows you to make your email a bit more proper... just sayin'!

References