Configuring SRS for Exim
SRS (Sender Rewriting Scheme) is used to replace the sender's address to pass SPF verification. SRS is also used to determine the origin (local or remote mail server) of bounced emails with errors and to identify unavailable addresses in the recipient list.
To check if it is supported on your Exim server, run the following command:
exim -bV | grep -i srs
An empty output indicates that SRS is not supported.
Domain preparation
The domain for SRS must be public and accessible for managing its DNS records. It is recommended to use a subdomain of srs, for example, srs.domain.com. This will prevent the reputation of the domains (primary and subdomain) from mixing and will simplify setup.
The domain's MX record must point to your mail server:
srs.domain.com. IN MX 10 mail.mydomain.com.
The TXT record for SPF must authorize the IP address of the mail server. For example, if the address for the mail domain mail.mydomain.com is 10.0.0.1, the record would be the following:
srs.domain.com. IN TXT "v=spf1 ip4:10.0.0.1 -all"
The domain for SRS itself must resolve to the same IP address via an A record:
srs.domain.com. IN A 10.0.0.1
Exim configuration without SRS support
Install SRS using a separate utility:
Debian-based systemsRHEL-based systems
apt update && apt install srs
yum update && yum install srs
SRS requires a secret key to function. Generate it with the following command:
Debian-based systemsRHEL-based systems
openssl rand -base64 32 | tr -d '\n' > /etc/exim4/srs.secret
openssl rand -base64 32 | tr -d '\n' > /etc/exim/srs.secret
Next, set the permissions on the key file:
Debian-based systemsRHEL-based systems
chown Debian-exim:Debian-exim /etc/exim4/srs.secret
chmod 640 /etc/exim4/srs.secret
chown exim:exim /etc/exim/srs.secret
chmod 640 /etc/exim/srs.secret
Create wrapper for the utility:
touch /usr/local/bin/srs-forward.sh
Add the following code to the created file:
#!/bin/bash
SECRETFILE="/etc/exim4/srs.secret"
ALIAS="srs.domain.com"
ADDRESS="$1"
if [ -z "$ADDRESS" ] || [ "$ADDRESS" = "<>" ]; then
exit 1
fi
RESULT=$(/usr/bin/srs --secretfile="$SECRETFILE" --forward --address="$ADDRESS" --alias="$ALIAS" 2>/dev/null)
if [[ "$RESULT" =~ ^SRS[01]=.*@ ]]; then
echo -n "$RESULT" | tr -cd '[:alnum:]=@._+-'
exit 0
else
exit 1
fi
Set the permissions on the created wrapper:
Debian-based systemsRHEL-based systems
chmod 755 /usr/local/bin/srs-forward.sh
chown root:Debian-exim /usr/local/bin/srs-forward.sh
chmod 755 /usr/local/bin/srs-forward.sh
chown root:exim /usr/local/bin/srs-forward.sh
Next, make configuration changes in the /etc/exim4/exim4.conf.template file (/etc/exim/exim.conf for RHEL-based systems).
In the begin transports section of the remote_smtp block, add the following lines after driver = smtp:
debug_print = "T: remote_smtp for $local_part@$domain, Return-Path: $return_path"
return_path = ${if !match_domain{$sender_address_domain}{+local_domains}{${run{/usr/local/bin/srs-forward.sh $sender_address}{$value}{$sender_address}}}{$sender_address}}
The block should look like this:
remote_smtp:
driver = smtp
debug_print = "T: remote_smtp for $local_part@$domain, Return-Path: $return_path"
return_path = ${if !match_domain{$sender_address_domain}{+local_domains}{${run{/usr/local/bin/srs-forward.sh $sender_address}{$value}{$sender_address}}}{$sender_address}}
In the begin routers section, add the following block to create a router for SRS before the dnslookup block:
Debian-based systemsRHEL-based systems
srs_router:
driver = redirect
domains = +local_domains
local_part_prefix = SRS0 : SRS1
data = ${run{/usr/bin/srs --secretfile=/etc/exim4/srs.secret --reverse --address=$local_part@$domain}{$value}{:fail: Invalid SRS address}}
redirect_router = dnslookup
allow_fail
srs_router:
driver = redirect
domains = +local_domains
local_part_prefix = SRS0 : SRS1
data = ${run{/usr/bin/srs --secretfile=/etc/exim/srs.secret --reverse --address=$local_part@$domain}{$value}{:fail: Invalid SRS address}}
redirect_router = dnslookup
allow_fail
Save the changes and restart Exim:
service exim4 restart
Exim configuration with SRS support
SRS requires a secret key to function. Generate it with the following command:
Debian-based systemsRHEL-based systems
openssl rand -base64 32 | tr -d '\n' > /etc/exim4/srs.secret
openssl rand -base64 32 | tr -d '\n' > /etc/exim/srs.secret
Next, set the permissions on the key file:
Debian-based systemsRHEL-based systems
chown Debian-exim:Debian-exim /etc/exim4/srs.secret
chmod 640 /etc/exim4/srs.secret
chown exim:exim /etc/exim/srs.secret
chmod 640 /etc/exim/srs.secret
Next, make configuration changes to the /etc/exim4/exim4.conf.template file (/etc/exim/exim.conf for RHEL-based systems).
In the begin routers section, add the following block between the .include and dnslookup directives to create a router for SRS:
Debian-based systemsRHEL-based systems
srs_return:
driver = redirect
senders = :
condition = ${if inbound_srs{$local_part}{${readfile{/etc/exim4/srs.secret}{}}}{yes}{no}}
data = $srs_recipient
redirect_router = dnslookup
allow_defer
no_verify
srs_return:
driver = redirect
senders = :
condition = ${if inbound_srs{$local_part}{${readfile{/etc/exim/srs.secret}{}}}{yes}{no}}
data = $srs_recipient
redirect_router = dnslookup
allow_defer
no_verify
Add the following line to the remote_smtp section after the line with the helo_data directive:
Debian-based systemsRHEL-based systems
return_path = ${if and{{def:original_domain}{!match{$return_path}{^SRS[01]=}}} \
{${srs_encode{${readfile{/etc/exim4/srs.secret}{}}}{$return_path}{srs.domain.com}}} \
{$return_path}}
return_path = ${if and{{def:original_domain}{!match{$return_path}{^SRS[01]=}}} \
{${srs_encode{${readfile{/etc/exim/srs.secret}{}}}{$return_path}{srs.domain.com}}} \
{$return_path}}
In the line with the interface parameter, specify the server's public IP address:
Debian-based systemsRHEL-based systems
interface = ${lookup{$sender_address_domain}lsearch{/etc/exim4/domainips}{$value}{<public_server_ip_address>}}
If using NAT, use the IP address pointing to the router with the public external IP address.
Save the changes and restart Exim:
service exim4 restart
Checking SRS operation
Encoding
Use the following command to check encoding:
Debian-based systemsRHEL-based systems
exim -be '${srs_encode{${readfile{/etc/exim4/srs.secret}{}}}{user@example.com}{srs.domain.com}}'
exim -be '${srs_encode{${readfile{/etc/exim/srs.secret}{}}}{user@example.com}{srs.domain.com}}'
Use the following command to check decoding:
Debian-based systemsRHEL-based systems
exim -be '${if inbound_srs{SRS0=xxxx=xx=example.com=user}{${readfile{/etc/exim4/srs.secret}{}}}{$srs_recipient}{failed}}'
exim -be '${if inbound_srs{SRS0=xxxx=xx=example.com=user}{${readfile{/etc/exim/srs.secret}{}}}{$srs_recipient}{failed}}'
Checking headers
To check that the headers in the email are transmitted correctly, follow these steps:
- Configure forwarding to the target external mailbox from a mailbox on your server;
- Send an email from another external mailbox to the mailbox on your server;
- In the email received in the target mailbox, check the headers of the email:
- The
Return-Pathheader should be in the format<SRS0=abcd=EF=<source_mailbox_domain>=<source_mailbox_name>@srs.domain.com> - The
spfandReceived-SPFheaders should be set topass - The DKIM header should be in the format
dkim=pass header.i=@<source_mailbox_domain> - The DMARC header should be in the format
dmarc=pass (p=NONE)
- The
This email may be marked as spam: check your Spam and/or Junk folders.