/
/
Configuring SRS for Exim

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:

 apt update && apt install srs
 yum update && yum install srs

SRS requires a secret key to function. Generate it with the following command:

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:

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:

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:

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:

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:

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:

        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:

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:

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:

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:

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:

  1. Configure forwarding to the target external mailbox from a mailbox on your server;
  2. Send an email from another external mailbox to the mailbox on your server;
  3. In the email received in the target mailbox, check the headers of the email:
    • The Return-Path header should be in the format <SRS0=abcd=EF=<source_mailbox_domain>=<source_mailbox_name>@srs.domain.com>
    • The spf and Received-SPF headers should be set to pass
    • 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)

This email may be marked as spam: check your Spam and/or Junk folders.