Login | Register For Free | Help
Search for: (Advanced)

Mailing List Archive: exim: users

Setting up exim to relay through ISP's email server

 

 

exim users RSS feed   Index | Next | Previous | View Threaded


vahe at xpree

Jun 18, 2008, 2:34 PM

Post #1 of 6 (602 views)
Permalink
Setting up exim to relay through ISP's email server

I'm running Centos (technically Red Hat 4.1.2-14), and I'm trying to get
the configuration correct for using the ISP's SMTP server as the relay.
Naturally the SMTP server requires authentication. This doesn't seem to
be all that straightforward: I've tried all of a dozen different
configurations out there and most just don't work. One did get going,
but the configuration was for SMTP relay without authorization, thus the
SMTP server returned with a "client not authorized" error.

Say my isp is

mail.isp.com

and my username is

username

and my password is

password

What would my configuration be in exim.conf, with the appropriate
configurations in routers, transports, and authenticators (I'm assuming
the configuration would require something in all three sections)?

I apologize in advance if this is a simple question, but the
documentation really doesn't lend itself to figuring out a configuration
like this.

TIA.

--
Vahe Oughourlian
Software Engineer
vahe[at]xpree.com


--
## List details at http://lists.exim.org/mailman/listinfo/exim-users
## Exim details at http://www.exim.org/
## Please use the Wiki with this list - http://wiki.exim.org/


exim-users at spodhuis

Jun 19, 2008, 2:22 AM

Post #2 of 6 (576 views)
Permalink
Re: Setting up exim to relay through ISP's email server [In reply to]

On 2008-06-18 at 14:34 -0700, Vahe Oughourlian (Xpree) wrote:
> Say my isp is
>
> mail.isp.com

isp.com is a real domain. I'll go with mail.isp.tld. :)

> and my username is
>
> username
>
> and my password is
>
> password

I'll write these as your_username and your_password for clarity.

> What would my configuration be in exim.conf, with the appropriate
> configurations in routers, transports, and authenticators (I'm assuming
> the configuration would require something in all three sections)?

First Router (they're an ordered list):

----------------------------8< cut here >8------------------------------
begin routers

isp_smarthost:
driver = manualroute
domains = ! +local_domains
transport = smarthost_smtp
route_data = mail.isp.tld
same_domain_copy_routing
no_more
----------------------------8< cut here >8------------------------------

Transports are just a collection of definitions, so order doesn't
matter; you'll need this; if the ISP supports using Submission on port
587, you can try using that (especially if it's a laptop which can roam
elsewhere). Hopefully the ISP offers TLS so you can get an encrypted
link but perhaps they don't (eg, national laws which would compel them
to have session key recording infrastructure and be able to hand over
keys on demand might lead to them just not offering TLS); if they don't,
comment out the _tls line. You might want to set the global option
"tls_verify_certificates" to let you verify their cert (see docs for
details).

----------------------------8< cut here >8------------------------------
begin transports

smarthost_smtp:
driver = smtp
# port = 587
hosts_require_tls = mail.isp.tld
hosts_require_auth = mail.isp.tld
# you can set helo_data to something defining your account too
----------------------------8< cut here >8------------------------------

By this point, you might well consider using a macro to extract the
definition of mail.isp.tld to the top of the file. :)

For the authenticators, it really depends upon which authentication
systems the ISP supports. This can vary a lot. I'll give you
simplified versions of what I have on my laptop.

I don't know which version of Exim Centos ships with; "exim -bV" will
report it. The use of $tls_cipher here is only valid from Exim 4.68
onwards; it will keep you from ever using cleartext authentication over
an unencrypted link. With hosts_require_tls, this becomes a
"belt+braces" approach to protection, with double safety-checks. For
protecting passwords, that's not a bad plan.

----------------------------8< cut here >8------------------------------
begin authenticators

auth_plain:
driver = plaintext
public_name = PLAIN
client_condition = ${if def:tls_cipher}
client_send = ^your_username^your_password

auth_cram:
driver = cram_md5
public_name = CRAM-MD5
client_name = your_username
client_password = your_password
----------------------------8< cut here >8------------------------------

