Funky routing of mail on non-standard ports

  • Posted on: 28 April 2004
  • By: agittins

For a while now I've been providing a secondary mail service for a friend, using my home server connected to BigPond Cable. It all works rather well, but Telstra have recently announced that they will be blocking outbound port 25 to mitigate the steaming hordes of spam monkeys they've attracted over the years. For one I applaud Telstra's action, albeit years late - at least they're making an effort now. But since it requires some reconfiguration to handle this I figured I'd throw it up here so that others in a similar situation can use this method to continue providing secondary mail services.

The issues

  • Outbound connections to/from(which?) port 25 will be blocked
  • All outbound mail needs to be sent via bigpond's server, using smart hosting
  • Being a secondary MX for a friend means bouncing through telstra is inefficient
  • If someone sends him spam, my mail server forwards it through telstra, so it looks like i'm the spamlord

The solution
This involves some port trickery. Basically, I still want to be able to send mail directly to his machine, so any way I can do that without using port 25 should be fine. Usually this isn't possible, but because I have indirect control of the config at both ends, it can be done.

The remote end
Years ago we used this trick because my friend had inbound port 25 blocked by his isp, so I don't know how he set it up at his end. It is probably as simple as a port forwarding rule in iptables. Try something like this, and if you can telnet localhost 2525 (on his machine) then it's probably working. This line is for adding to the nat table, /etc/sysconfig/iptables on redhat:

-A PREROUTING -d [local-ip-address] -p tcp -m tcp --dport 2525 -j REDIRECT --to-ports 25

I haven't tried that, and I'm not sure if that's exactly what he's got at his end, but it's likely to work. Basically any connections made into the machine for port 2525, get redirected instead to port 25 (still on the local machine) - this assumes you have sendmail or another MTA listening on port 25 - if not you've got more serious problems.

The sending end

The config for the seconday MX, or sending end is a little more complex because you have to tell sendmail itself how to get the mail past the firewall trolls and into the remote machine, while still sending all your other mail via the smart host. Fortunately it's not too hard, as the "mailertable" overrides the smart host directive for matching mail.

First, we define a new mail handler for sendmail. I just threw this at the bottom of my so that it gets dumped into when I rebuild the m4 file (if that made no sense, you should read up on how sendmail configs are built from an mc file, parsed by m4 then dumped out into Oh... looks like I just about explained it anyway. Ok, add this to the end of

Mesmtp2525, P=[IPC], F=mDFMuXa, S=EnvFromSMTP/HdrFromSMTP, R=EnvToSMTP, E=\r\n, L=990,
A=TCP $h 2525

You might have an existing "MAILER DEFINITIONS" area in your file, so put it in there. I had one (as a result of the config changes I made to accomodate Cyrus) so to be honest I don't know if there's some other magic needed in the file that I already had. ymmv.

Once you rebuild your sendmail config and restart sendmail you should have another mailer service available. If you look at your, you will see that there's an entry like the above for Mestmp, the only differences being the name and the port number after the $h ( $h gets expanded to the destination hostname). All we've done is create a new mailer that sends on port 2525 instead of 25. Ie, it's completely useless unless someone is specifically set up to listen to us.

Now that we have the mailer available, we need to tell sendmail when to use it. This is nice and easy. Hopefully you have a mailertable file somewhere in your sendmail configs (/etc/mail on redhat). It's probably empty. Add this line to it: esmtp2525:[]

This of course assumes two things:

  1. Your friend owns the domain (hint - he doesn't, so fix that)
  2. Your friend's mail server is (to find out, use "dig mx" - you should get his and your servers in the reply - again, it's not that you're interested in, ok)?

You'll need to rebuild the mailertable database, and probably restart sendmail. Google for it if you need to find out how. On redhat you can just run "make" in the /etc/mail directory, which is a really nice touch imho.

That's it - things should be working.


From your server, run something like "tcpdump -i [your-external-interface] port 2525", then send an email to your buddy. You should see the packets fly by on the correct (non-iana) ports, and he should get an email with headers proving that the mail indeed came direct from your box to his, without passing your smart relay or waking any port-nazis. Now, spam the little bugger into oblivion, your ISP won't even notice >-)


All fine and nice except i have this exactly and it doesn't go to the alternate port.

Add new comment

Plain text

  • No HTML tags allowed.
  • Web page addresses and e-mail addresses turn into links automatically.
  • Lines and paragraphs break automatically.
I love robots, but not robots that create spam. Thus, I humbly request evidence of your sentience...