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.
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/homepage | Version |
---|---|
Postfix | 2.5.5 |
ProxyChains | 3.1 |
OpenSSH | 5.1_p1-r1 |
Perl | 5.10.0-r1 |
Lsof | 4.78-r2 |
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.
#!/bin/sh echo "ProxyChains-3.1 (http://proxychains.sf.net)" if [ $# = 0 ] ; then echo " usage:" [...etc...]
#!/bin/sh if [ $# = 0 ] ; then echo "ProxyChains-3.1 (http://proxychains.sf.net)" echo " usage:" [...etc...]
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)
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];
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