From Halon, SMTP software for hosting providers
Jump to: navigation, search

Normally, the Halon platform operates in a traditional store-and-forward MTA fashion. In some cases however, such as providing outbound filtering for a network of computers, it's desired to run the software in a more proxy-like setup.

Transparent operation

One aspect of proxying is being more transparent. Please keep in mind that many of the recommended methods for dealing with spam and blacklisting is hampered as you move towards a more transparent mode of operation.

Original source

When delivering email out from the gateway, the source address can be changed using the SetSourceIP() function. By enabling the system_nonlocal_source system setting, any (such as the connecting/sending client's IP) address can be used

if ($senderip)
SetSourceIP($senderip, ["nonlocal_source" => true]);
if (

Please keep in mind that your routers/firewalls needs to be configured in such a way so that the returning traffic is routed back to the Halon system.

Original destination

We argue that "forcing" the email to be sent to the $recipientdomain's (RCPT TO) MX by simply relying on the normal behaviour of a "lookup-mx" transport is a powerful security/anti-spam feature. However, in some cases it might be necessary to send the message to the original destination IP address that the sending client connected to. This requires a load balancer in front of the Halon system, that can append the destination IP as a header to the message. If you don't have a load balancer, you can setup a simple SMTP proxy on for example Linux, using the SO_ORIGINAL_DST socket option. The header can be read from the DATA script

SetMetaData(["orig_dest" => GetHeader("x-orig-dest")]); 

and used in the pre-delivery script when sending the message

$meta GetMetaData();
if (

You could in theory even forward authentication information from the AUTH script to the pre-delivery script's SetSASL() function, although that seems like a poor idea from a security perspective.

Fully transparent mode

If the semi-transparent method described in the previous chapter isn't suitable, one can use an external proxy that handles all communication between client and server with the Halon system on "the side" (inspecting the messages, and coming up with an verdict).


The open source ProxSMTP by Stef Walter (currently at Red Hat) is ideal for a fully transparent setup, and available as a package for most Linux and *BSD distributions.

Using Halon's modified version

For high performance systems, we recommend that you use our ProxSMTP version which enables direct communication from ProxSMTP to Halon nodes without invoking an external program. It is configured like

FilterType: smtp
FilterCommand: IP-OF-HALON

Using ProxSMTP with a Halon cluster

ProxSMTP does not have built-in support for load balancing traffic against a cluster of Halon nodes but this can be easily accomplished by installing a separate load balancer (for example HAProxy) and using a configuration similar to this:

 listen smtp
     mode tcp
     option tcplog
     option smtpchk
     balance roundrobin
     server halon1 check
     server halon2 check

and then using the listener for the load balancer as the FilterCommand in ProxSMTP.

Using pre-compiled versions with a script

It is possible to use a stock (packaged) ProxSMTP with Halon using a FilterCommand script, although this isn't recommended. The proof-of-concept Python code below can be used for lower traffic volumes.

#!/usr/bin/env python
# Proof-of-concept proxy-to-Halon FilterCommand script for ProxSMTP
import os, smtplib, sys
    cn = smtplib.SMTP()
    cn.connect('', 25)
        open(os.environ['EMAIL'], 'r').read())
except smtplib.SMTPDataError as e:
    sys.stderr.write(str(e[0]) + ' ' + e[1] + '\r\n')
except Exception:

In-line delivery

Although the system operates more efficiently in queued mode (because the system can schedule more freely), sometimes you want queue-less, in-line delivery using DirectDeliver(). It's also possible to combine queued delivery in the Halon and in-line delivery for a client, using an external SMTP proxy which reacts to callbacks from a post-delivery script such as

http("https://smtp-proxy/callback", [], [], ["code" => $errorcode"msg" => $errormsg"id" => $messageid]);
Delete(); // no more retries 

While developing such a proxy might seem like a daunting task; we have customers who have done so in reasonable short time using high-level frameworks such as Twisted.