Postfix send via Proxychains

I run my own Postfix server on my laptop, since I have my own vanity domain, and thus like to send email with various local usernames. This works fine when I'm at work, but my home IP address falls into a block that Verizon intentionally DNS-blacklists. So, I figured out how to get Postfix to send mail via a SOCKS proxy via SSH.

It basically boils down to installing ProxyChains, configuring it, editing a Postfix file, and running the SSH proxy.

Required software

The following software is required. The versions I used are also listed, but not necessarily required. I use Gentoo Linux, so versions might be slightly different than upstream.

Software/homepageVersion
Postfix2.5.5
ProxyChains3.1
OpenSSH5.1_p1-r1
Perl5.10.0-r1
Lsof4.78-r2

Install ProxyChains

After installing ProxyChains, I found the following modification useful: Some programs don't work right with the simple wrapper if it outputs the version information.

Original /usr/bin/proxychains:

#!/bin/sh
echo "ProxyChains-3.1 (http://proxychains.sf.net)"
if [ $# = 0 ] ; then
    echo "  usage:"
[...etc...]

Modified /usr/bin/proxychains:

#!/bin/sh
if [ $# = 0 ] ; then
    echo "ProxyChains-3.1 (http://proxychains.sf.net)"
    echo "  usage:"
[...etc...]

Configure ProxyChains

These are all the non-commented lines in my /etc/proxychains.conf. I think the tcp_* options are the defaults.

strict_chain
quiet_mode
proxy_dns
tcp_read_time_out 15000
tcp_connect_time_out 8000
[ProxyList]
socks5  127.0.0.1       23649

The last line is the most important one. Change 23649 to whatever port you'll use in the SSH proxy step; it's arbitrary, except that it should probably be in the range 1025-65534, inclusive. (23649 = b-e-n-i-z on a touchtone keypad)

Editing Postfix

Postfix SMTP mail is sent via the /usr/lib/postfix/smtp program. So, I created a wrapper for that program that would invoke ProxyChains if the SSH proxy is open. It's written in Perl, and uses the 'lsof' utility. First, I moved the original 'smtp' to 'smtp.orig'.

#!/usr/bin/perl
use warnings;
use strict;
my @cmd = ($0.'.orig', @ARGV);
# test to see that the proxy is running
my $closed = system 'lsof -i :23649 >/dev/null 2>/dev/null';
my @preload;
push @preload, 'libproxychains.so' if !$closed;
$ENV{LD_PRELOAD} = join ':', @preload if @preload;
exec { $cmd[0] } 'smtp', @cmd[1..$#cmd];

Running SSH

Now, whenever I want Postfix to use the proxy, I log in to a remote host with the '-D' flag:

ssh -o KeepAlive=yes -o ServerAliveInternal=30 -D 23649 remote.example.com