Devuan Exim using SRS Daemon (srsd) Pseudo-HOW-TO
The code published here is tested, the tutorial not so much... If you try this, please report back
your experience to improve this tutorial. Thank you!
This Pseudo-HOW-TO describes in short terms how to configure exim Sender Rewriting Scheme
(using srsd to tag forwarded mails) to comply with SPF enabled target hosts.
What you need:
- Devuan GNU/Linux (you need to adapt for systems not using SystemV as init)
- a running installation of Exim v4
- Remote mail accounts on SPF & SRS enabled Systems with
forwarding capabilities for testing
- (optional) a list of your virtual mail domains, that can be retrieved in a bash script
- not being helpless when things go wrong
What you get:
- SRS tags on outgoing forwarded emails
- SRS tag verification on incoming bounce messages during mail reception
- Enable tagging individually per domain or automatically for all SPF enabled domains*
- Tagged messages get sent from the virtual domain the forwarding takes place
- Untagged addresses in bounce message text
- (optional) Untagged addresses for greylisting
*) automatically enabling needs: If your virtual domain list is different than mine, you need to adapt a bash script for retrieving it.
Install Software:
- apt-get update
- apt-get install srs
Configure:
- srsd:
- Install a start-up script for srsd: Download the file
srsd to your /etc/init.d/ directory.
Make it executable (chomd u+x /etc/init.d/srsd)
- Ensure the daemon gets started during boot-up (update-rc.d srsd defaults 02)
- Edit the new file /etc/exim4/srs_domains which holds the domains you want to enable
srs tagging for (nano /etc/exim4/srs_domains). Add one domain per line. For testing purpose
you should only add one domain first. When you are sure things run smooth, you can either use the
mechanism to auto add all SPF enabled domains of your server or add more domains manually. You will
set a reference in step 6 in the Exim section below to this file in your exim configuration by setting
SRS_ENABLED_DOMAINS_FILE pointing to it.
- Create a new file holding the secret for your srs daemon:
- touch /etc/exim4/srsd.secret
- chmod 640 /etc/exim4/srsd.secret
- chgrp Debian-exim /etc/exim4/srsd.secret
Edit the file (nano /etc/exim4/srsd.secret),
and write a random string of at least 40 characters on a single line to it.
Alternatively, if you have pwgen installed, use: pwgen -N 1 -sync 75 > /etc/exim4/srsd.secret
- Solve the smashed case bug in libmail-srs-perl as reported and proposed under Debian bug
#823064:
Edit /usr/share/perl5/Mail/SRS/Daemon.pm and delete the lines 72-74:
# Until we decide that forward() and reverse() can die, this will
# allow us to trap the error messages from those subroutines.
local $SIG{__WARN__} = sub { die @_; };
You need to do this for sure for versions 0.31-5 of libmail-srs-perl and earlier, and maybe for later versions, if the proposed
patch did not make it in the next release. Just check with the following command:
if [ $(grep -c "Until we decide that forward" /usr/share/perl5/Mail/SRS/Daemon.pm) -eq 1 ]; then echo 'Please patch SRS/Daemon.pm!'; else echo "Ok, no patching needed."; fi
Unfortunately with the proposed fix you cannot log the smashed case in exim no more. Or at least I need to find a way around it first...
- Start srsd (service srsd start)
- Exim:
- Download 175_exim4-config_srs
into /etc/exim4/conf.d/router/
If you don't use the Debian "split configuration", put the code between "hubbed_hosts" and "dnslookup_relay_to_domains",
which is in the beginning of the routers section (labelled as "begin routers"; or just put it directly after "begin routers").
- Copy the statements found in acl_check_rcpt.srs.part to /etc/exim4/conf.d/acl/30_exim4-config_check_rcpt
Put the code somewhere to the beginning of the ACL acl_check_rcpt, be sure to place it before the greylisting section.
- Download bounce_message_text
into /etc/exim4/ and reference the the file in /etc/exim4/conf.d/main/01_exim4-config_listmacrosdefs with:
bounce_message_file = /etc/exim4/bounce_message_text
- (optional) If you use BATV already, make sure you do not double tag outgoing mails! You can arrange this by proceeding your
BATV adding code with a condition like this:
${if ! match {$sender_address_local_part} {\N(?i)^SRS[01][=+-].*\N} {\
In my case, I add the BATV tag in the remote_smtp transport (/etc/exim4/conf.d/transport/30_exim4-config_remote_smtp),
the whole section looks like this:
.ifdef BATV_SECRETS
return_path = ${if and{ {def:sender_address} \
{! match {$sender_address_local_part} {\N(?i)^SRS[01][=+-].*\N}}} {\
${prvs{$return_path}{${lookup {$sender_address_domain} lsearch {CONFDIR/BATV_SECRETS} {$value}fail}}}\
}fail}
.endif
- Edit /etc/exim4/conf.d/main/01_exim4-config_listmacrosdefs and search the macro CHECK_RCPT_LOCAL_LOCALPARTS: Delete the slash character "/" from the list of disallowed characters.
- In the same file 01_exim4-config_listmacrosdefs set a reference to the file you created above (in step 3 of the srsd section) by setting
SRS_ENABLED_DOMAINS_FILE = srs_domains
- (optional) You might consider logging more information to the mainlog by adding the statement to /etc/exim4/conf.d/main/01_exim4-config_listmacrosdefs:
MAIN_LOG_SELECTOR = +address_rewrite +received_sender +return_path_on_delivery +sender_on_delivery +smtp_confirmation +smtp_protocol_error +smtp_syntax_error
- If you feel comfortable with what you did, enable SRS tagging by setting USE_SRS = true in /etc/exim4/conf.d/main/01_exim4-config_listmacrosdefs
Just comment it out to stop srs tagging (always reload the exim configuration to take effect!).
- Reload the Exim configuration (service exim4 reload)
- greylistd (optional):
If you use the Debian greylist daemon, you can reconfigure Exim to not hand out SRS and BATV tagged addresses to the daemon.
Since those tags vary for the same sender, greylisting gets disturbing. The provided code also replaces the Debian standard
of greylisting sender host's numerical IP addresses with their domain name. Providers who use server farms to send out messages often
need more than two attempts to deliver a message, when greylisting with numerical IP addresses is in effect. So, this code lists
sender host's domain / untagged sender address / recipient address
sender host's domain:
If the reverse lookup for an IP fails, the IP with a mask of 29 bits (8 addresses) is listed, else the domain name gets listed
reduced to three words for longer domains, reduced to two words for three word domains or added as is for shorter domains.
untagged sender address:
Any SRS tagged sender address gets the prefix and variable part stripped off. If it is a BATV tagged forwarded message (BATV tag
inside an SRS tag), both tags get stripped off. For BATV only tagged addresses the BATV tag gets removed.
recipient address:
This address gets listed without BATV tag, if applicable.
If you feel all right with that, copy the statements found in acl_check_rcpt.greylistd.part to /etc/exim4/conf.d/acl/30_exim4-config_check_rcpt
replacing the original condition block under the deny section of the greylisting ACL configuration. The
condition block starts with the line:
condition = ${readsocket{/var/run/greylistd/socket}\
...
You now can enable using triplets in greylistd:
- Edit /etc/greylistd/config and set savetriplets = true, singlecheck = false and singleupdate = false
- Reload the greylist daemon (service greylist reload)
Advanced setup (optional):
Automatically adding srs tagging to all your domains having a published SPF record can be accomplished as follows:
- Download and edit the script srs_auto_add_domains:
You need to adjust the line after "# process all mail domains" for your setup, if it differs from mine:
I use a flat file having two fields on one line, separated by a colon. The first field contains my virtual domains.
DOMLIST should get populated with all your domains you are handling mails for.
- Adjust the variable EXIM_PRIMARY_DOMAIN in the beginning of the script to contain your primary hostname or primary domain.
This is just one additional entry to DOMLIST.
- If you publish your SPF records only in TXT style, you need to adjust the line: if [ $(dig +noall +short $dom SPF | wc -m) -eq 0 ]; then
or publish your records as SPF RR aswell.
- Save your script to /usr/local/sbin/srs_auto_add_domains, make it executable and test, that it does what it should:
It should gather all your domains that are SPF enabled that you are handling mail for.
- If you are happy with the result, let it execute, when you restart or reload your name server:
Using bind9, you can add a statement to the end of the file /etc/default/bind9:
# regenerate SRS enabled domain list for exim
[ -x /usr/local/sbin/srs_auto_add_domains ] && $(sleep 10; /usr/local/sbin/srs_auto_add_domains "$1") >/dev/null &
This is not safe, if your bind9 can get restartet or reloaded several times within 15 seconds or so. If you are the only one reloading your bind9, that's fine.
You have to add a locking mechanism to the script or use another mean for auto generation (please report back!).
Test your setup:
Instead of sending real messages you may use "-N" command line switch to exim, like the following:
echo -e "Subject: Test01\nno body" | exim -d+all -f <from-address> -N <target-address> 2>&1 | less
- Test the SRS daemon by using the srsc client programm:
- Start the client without any arguments (srsc)
- Enter an address to convert (FORWARD test@someplace.tld mysrs.converting.dom)
- Try to revert the resulting srs tagged address again (REVERSE SRS0=cVlOuW5jNXzKFPUOfPLTsoMH=QE=someplace.tld=test@mysrs.converting.dom)
- Test your new Exim configuration (watch the mainlog less /var/log/exim4/mainlog, press "F"):
Do your tests with your srs-enabled domain (domains listed in /etc/exim4/srs_domains) and with one that is not listed. They should behave differently!
- Send a purely local mail, it shouldn't be tagged.
- Send a local originated mail to a remote address, it shouldn't be tagged.
- Send a mail from remote to a local address, it shouldn't be tagged.
- Send a local originated mail to a forwarded address with a local destination, it shouldn't be tagged.
- Send a mail from remote to a locally forwarded address with a remote destination, it should get tagged.
- Arrange for a remote place tagging forwarded mails and send such a mail through your forwarding server. You should see an SRS1 tag in the outgoing mail.
- Now set up forwarding to a remote non-existent addresses and set up a local forward to :fail: Delivery failed by administrative intent for testing purposes.
You need to test that SRS tagged bounce messages do get checked and delivered correctly. Check the mail header for the X-SRS tag!
- Send a locally originated mail to your remote forwarder, that points to your local :fail: address.
You should get a bounce message back from the remote forwarding server.
- Send a locally originated mail to your remote forwarder, that points to your local forward for a remote failing address.
You should get a bounce message back that your server created.
- Now do the same as in the two previous points over multiple hops.
- Try to send fake bounce messages with no, wrong and smashed case srs tags to you server.
- (optional) Test greylisting:
- Use greylist list --grey to see what gets written to the greylist.
- Use greylist list --white to see what got whitelisted.
Caveats:
Enjoy. Comments and corrections are welcome.
Adrian Zaugg. (info at ente dot limmat dot ch)
(v0.0.7) 2021-07-10
- added hint for testing using "-N"
- DKIM tip added
(v0.0.6) 2019-07-21
- removed BETA note
- targeted for Devuan
(v0.0.5) 2017-01-02
- corrected smashed case code in 175_exim4-config_srs and warning acl
- corrected some typos
(v0.0.4) 2016-09-13
- forgot to mention SRS_ENABLED_DOMAINS_FILE
- give up my perl hack to solve the smashed case bug in favor of the official, better soltuion
history: (v0.0.3) 2016-06-01
Thanks go to Bernd Strehhuber and Xan Charbonnet for pointing out some mistakes!