Super User is a question and answer site for computer enthusiasts and power users. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

I have an exim email server that is used for multiple websites. It uses a different host string for helo_data for each website that it serves. DNS and rDNS for each applicable host string is properly set-up.

I want to be to log in the exim mainlog which host string was used for each email sent.

Is this possible and if not, what are my options to know which host string was used in HELo on a per email basis?

Thank you

share|improve this question
How are you telling exim to switch between the helo_data values? – Majenko Mar 27 '11 at 19:53
Since each value of helo_data needs its own ip (interface) I am assigning a value to interface based on the value of $sender_address_domain. If a particular domain has more than one interface that pertains to it, it will chose one at random. After interface is assigned, it then uses the value of $sending_ip_address to chose the correct value for helo_data. The solution sounds convoluted but it works and is only minimally complicated. A script writes the appropriate config strings so it is not "hard to maintain" either. Not enough room in this response, I'll post code snippets after. – Radmilla Mustafa Mar 27 '11 at 20:00
interface = ${extract{$sender_address_domain}{${extract{${eval:1 + ${randint:2}}}{:}{}{$value}{}}}{$value}{}} helo_data = ${extract{$sending_ip_address}{}{$value}{}} – Radmilla Mustafa Mar 27 '11 at 20:05
I assume this is done within the transport section? – Majenko Mar 27 '11 at 20:20
yes, within the transport. It has been pretty thoroughly tested and it works as expected. – Radmilla Mustafa Mar 27 '11 at 20:26
up vote 1 down vote accepted

If you can decide upon the helo data in the ACL stage, you can assign it to an $acl_m_... variable ($acl_m_outbound_helo), which can be referenced anywhere in the lifetime of the message. You probably want to do this in the DATA ACL, based entirely upon the sender, not the recipient.

You can then use log_message in that same ACL to log the value; it will go into the mainlog together with the Exim message id, for correlation. Then in the transport, you just reference that same $acl_m_outbound_helo to use for the connection.

share|improve this answer
this sounds very promising! I will give it a try and get back shorty. – Radmilla Mustafa Mar 27 '11 at 21:12
I added log_message to every ACL accept, restarted exim of course, but no message is added to the mainlog. Looking at the documentation, I only see log_message referred to in sections that deal with deny warn and defer. Does log_message not apply to accept or am I overlooking something else? – Radmilla Mustafa Mar 27 '11 at 21:58
I do believe accept does not allow log_message, however warn looks as though it is what I am looking for. I'll come back here and give a status update. – Radmilla Mustafa Mar 27 '11 at 22:05
Adding a warn condition = true to the data acl seems to work well. I haven't yet implimented the full solution but from here I think it should be a simple matter, my main obstacle is conquered. Thank you! – Radmilla Mustafa Mar 27 '11 at 22:19

Unfortunately there is no built-in method for logging the helo_data variable to the mainlog file.

The method I would probably use would either to be to add a hook somewhere within the message path to log the data I am looking for to another file with some reference to point back to the entries in the mainlog file (say the message ID), or I would set up a separate router & transport on a per-website basis. The transport used to send the mail is logged in the mainlog file as the T=my_transport value.

For the custom logging I have managed to do something similar for inserting of received email details into a database using the condition = value in the router. You could use the ${run{<command> <args>}} string expansion to achieve this:

condition = ${run{/path/to/interpreter /path/to/custom/logging/script $sender_domain $message_exim_id}{1}{0}}


That little snippet in the router will execute the script /path/to/custom/logging/script using the interpreter /path/to/interpreter (/bin/sh, /usr/bin/perl, whatever) passing it the domain name of the sender and the Exim message ID.

It's fairly heavyweight, so wouldn't be ideal on a heavy usage server, but it might just work....

share|improve this answer
I too thought of setting up different transports for each domain, this would work sure fire. The only problem being that I could potentially end up some day with dozens of transports which all have near identical configs, and this would be very hard to maintain, even if it is script generated. I am not quite sure what you mean when you say "add a hook somehwere within the message path," could you clarify for me? Thank you. – Radmilla Mustafa Mar 27 '11 at 20:36
How's that? (see edit) – Majenko Mar 27 '11 at 22:05
That is a little bit too resource intensive for my needs, we do send a lot of email and executing a shell each time is not ideal. Thank you for your insight though. – Radmilla Mustafa Mar 27 '11 at 22:20

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .