using exim to filter aliases with #exim filter

Our aliases are spammed like any other account, but filtering on them would require making a real account. I wanted to be able to filter aliases without creating accounts for everything. My first solution was to create an account and filter on that one, then using $original_local_part I could forward to a filtered alias. This works but if someone discovers the filtered alias, they can bypass the filtering.

The exim docs suggested that I could have filtering in the aliases but it didn't seem to work and I kept getting this in the logs:

error in redirect data: missing or malformed local part (expected word or "") in "# Exim filter\n

Looking closer at the docs I found this sentence:

If you are reading the data from a database where newlines cannot be included, you can use the ${sg} expansion item to turn the escape string of your choice into a newline.

Exim isn't interpreting the \n as a newline so it ignores the alias as a filter file. I added the sg to my data part on the alias router and voila, everything works.

data = ${sg{${lookup{$local_part}dbm{/etc/exim/aliases.db}}}{newline}{\n}}

This sg will take any occurence of the word newline in an alias and translate it into a newline. After that when I deliver -d I see the line being translated...


lookup yielded: # Exim filter newline if $sender_address contains proofpoint-pps newline then newline seen finish newline else deliver thomas@example.com newline endif
expanded: # Exim filter
if $sender_address contains proofpoint-pps
then
seen finish
else deliver thomas@example.com
endif

So aliases can be filtered like real accounts this way, you could use the #Sieve filter syntax too but the #Exim filter syntax works well enough for me.