The '^' becomes a NUL character; see RFC 4616 for details of PLAIN if
you're interested in why those are there (and RFC 2195 for details of
CRAM-MD5).

It's fairly common to extract the password to an external file and use
Exim's string replacement to let you look the details up, instead of
hardcoding the password in the Exim config file.

Regards,
-Phil

--
## List details at http://lists.exim.org/mailman/listinfo/exim-users
## Exim details at http://www.exim.org/
## Please use the Wiki with this list - http://wiki.exim.org/


zybhjk at verizon

Jun 19, 2008, 9:07 PM

Post #3 of 6 (554 views)
Permalink
Re: Setting up exim to relay through ISP's email server [In reply to]

On Thu, Jun 19, 2008 at 02:22:21AM -0700, Phil Pennock wrote:
> It's fairly common to extract the password to an external file and use
> Exim's string replacement to let you look the details up, instead of
> hardcoding the password in the Exim config file.

Do you have an example of this? I've been trying to set up multiple SMTP
relaying based on a message's From: domain, but without much luck. I
have a bunch of SMTP accounts, so this would be very useful in addition
to the security concerns. (although I have a workable solution now
since some of the servers accept any From: header as long as the client
is authenticated).

And thanks for the tip about checking for TLS if using auth PLAIN. Does
$tls_cipher count SSL connections as well? A disturbing number of
servers use PLAIN over unencrypted SMTP...

--
Eli C.
2008:06:20

--
## List details at http://lists.exim.org/mailman/listinfo/exim-users
## Exim details at http://www.exim.org/
## Please use the Wiki with this list - http://wiki.exim.org/


exim-users at spodhuis

Jun 20, 2008, 8:46 PM

Post #4 of 6 (527 views)
Permalink
Re: Setting up exim to relay through ISP's email server [In reply to]

On 2008-06-20 at 00:07 -0400, Eli C wrote:
> Do you have an example of this?

I have a rather complex setup for my laptop. It does this and more.
Details below. Used on MacOS.

> And thanks for the tip about checking for TLS if using auth PLAIN. Does
> $tls_cipher count SSL connections as well? A disturbing number of
> servers use PLAIN over unencrypted SMTP...

AFAIK, $tls_cipher counts SSL connections, but I don't think Exim
supports SSL-on-connect outbound. That is strictly for legacy client
support, Exim supports it for inbound connections only. I think.


Okay, my laptop. This does not highlight how easy Exim can be to
configure for many scenarios (once you know _how_, which is always the
sticking point); rather, it's a glimpse of the power you get from the
rather complete string expansion language. And a glimpse of how nuts I
am.

There will be various macros and hostlists which you define for
yourself. There are two special external files which are the heart of
it. "smarthosts" and "client-passwords". Example here uses Gmail
because that's what I have configured (various disclaimers apply).
Gmail's delivery folks aren't entirely enthralled with people routing
mail through Gmail and sending bounces, risking mail-loops, etc, so if
you mismanage this and damage your account's spam reputation score, on
your head be it.

smarthosts:
----------------------------8< cut here >8------------------------------
gmail.com: host=smtp.gmail.com submission=yes tls=yes user=nobody[at]gmail.com
googlemail.com: host=smtp.gmail.com submission=yes tls=yes user=nobody[at]gmail.com
*: host=mail.example.org submission=yes tls=yes
----------------------------8< cut here >8------------------------------

For the "client-passwords" file, I don't keep that in source-code
control and I'm not on the laptop right now, so I might be making a
mistake, but I believe it goes something like:
----------------------------8< cut here >8------------------------------
nobody[at]gmail.com: password=12345678
mail.example.org: user=fred password=sekret
----------------------------8< cut here >8------------------------------
Note how when a user is specified in smarthosts, the client-passwords
file is keyed by that, otherwise it's keyed by the smarthost (or parent
domains thereof).

Routers first; the first Router lets me declare for which domains I'll
send direct to MX, by creating a file named for the domain in a special
directory. The second Router verifies DNS so that I don't pass invalid
domains on and damage my reputation with remote systems; this does mean
that I need to be online whilst submitting email to Exim though.

----------------------------8< cut here >8------------------------------
begin routers

