SRS not working for forwarders without a mailbox

plakjeworst

New member
Joined
Apr 28, 2016
Messages
4
I'm using the latest EXIM spamblocker configuration, which includes SRS support. However, SRS only works for a forwarded e-mail address if there is also a virtual mailbox for the same account.
I suspect this is because the forwarder redirect router in exim uses the 'unseen' option. This duplicates the recipient address so that if there is any mailbox for it, it will get delivered as well. The drop_solo_alias router will drop the copy if there was no mailbox for it after all. Some time ago I tried to add a header with headers_add in the forwarder router and these would also only work if there was both a forwarder and a mailbox, since unseen removes the headers for one of the copies, and it appears the wrong copy is removed by the drop_solo_alias router). It might be that something similar is the case for the srs router option.
 
Bump thread

I also notices that forwarding email without virtual mailbox on my DA server isn't triggering SRS rewrite. This is somewhat big issue, many of my clients are using only forwarding option without using mailboxes. Many outgoing email are bounced back because of SPF rules - and this is normal behaviour, our server (and many other) aren't allowed to send emails on behalf of, for example, yahoo, hotmail etc. In this scenario SRS rewrite'ing is crucial.

I tried to modify exim.conf but unfortunately my knowledge isn't enough for this task.
 
We have the exact same problem. The unseen option makes SRS header rewrite get lost and thus SRS does not work for e-mail addresses that have no local mailbox with the same name. If there is a local mailbox with the same name as the forwarder, then SRS works fine. Please, someone provide a fix for this.
 
Thanks for the report. I've confirmed the issue.
I had to hunt, but found that yes, the headers/changes for "unseen" are supposed to be dropped:
http://www.exim.org/exim-html-current/doc/html/spec_html/ch-generic_options_for_routers.html
Warning 2: If the unseen option is set on the router, all header additions are deleted when the address is passed on to subsequent routers. For a redirect router, if a generated address is the same as the incoming address, this can lead to duplicate addresses with different header modifications. Exim does not do duplicate deliveries (except, in certain circumstances, to pipes -- see section 22.7), but it is undefined which of the duplicates is discarded, so this ambiguous situation should be avoided. The repeat_use option of the redirect router may be of help.

But I had an idea to flip things around to make a virtual_user_unseen router for the forward+save case.
An "unseen" router does it's action (assuming conditions are met) and continues on.
A "seen" router (default) does it's action, then stops further deliveries.

Currently, we have:
Code:
virtual_aliases_nostar:
    unseen
    #secretly forwards, then continues if email account
virtual_user:
    seen
    #visibly saves the email
virtual_aliases:
    seen
    #visibly forwards if no local email
and the idea would be to flip it so that the local save is unseen, so all aliasse are seen, so srs works..
so logically, like this:
Code:
virtual_user_unseen:
    unseen
    condition = local exists, and fowrarder also exists (so we know it will catch later)
    #secretly saves locally, then continues to forward
virtual_aliases:
    seen
    #visibly forwards. Local save might or might not have happened, it doesn't matter
virtual_user:
    seen
    #visibly saves the email locally.
So, that's my thought... if anyone sees any glaring logical errors with that, let me know.
I'll try and find some time later to test it out.

I've already tried the repeat_use, and repeat_use = false with the old way, but it didn't make any difference.
There is also mention of the $address_data option, but not sure if that's going to help us with the old method (unless someone knows more about it's use in this context)

John
 
Ok.. I think we have a working version, although it's somewhat more complicated than expected due to the seen catch-all case (virtual_aliases) stealing the delivery from virtual_user with a * :fail:

So, here's what I've ended up with:
Code:
#forwarder exists
#user exists
virtual_user_unseen:
  driver = accept
  condition = ${lookup{$local_part}lsearch{/etc/virtual/${domain}/aliases}{1}{0}}
  condition = ${perl{save_virtual_user}}
  domains = lsearch;/etc/virtual/domainowners
  group = mail
  retry_use_local_part
  transport = dovecot_lmtp_udp
  unseen


#forwarder exists
#user does not exist
virtual_aliases_nouser_nostar:
  driver = redirect
  .include_if_exists /etc/exim.srs.forward.conf
  allow_defer
  allow_fail
  condition = ${lookup{$local_part}lsearch{/etc/virtual/${domain}/aliases}{1}{0}}
  condition = ${lookup{$local_part}lsearch{/etc/virtual/${domain}/passwd}{0}{1}}
  data = ${lookup{$local_part}lsearch{/etc/virtual/$domain/aliases}}
  file_transport = address_file
  group = mail
  pipe_transport = virtual_address_pipe
  retry_use_local_part


