Implementing SRS with Exim and SQLite

Due to issues with SPF-style restrictions I decided I’d take a look at implementing SRS (the Sender Rewriting Scheme, a good description of which is over here) with Exim. I thought it’d be fairly straightforward and well documented, but it wasn’t. I’m left wondering if anybody actually does it like this?

To start with I built Exim on FreeBSD with the SPF and SRS libraries (I used libsrs_alt). This was straightforward enough – although where are the options in the FreeBSD port? – and would be standard across most operating systems.

Since this was a trial run I thought I’d take the lightweight approach and use SQLite rather than set up a full database like MySQL. This again was a straightforward install.

Lets look quickly and the SQLite tables. The instructions on the libsrs_alt site don’t talk about creating these, so I just figured it out for myself. This is what I ended up with:

# sqlite3 /var/tmp/srs.db .dump
BEGIN TRANSACTION;
CREATE TABLE SRS(Key TEXT, Address TEXT, Time INTEGER);
COMMIT;
#

That’s pretty simple. The database should probably live somewhere a bit more permanent though :-).

Right, back to the instructions. Basically we need to add a bit of config and a new router to the exim configuration. Starting with the default configuration I added the following option in the global section:

hide srs_secrets = asecurestringofareasonablelength

And then the following routers:

srs_reverse:
  driver = redirect
  domains = +local_domains
  srs = reverseandforward
  srs_dbinsert = ${lookup sqlite{/var/tmp/srs.db \
    INSERT INTO SRS ('Key', 'Address', 'Time') \
    VALUES ('${srs_db_key}', '${srs_db_address}', \
    strftime('%s','now'))}}
  srs_dbselect = ${lookup sqlite{/var/tmp/srs.db \
    SELECT Address FROM SRS \
    WHERE Key = '${srs_db_key}' \
    AND Time > strftime('%s','now','-30 days') \
    LIMIT 1}}
  data = ${srs_recipient}
srs_forward:
  driver = redirect
  domains = +local_domains
  srs = forward
  srs_dbinsert = ${lookup sqlite{/var/tmp/srs.db \
    INSERT INTO 'SRS' ('Key', 'Address', 'Time') \
    VALUES ('${srs_db_key}', '${srs_db_address}', \
    strftime('%s','now'))}}
  data = $local_part@example.org

As you can see in this case, I’m simply forwarding all email to another domain. That’s not the most useful setup, but again I’m just testing.

Note that I had to put these in the opposite order to the instructions. The first router is looking for addresses that are already SRS encoded (so bounces for forwarded messages, etc). If it doesn’t find one, it just passes on to the next one. So this way round work best for me.

That’s it really. At a simple level this works. I’ve not looking at proper integration in to the forwarding setup or any kind of database maintenance yet. But given the lack of useful documentation online I thought I’d post my findings.

If you’re reading this and thinking “why on earth is he doing it like that?” please drop me a comment below and enlighten me :-).

(Visited 669 times, 1 visits today)
Share

Leave a Reply

Your email address will not be published. Required fields are marked *