direct_to_mx:
driver = dnslookup
domains = partial()dsearch;DIRECT_OUT_DIR
transport = remote_smtp
ignore_target_hosts = +special_ipv4_bad
same_domain_copy_routing
no_more

remote_dns_verify:
driver = dnslookup
domains = ! +local_domains
transport = remote_smtp
ignore_target_hosts = +special_ipv4_bad
same_domain_copy_routing
verify_only
no_more

smarthost:
driver = manualroute
domains = ! +local_domains
transport = smarthost_smtp
ignore_target_hosts = +special_ipv4_bad
route_data = ${extract{host}{${lookup{$domain}partial()lsearch*{RUNCONFDIR/smarthosts}}}}
address_data = ${lookup{$domain}partial()lsearch*{RUNCONFDIR/smarthosts}}
same_domain_copy_routing
no_verify
no_more

----------------------------8< cut here >8------------------------------

The route_data extracts the 'host' field from the smarthosts file;
address_data associates the entire line from smarthosts with the
address, for later extraction.

----------------------------8< cut here >8------------------------------
begin transports

remote_smtp:
driver = smtp
.ifndef TLS_ALLOWED_OUTBOUND
hosts_avoid_tls = *
.endif
hosts_require_tls = +tls_required_to
hosts_try_auth = +authenticate_attempt_to

smarthost_smtp:
driver = smtp
port = ${extract{port}{$address_data}{$value}{\
${extract{submission}{$address_data}{587}{25}}\
}}
hosts_require_tls = ${extract{tls}{$address_data}{*}{+tls_required_to}}
hosts_require_auth = ${extract{user}{$address_data}{*}{+authenticate_required_to}}
helo_data = ${extract{helo}{$address_data}{$value}{MYHELO_TO_SMARTHOST}}
----------------------------8< cut here >8------------------------------

The TLS_ALLOWED_OUTBOUND is something I might define on the command-line
to send mail with a queue-run to someone whose TLS is currently broken.

The hostlist authenticate_attempt_to is used for stuff not going via a
smarthost.

The hostlists tls_required_to and authenticate_required_to are fallbacks
for when the fields are not present. You can easily remove those and
just have no coerced default. Note the default HELO parameter is a
macro. No, none of the lines in the example smarthosts file set helo,
so I always use that default.

For the authenticators, I'll remove the server_* fields which aren't
relevant; in theory I might start my laptop's Exim accepting remote mail
from the local network, authenticated, and send via that. I've done
that once, maybe twice, so it's just a distraction here. But if you do
want to handle authentication server-side, you just add the server_*
fields to these same authenticators.

----------------------------8< cut here >8------------------------------
begin authenticators

auth_cram:
driver = cram_md5
public_name = CRAM-MD5
# If smarthosts address_data gives us a user, use that; else do
# a domain search on client-passwords (no * default support)
client_name = ${extract{user}{$address_data}{$value}{\
${extract{user}{${lookup{$host}partial()lsearch{RUNAUTHDIR/client-passwords}}}{$value}fail}}}
# The password, however, always comes from client-passwords
client_secret = ${extract{password}{${lookup{\
${extract{user}{$address_data}{$value}{$host}}\
}partial()lsearch{RUNAUTHDIR/client-passwords}}}{$value}fail}

auth_plain:
driver = plaintext
public_name = PLAIN
client_condition = ${if def:tls_cipher}
client_send = ^${extract{user}{$address_data}{$value}{\
${extract{user}{${lookup{$host}partial()lsearch{RUNAUTHDIR/client-passwords}}}{$value}fail}}}\
^${extract{password}{${lookup{\
${extract{user}{$address_data}{$value}{$host}}\
}partial()lsearch{RUNAUTHDIR/client-passwords}}}{$value}fail}
----------------------------8< cut here >8------------------------------

There's no GSSAPI support client-side because I only use that with
GSSAPI-enabled MUAs, not from an MTA. I could create a server principal
with no bound address, I suppose, but I don't want to.

I think I got the full details.

--
## List details at http://lists.exim.org/mailman/listinfo/exim-users
## Exim details at http://www.exim.org/
## Please use the Wiki with this list - http://wiki.exim.org/


exim-users at spodhuis

