I finally got around to setting up something I've wanted for a long, long time. You see, I have a few co-located machines runnning Debian GNU/Linux that handle e-mail, DNS, web, MySQL, and other services for roughly 30 domains including zawodny.com. But the e-mail has always been a bit of a pain.

Why? Because I send roughly half of my mail using mutt while logged directly into one of those machines. That's fine. However, the other half of the time I'm using something like Apple's Mail.app on the TiBook. When that happens, I have to worry about relaying issues.

Traditionally, I've just used Exim's host_accept_relay option, setting it to a list of hosts that I'll be using:

host_accept_relay = 192.168.1.2

The problem with doing that is dynamic addresses. My cable modem address changes now and then. And sometimes I'll plug the TiBook into a foreign network. Then I need to figure out what the address is, if there's NAT involved, and so on. It's a pain. There's a better way.

Fortunately, Exim (my preferred mail server) has two features which combine to solve the problem. First, you have SMTP AUTH (RFC 2554), which is the standard way of mail clients authenticating with a mail server for sending messages. The second piece of the puzzle is SSL support, so the entire session can be encrypted--including the authentication (username and password).

My goal was to configure Exim so that it would allow any authenticated user to use the server as a mail relay no matter where they connect from. Then I'd require all autentication to happen over an encrypted channel so that I'd never have to worry about passwords being sniffed. It turns out that this is surprisingly easy to do.

By reading chapters 35, 36, and 38 in the Exim manual, it was quite easy.