#forwarder does not exist
#user exists
virtual_user:
  driver = accept
  condition = ${lookup{$local_part}lsearch{/etc/virtual/${domain}/aliases}{0}{1}}
  condition = ${perl{save_virtual_user}}
  domains = lsearch;/etc/virtual/domainowners
  group = mail
  retry_use_local_part
  transport = dovecot_lmtp_udp


#wildcard forwarder
#user should have already been caught above
virtual_aliases:
  #only the wildcard will be used here
  driver = redirect
  .include_if_exists /etc/exim.srs.forward.conf
  allow_defer
  allow_fail
  data = ${if exists{/etc/virtual/$domain/aliases}{${lookup{$local_part}lsearch*{/etc/virtual/$domain/aliases}}}}
  file_transport = address_file
  group = mail
  pipe_transport = virtual_address_pipe
  retry_use_local_part
If anyone has time to really give it a workout with as many cases as they can, that would be helpful.
I think it's covered, but we just need to really be sure before I add it to exim.conf 4.4.7 :)

The "data" in the virtual_aliases section can likely be simplified to the data in virtual_aliases_nouser_nostar, since we know aliases will always exist, but I didn't want to change the old code just yet until we know it works, then I'll swap it out.

John
 
I've been testing these changes out for a while now on a live test box, and seems to working.
As this is a major core changes to the file, I've released it as SpamBlocker 4.5.0, in testing.
I've uploaded all changes to files1, all mirrors should get them shortly.

If you'd like to use it, you'd need:
1) The latest CustomBuild 2.0 rev 1598+
2) Run
Code:
./build update
./build version
./build set eximconf_release 4.5
./build exim_conf

John
 
Thank you for the update. SRS now works, but delivering mail to da_user@da_server_hostname (the default user@server mailbox) results in error message in exim mainlog:

2016-10-18 16:57:48 1bwUto-0000HZ-Oq failed to expand condition "${if and{{bool_lax{${if and{{bool_lax{NULL}}{bool_lax{${lookup{$local_part}lsearch{/etc/virtual/${domain}/aliases}{1}{0}}}}}}}}{bool_lax{${lookup{$local_part}lsearch{/etc/virtual/${domain}/passwd}{0}{1}}}}}}" for virtual_aliases_nouser_nostar router: failed to open /etc/virtual/[SERVER_HOSTNAME]/aliases for linear search: No such file or directory inside "and{...}" condition inside "and{...}" condition

And of course there is no /etc/virtual/[SERVER_HOSTNAME]/aliases file. Can this be solved in exim.conf or do we have to create the file?

I replaced the real server hostname with [SERVER_HOSTNAME].
 
Thanks, I've added a few extra conditions for it to check. It's still 4.5.0.
Once updated, you'll see:
Code:
#forwarder exists
#user exists
virtual_user_unseen:
  driver = accept
[B]  condition = ${if exists{/etc/virtual/${domain}/passwd}{1}{0}}[/B]
  condition = ${lookup{$local_part}lsearch{/etc/virtual/${domain}/aliases}{1}{0}}
  condition = ${perl{save_virtual_user}}
  domains = lsearch;/etc/virtual/domainowners
  group = mail
  retry_use_local_part
  transport = dovecot_lmtp_udp
  unseen


#forwarder exists
#user does not exist
virtual_aliases_nouser_nostar:
  driver = redirect
  .include_if_exists /etc/exim.srs.forward.conf
  allow_defer
  allow_fail
[B]  condition = ${if exists{/etc/virtual/${domain}/passwd}{1}{0}}[/B]
  condition = ${lookup{$local_part}lsearch{/etc/virtual/${domain}/aliases}{1}{0}}
  condition = ${lookup{$local_part}lsearch{/etc/virtual/${domain}/passwd}{0}{1}}
  data = ${lookup{$local_part}lsearch{/etc/virtual/$domain/aliases}}
  file_transport = address_file
  group = mail
  pipe_transport = virtual_address_pipe
  retry_use_local_part


#forwarder does not exist
#user exists
virtual_user:
  driver = accept
[B]  condition = ${if exists{/etc/virtual/${domain}/passwd}{1}{0}}[/B]
  condition = ${lookup{$local_part}lsearch{/etc/virtual/${domain}/aliases}{0}{1}}
  condition = ${perl{save_virtual_user}}
  domains = lsearch;/etc/virtual/domainowners
  group = mail
  retry_use_local_part
  transport = dovecot_lmtp_udp


#wildcard forwarder
#user should have already been caught above
virtual_aliases:
  #only the wildcard will be used here
  driver = redirect
  .include_if_exists /etc/exim.srs.forward.conf
  allow_defer
  allow_fail
  data = ${if exists{/etc/virtual/$domain/aliases}{${lookup{$local_part}lsearch*{/etc/virtual/$domain/aliases}}}}
  file_transport = address_file
  group = mail
  pipe_transport = virtual_address_pipe
  retry_use_local_part
