Incoming SMTP on a budget AKA Keep on rollin'
Sometimes you need to run a service on your home computer(s), but due to previous patterns of abuse by other customers, your broadband provider blocks certain inbound services. I totally understand that need. Normally you have the option to use a non-privileged and non-standard port, and as long as you don't serve up too much traffic the ISP won't try to convert you to a business account.
The broadband provider that I have at home blocks a bunch of different ports, including Port 25, which is what I needed to run a SMTP server at home. For a normal user, this would be silly, but I still need to receive mail on an old sub-domain that I have assigned to me, but I do not control the primary domain or the MX servers for it.
I had access to a friend's business class service that had a spare static IP, which allowed me do a few experiments. There are several pieces of software for Windows that will do port translation, but none that are free, and if I was willing to spend the money in the first place, I would have sprung for business class service at home that had static IP addresses and unblocked ports.
It is more fun to tinker and try to come up solutions, even if you expend more time and effort.
I tried a few different cobbled together a few Linux solutions that worked to some extent.
The first was an experiment using Netcat. Basically, using Netcat you can create (as root) two different Netcat processes connected via a pipe. One Netcat listens to the default interface on Port 25. The other Netcat creates a connection to the server at home on a different port. The nice thing about this solution is that it is pretty simple and also works for http and a few other protocols. Netcat will resolve a DNS name for the output, so if you were to use a dynamic DNS service you could have a flexible solution. The things that is terrible is that you have to run it as root and after a period of time (at the end of the connection on the incoming, or a time out on the outgoing), Netcat dies and you have to respawn the process. The other awful thing is that this uses an incredible amount of CPU time.
I came up with another solution that was a bit better since it was in user space. I sat a Linux machine behind a junk pile firewall and did the simple NAT to take the public IP address and port 25 and map it to the Linux machine sitting in an RFC 1918 address range on a non-privileged port. This allowed me to use ssh tunnels to accept traffic on that Linux machine and send it to the mail server directly over the ssh link. The performance on this was somewhat spotty, but it performed ok. The advantage of this is that you can connect to a Dynamic DNS host for the ssh tunnel and automate the logins if you use session keys.
That was still a bit clunky, so Googled a bit on iptables. Most examples I would find on the web used port forwarding to do what I wanted to do, but by using a NAT table to map it from a public to private ip space. What I was looking to do was basically to take traffic on an untrusted interface and shoot it back out that same untrusted interface on a different TCP port so it could hit my home server. I had used the open source version of Smoothwall in the past at home and knew that used iptables, so I downloaded an ISO and spun up a system on the Public IP address that was available to me. Bingo. Using the port forwarding rules allow you to take inbound traffic on your red interface and forward it back out that same interface. Most other firewalls of that grade (i.e. free or open source) limit your port forwarding to an address behind your trusted interface of on a RFC 1918 address that you are NATting to. The beauty of this solution is that it is completely transparent and is only limited by the bandwidth constraints of the network that feeds your public ip address. The downside is that it only works properly with a fixed ip address. You could write a script to do an nslookup of the A record attached to your dynamic DNS and then write that into a script that would program your iptables configuration. In the end it would take a bit more work to make things work smoothly.
While that was a fun experiment, the best free solution I found was to use a mail redirection service from a company called Rollernet. They accept mail for you on their mail SMTP server, run the mail against a list of domains that you own, run it through a SPAM filter, check against a valid recipient list, and finally send it off to a valid server and port combination that you own. Right now they give you 10Mb of free mail transfer a day, and give you the option to defer mail that is beyond that cap until the next day. You can't beat the price, as long as you are able to give up a little bit of control. In my case that was an acceptable risk to be able to keep a mail domain that has long gone dormant, but still gets valid emails from time to time.
A quick and dirty mail relay using netcat on Linux is below:
# echo "hit [CTRL+C] to stop!"
mknod mailpipe p
# Viewable Output, Launch with 'nohup ./mailrelay.sh > /dev/null 2>&1 &'
nc -l local_interface_ip -p 25 0<mailpipe | nc remote_ip_or_dnsname remote_port | tee mailpipe