Jun 20, 2008, 9:04 PM

Post #5 of 6 (523 views)
Permalink
Re: Setting up exim to relay through ISP's email server [In reply to]

On 2008-06-20 at 20:46 -0700, Phil Pennock wrote:
> On 2008-06-20 at 00:07 -0400, Eli C wrote:
> > Do you have an example of this?
>
> I have a rather complex setup for my laptop. It does this and more.

For the specific example of 'this' cited, yes, it does that and more.
It doesn't switch based on From: header though.

Switching on the From: header instead of the SMTP Envelope Sender is
slightly complicated because From: can contain multiple addresses, so
you want something like:

${sg{${addresses:$h_From:}}{:.*}{}}

to get the first one. If you're sure there will only ever be one
address in From:, then just ${address:$h_From:} will do.

Amending the example I gave to do dispatch based on sender, not
recipient, left as an exercise to the reader. Which will probably be me
soonish, since I really should be switching based on From: instead of
being lazy and just doing it based on recipient.

-Phil

--
## List details at http://lists.exim.org/mailman/listinfo/exim-users
## Exim details at http://www.exim.org/
## Please use the Wiki with this list - http://wiki.exim.org/


exim-users at spodhuis

Jul 26, 2008, 3:38 PM

Post #6 of 6 (182 views)
Permalink
Re: Setting up exim to relay through ISP's email server [In reply to]

Self-followup to correct an omission.

On 2008-06-20 at 20:46 -0700, Phil Pennock wrote:
> begin transports

> smarthost_smtp:
> driver = smtp
> port = ${extract{port}{$address_data}{$value}{\
> ${extract{submission}{$address_data}{587}{25}}\
> }}
> hosts_require_tls = ${extract{tls}{$address_data}{*}{+tls_required_to}}
> hosts_require_auth = ${extract{user}{$address_data}{*}{+authenticate_required_to}}
> helo_data = ${extract{helo}{$address_data}{$value}{MYHELO_TO_SMARTHOST}}

In answering a mail from M G Berberich, I realised that I wasn't setting
any client-side server verification in my own laptop configuration.

To do verification (ie, make the TLS worthwhile) you need a collection
of the CA certificates which signed the certificates that you care about
(or signed intermediate CAs, etc). For GnuTLS, these need to be all in
one file, for OpenSSL they can either be in a file or in a directory
(which has the hash->certificate symlinks typically generated by
c_rehash). For me, using OpenSSL, this means /etc/ssl/certs/ which has
the usual CAs and my own private CA.

What I've chosen to do is to require verification on smarthost_smtp but
not on remote_smtp. So direct-to-arbitrary hosts have no more
protection than they ever had, against someone who can hijack a TCP
session or fake DNS, but do have protection against passive
eavesdropping.

For connections to smarthosts, there is assumed to be a trust
relationship present, and the list of smarthosts is small enough that I
can verify that I have the certificates required. So suddenly there's
more security for outbound email in the usual case.

So this is added to smarthost_smtp above:
# For an explicitly configured smarthost, where we've configured tls, it's
# reasonable to require that we have the TLS certs for verification, too.
tls_verify_certificates = ${extract{tls}{$address_data}{/etc/ssl/certs}{}}


Oh, note also that the use of submission=yes and tls=yes in the
smarthosts file is perhaps misleading. What matters is that
'submission' or 'tls' be present, at all. tls=no will be treated the
same as tls=yes. The only way around this would be to make the
expansion string much more complicated.

You can replace =yes with ="" if that helps keep it clearer that
presence is what matters, not the value.

A full-fledged feature offering, rather than a private use thing, would
allow tls=no to actively disable even trying TLS, since not specifying
tls at all in this smarthosts config just means that TLS is not
required, not that it will not be used. This is left as an exercise to
the reader.

-Phil

--
## List details at http://lists.exim.org/mailman/listinfo/exim-users
## Exim details at http://www.exim.org/
## Please use the Wiki with this list - http://wiki.exim.org/

exim users RSS feed   Index | Next | Previous | View Threaded
 
 


Interested in having your list archived? Contact lists@gossamer-threads.com
 
  Web Applications & Managed Hosting Powered by Gossamer Threads Inc.