To get it from files1 (or other mirrors within 24 hours)
Code:
./build update
./build exim_conf
John
 
So far i didn't notice any problems with SpamBlocker 4.5.0. Forwards and SRS is working great, tested with and without a real mailbox in DirectAdmin.

Also thanks for moving the TLS options in 4.5.0 to exim.variables.conf.default:
Code:
tls_certificate
tls_privatekey
tls_require_ciphers
openssl_options

Now we can add these to exim.variables.conf.custom (with custom settings) and rebuild exim_conf without having to re-edit exim.conf afterwards. :)
 
With John we have tested the TLS for Exim in order to automatically have certificates for incoming mail (IMAP/POP) with Dovecot.
As soon as exim support TLS and is able to capture the host you're connecting to, this will be working also for exim.

Hope John will implement the functionality for Dovecot as soon as possible, many customers will appreciate :)

Best regards
 
@John,

I'm not quite sure as of yet what might be wrong, but it seems sender verification fails if it's done for locally hosted email. Here is a picture

serverA hosts domain example.com. We have forwarders:

Code:

An email arrived to any forwarder and SRS rewrites its address to


and now if I try to verify address the way it was modified by SRS on serverA it fails:

Code:
[root@serverA etc]# exim -bvs [email protected]
[email protected] failed to verify:

But if I do it from another serverB, it succeeds:

Code:
[root@serverB etc]# exim -bvs [email protected]
[email protected] verified

Now comes the question, how can we solve it? Why email addresses modified by SRS can not be verified locally on the server where they are hosted?

exim.conf 4.5.0 with SRS.

p.s. I'm actively reading exim docs on the matter, and hope to find answers soon.
 
It fails in virtual_aliases router:

Code:
--------> virtual_aliases router <--------
local_part=srs0=gqchfk=wl=host.example.org=hello domain=example.com
calling virtual_aliases router
rda_interpret (string): ${if exists{/etc/virtual/$domain/aliases}{${lookup{$local_part}lsearch*{/etc/virtual/$domain/aliases}}}}
search_open: lsearch "/etc/virtual/example.com/aliases"
  cached open
search_find: file="/etc/virtual/example.com/aliases"
  key="srs0=gqchfk=wl=host.example.org=hello" partial=-1 affix=NULL starflags=1
LRU list:
  6/etc/virtual/example.com/aliases
  6/etc/virtual/domainowners
  6/etc/virtual/domains
  End
internal_search_find: file="/etc/virtual/example.com/aliases"
  type=lsearch key="srs0=gqchfk=wl=host.example.org=hello"
cached data used for lookup of srs0=gqchfk=wl=host.example.org=hello
  in /etc/virtual/example.com/aliases
lookup failed
trying to match *
internal_search_find: file="/etc/virtual/example.com/aliases"
  type=lsearch key="*"
file lookup required for *
  in /etc/virtual/example.com/aliases
lookup yielded: :fail:
expanded: :fail:
file is not a filter file
parse_forward_list: :fail:
extract item: :fail:
virtual_aliases router forced address failure
[email protected] failed to verify:
search_tidyup called
>>>>>>>>>>>>>>>> Exim pid=11728 terminating with rc=2 >>>>>>>>>>>>>>>>
 
If you'd like to use it, you'd need:
1) The latest CustomBuild 2.0 rev 1598+
2) Run
Code:
./build update
./build version
./build set eximconf_release 4.5
./build exim_conf

John

How do we update CustomBuild to rev 1598+ ?

when i update to either exim.conf 4.4 or 4.5 i get this error about srs

Code:
Restarting exim.
Shutting down exim: /etc/init.d/exim: line 40: kill: (135318) - No such process

Starting exim: 2016-12-09 22:05:33 Exim configuration error in line 1 of /etc/exim.srs.conf:
  main option "srs_config" unknown

comment out exim.srs.forward.conf & exim.srs.conf and restart then error again;

Code:
Starting exim: 2016-12-09 22:13:21 Exim configuration error in line 758 of /etc/exim.conf:
  option "srs" unknown

comment out line 758 and Exim ok starts.

So how do we fix this ?
 
Try to rebuild exim: /usr/local/directadmin/custombuild/build exim

Than try again to install eximconf release 4.5

Also, not sure, but you may need/want to enable ESF and BC.

Best regards
 
Try to rebuild exim: /usr/local/directadmin/custombuild/build exim

Than try again to install eximconf release 4.5

Also, not sure, but you may need/want to enable ESF and BC.

Best regards

Ok after updating Exim and these messages disapear.

did the following;

cd /usr/local/directadmin/custombuild
./build update
./build set eximconf yes
./build set eximconf_release 4.4
./build set blockcracking yes
./build set easy_spam_fighter yes
./build set spamassassin yes
./build update
./build exim_conf
 
Back
Top