First, I made sure to install the Debian exim-tls package as a replacement for the normal exim package. (TLS stands for "transport layer security. In this case, OpenSSL is providing the TLS.)

shell$ sudo apt-get install exim-tls

To setup the SMTP authentication, I added this bit to the end of my /etc/exim/exim.conf file:

# AUTH stuff here

fixed_plain:
  driver = plaintext
  public_name = PLAIN
  server_condition = ${if and {{eq{$2}{user}}{eq{$3}{pass}}}{yes}{no}}
  server_set_id = $2

Where "user" is the username I'm going to use and "pass" is the password. It's possible to use PAM, MySQL, text files, LDAP, or any number of other ways to do this so you can support many users. Right now this is for just me, so this works. Someday I'll improve it and allow others to make use of it.

Then I followed the example instructions for creating an SSL certificate and key. I installed them as /etc/exim/exim.key and /etc/exim/exim.cert.

Lastly, I updated a few more settings in my Exim configuration and then restarted Exim:

# Only localhost can relay by default
host_accept_relay = localhost
  
# Anyone can relay if they auth first.  And auth must happen over SSL.
host_auth_accept_relay = *

# SSL/TLS cert and key
tls_certificate = /etc/exim/exim.cert
tls_privatekey = /etc/exim/exim.key

# Advertise TLS to anyone
tls_advertise_hosts = *

# Require auth over SSL only.
auth_over_tls_hosts = *

Then I told Mail.app to use password authentication and to use SSL for outgoing mail. That's it. It just works. The same should work for Netscape, Outlook, Eudora, etc.

Posted by jzawodn at January 19, 2003 10:50 PM

Reader Comments
# Brian J. France said:

You may want to tcpdump and make sure Mail.app is working correctly.

I found it would would connect, send the STARTTLS, not like the certificate and disconnect, reconnect and sendmail via plain text.

It just looked like it worked, no error, no asking, nothing.

I think this is because it was a self signed certificate, but some feed back would be nice.

Brian

on January 20, 2003 09:58 AM
# Jeremy Zawodny said:

Verified. It really worked.

Exim logged it as an authenticated transaction and I had it configured to allow authentication only over a secure channel.

on January 20, 2003 10:22 AM
# Rob said:

Anyone know a way to do this using Postfix?

on January 22, 2003 09:54 AM
# Harald Koch said:

The first Google entry for "Postfix TLS" is:

http://www.aet.tu-cottbus.de/personen/jaenicke/pfixtls/

it's even easier if you start with Simon's RPMs, referenced on that page. It's well documented...

on January 22, 2003 01:07 PM
# Steve Madsen said:

I'm going to put this here, because this page is ranked pretty high on Google and finding this information elsewhere takes some digging.

To get Exim SMTP AUTH working with PAM on Debian (may work with other distributions, I don't know), your exim.conf must contain

exim_user=mail
exim_group=shadow

or the authentication will not work.

on June 12, 2003 11:26 PM
# Robert Hutton said:

I've just got /etc/exim/passwd to work. Seems that the examples in the Debian /etc/exim/exim.conf are flawed. They have the $1, $2 and $3 in the wrong places. $1 is junk, $2 is the username and $3 is the password. They must have thought that $1 was the username, $2 the password, which is incorrect.

The corrected config snippet:

# The examples below are for server side authentication; they allow two
# styles of plain-text authentication against an /etc/exim/passwd file
# which should have user IDs in the first column and crypted passwords
# in the second.

plain:
driver = plaintext
public_name = PLAIN
server_condition = "${if crypteq{$3}{${extract{1}{:}{${lookup{$2}lsearch{/etc/exim/passwd}{$value}{*:*}}}}}{1}{0}}"
server_set_id = $2

login:
driver = plaintext
public_name = LOGIN
server_prompts = "Username:: : Password::"
server_condition = "${if crypteq{$3}{${extract{1}{:}{${lookup{$2}lsearch{/etc/exim/passwd}{$value}{*:*}}}}}{1}{0}}"
server_set_id = $2

on June 17, 2003 04:02 AM
# Robert Hutton said:

Oh, also to create /etc/exim/passwd you use htpasswd (which comes with apache).

on June 17, 2003 04:05 AM
# Spencer said:

Maybe this is a stupid question, but oh well. Where does the host_auth_accept_relay option go? I tried putting it in the general section and the authentication section, but it doesn't like either one, and the exim docs don't really say where to put it either.

on July 9, 2003 07:09 AM
# Jeff Wiegley said:

SMTP-AUTH and PAM and Debian...

I need: TLS and SMTP-AUTH abilities for security
and relay control respectively.

The exim4-daemon-heavy debian package seems to
have everything I need.

To get STARTTLS advertised you'll need to create a
self signed cert in /etc/exim4/exim.{key,crt} and
you'll need to uncomment the
tls_advertise_hosts = *
tls_certificate = CONFDIR/exim.crt
tls_privatekey = CONFDIR/exim.key
lines in the
/etc/exim4/conf.d/main/03_exim4-config_tlsoptions
file.

user is already set to mail and group is
already shadow so you should be able to
authenticate using /etc/passwd. Could somebody
please demonstrate all of the config lines
necessary to accomplish this? (authentication
against PAM would be better.)

on July 21, 2003 04:51 PM
# Michael Dickinson said:

Steve Madson wrote that

exim_user=mail
exim_group=shadow

must be placed in the exim.conf on Debian systems, but whereabouts in the file does it need to go?

on December 30, 2004 10:20 AM
# Oitemyke said:

Is it possible that the host_accept_relay option has been depreciated? Attempting to startup Exim yeilds 'unknown option host_accept_relay.' As of yet, I have not been able to find documentation on what, if anything, may have replaced this option.

Thanks!

on January 7, 2005 11:43 AM
# Mike said:

Another option would be to use imaps. I use many computers at work/university/home. Having your email organized on the server with folders and such is a great advantage. Plus all you woul dhave to do is set up imaps (imap server with SSL)

Highly recommended :)

btw. Very nice tutorial, very descriptive

on May 14, 2005 06:03 PM
# Eeehmsen said:

I have done a similar setup on exim-4.40+ following this tutorial, but changing a few bits to fit exim4. So this is a quick summary of how I got it working:

exim.conf:

tls_advertise_hosts = *
tls_certificate = /etc/exim/exim.cert

begin authenticators

plain:
driver = plaintext
public_name = PLAIN
server_advertise_condition = ${if eq{$tls_cipher}{}{no}{yes}}
server_condition = ${if pam{$2:$3}{1}{0}}
server_set_id = $2

In a shell:
#openssl req -x509 -newkey rsa:1024 -keyout /etc/exim/exim.cert -out /etc/exim/exim.cert

/etc/pam.d/exim:

auth required pam_exim.so
account required pam_permit.so

I have installed the pam_exim module in PAM.

Hope this helps people with a more recent version of exim.

on August 29, 2005 08:39 AM
# Eeehmsen said:

Dammit! I always make one small mistake eventhough I read the damm thing before posting!

The openssl line should read:
openssl req -x509 -newkey rsa:1024 -keyout /etc/exim/exim.cert -out /etc/exim/exim.cert -days 9999 -nodes
(change the days thing if you like)

on August 29, 2005 08:44 AM
Disclaimer: The opinions expressed here are mine and mine alone. My current, past, or previous employers are not responsible for what I write here, the comments left by others, or the photos I may share. If you have questions, please contact me. Also, I am not a journalist or reporter. Don't "pitch" me.

 

Privacy: I do not share or publish the email addresses or IP addresses of anyone posting a comment here without consent. However, I do reserve the right to remove comments that are spammy, off-topic, or otherwise unsuitable based on my comment policy. In a few cases, I may leave spammy comments but remove any URLs they contain.