0

My exim relays all its incoming email to third-party smtp relays. They use smtp authentication (username/password).

It seems I can only define ONE username/password in the begin authenticators section of the Exim config. I want to route certain email through one relay (with its own username/password auth), and other email through a second relay (its username/password auth is different than the first).

Here's much of my config. The begin routers relays domains in the +local_domains list to smtp-relay-1 and the rest relays to smtp-relay-2.

begin routers

my_domains_relay:
  debug_print = "R: my_domains_relay for $local_part@$domain"
  driver = manualroute
  domains = +local_domains
  transport = remote_smtp_smarthost
  route_list = * "<+ smtp-relay-1.example.com:465"
  host_find_failed = defer
  no_more

smart_host_relay:
  debug_print = "R: smart_host_relay for $local_part@$domain"
  driver = manualroute
  transport = remote_smtp_smarthost
  route_list = * "<+ smtp-relay-2.example.net:465"
  host_find_failed = defer
  no_more

begin transports

remote_smtp_smarthost:
  debug_print = "T: remote_smtp_smarthost for $local_part@$domain"
  driver = smtp
  port = 465
  hosts_require_tls = *
  hosts_require_auth = *
  protocol = smtps

begin authenticators

login:
  driver = plaintext
  public_name = PLAIN
  client_send = ^my-username^top-secret-password

What I want is to define separate username/password auth in the begin authenticators section, and assign each to a single router/transport. Right now, the username/password auth is global and used for all relays.

The exim documentation says it matches the public_name with an advertised authentication by the server. So if both my smtp relays advertise as AUTH PLAIN then they both use that one authenticators username/password in the config. I'm hoping there's a setting that allows me to link an authenticators instance with a specific router/transport, but I don't see how.

Crash Override
  • 601
  • 1
  • 10
  • 21

2 Answers2

0

You can use the client_condition authenticator option (cf. Section SMTP authentication of the manual).

Exim accepts at most two authenticators for a given public name: as client side and a server side authenticator.

However the functionality you are seeking is already in Debian's default configuration: dowload the exim4-config package and extract the files (its an ar archive containing two tar archives).

The file /etc/exim4/conf.d/auth/30_exim4-config_examples contains client authenticators that:

  1. read the password from the /etc/exim4/passwd.client file, so the password is not in Exim's configuration. The format of the file is a line per server in the <servername>:<username>:<password> format,
  2. choose the password according to the host,
  3. are well tested, so you don't have to test Exim's string expansions.

Debian configuration boils up to the following client authenticator:

# this returns the matching line from passwd.client and doubles all ^
PASSWDLINE=${sg{\
                ${lookup{$host}nwildlsearch{CONFDIR/passwd.client}{$value}fail}\
                }\
                {\\N[\\^]\\N}\
                {^^}\
            }

plain:
  driver = plaintext
  public_name = PLAIN
.ifndef AUTH_CLIENT_ALLOW_NOTLS_PASSWORDS
  client_send = "<; ${if !eq{$tls_out_cipher}{}\
                    {^${extract{1}{:}{PASSWDLINE}}\
                     ^${sg{PASSWDLINE}{\\N([^:]+:)(.*)\\N}{\\$2}}\
                   }fail}"
.else
  client_send = "<; ^${extract{1}{:}{PASSWDLINE}}\
                    ^${sg{PASSWDLINE}{\\N([^:]+:)(.*)\\N}{\\$2}}"
.endif
Piotr P. Karwasz
  • 5,748
  • 2
  • 11
  • 21
  • Thanks but did not work. I get: `Exim configuration error: two client authenticators (login_one and login_two) have the same public name (PLAIN)`. This was after I created `login_one` and `login_two` under `begin authenticators`, each with different `client_condition`. Looks like Exim insists on just one `public_name = PLAIN` no matter what. I'm using Exim 4.94, the latest stable release as of this comment. – Crash Override Jan 14 '21 at 16:01
  • I actually tested my answer and came to the same conclusion you did. :-) Debian uses only one authenticator for all servers, I copied its authentication into the answer. – Piotr P. Karwasz Jan 17 '21 at 15:56
0

In the same authenticator, you can use if-condition to select set of username:password to authenticated. But you need the "condition" to choose which relay to be used first.

For example, for mail send to user@domain1.com will use smtp-relay-1.example.com authenticated by my-username:top-secret-password, and user@domain2.com will use smtp-relay-2.example.com authenticated by my-username2:top-secret-password2

The routers and transports will be the same

begin routers

my_domains_relay:
  debug_print = "R: my_domains_relay for $local_part@$domain"
  driver = manualroute
  domains = +local_domains
  transport = remote_smtp_smarthost
  route_list = * "<+ smtp-relay-1.example.com:465"
  host_find_failed = defer
  no_more

smart_host_relay:
  debug_print = "R: smart_host_relay for $local_part@$domain"
  driver = manualroute
  transport = remote_smtp_smarthost
  route_list = * "<+ smtp-relay-2.example.net:465"
  host_find_failed = defer
  no_more

begin transports

remote_smtp_smarthost:
  debug_print = "T: remote_smtp_smarthost for $local_part@$domain"
  driver = smtp
  port = 465
  hosts_require_tls = *
  hosts_require_auth = *

The authenticators need to change to something like this

begin authenticators

login:
  driver = plaintext
  public_name = PLAIN
  client_send = ^${if   eq{$domain}{domain1.com}\
                        {my-username}\
                        {my-username2}}\
                ^${if   eq{$domain}{domain1.com}\
                        {top-secret-password}\
                        {top-secret-password2}}