My current network setup looks somewhat like this:
________ \ / ________ __________ | | / \ | | _________| |___| ADSL- |____\ Internet /____| root | LAN | firewall | | router | / \ | server | |__________| |________| \ / |________| ^ / \ ^ :..............................................: OpenVPN tunnel
My local Internet connection (left-hand side) does not have a fixed IPv4 address, so I used to send outgoing e-mails through my mail-hosting provider, who unfortunately went south last month.
The root-server on the right-hand side, which hosts some virtual machines, has a fixed, global IPv4 address, and since I control the DNS zone file, I decided to have it handle outgoing as well as incoming e-mail traffic.
The easy part was to route incoming traffic to those VMs using iptables on the root-server:
# iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 25 -j DNAT --to-destination "IP of Postfix VM" # iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 80 -j DNAT --to-destination "IP of Apache VM" # iptables -t nat -A POSTROUTING -o eth0 -j SNAT --to-source "global IP of root-server"
Now, routing outgoing e-mail traffic from my LAN through the root-server without passing all traffic through the VPN tunnel was a bit more tricky.
First, declare a new routing table for iproute2 on the firewall; let's call it "smtp" and assign it the (arbitrary) number 25:
# echo "25 smtp" >> /etc/iproute2/rt_tables
Next, when the VPN tunnel comes up, add a default route using the new table smtp and force marked packets through that route:
# ip route add default via "root-server IP on VPN" table smtp # ip rule add fwmark 0x01 lookup smtp
(the above two commands could be placed in the OpenVPN "up" script).
Finally, mark outgoing SMTP packets using iptables on the firewall:
# iptables -t mangle -A OUTPUT -p tcp --dport 25 -j MARK --set-mark 0x01
Et voilà - SMTP packets originating on the firewall (which queues outgoing e-mails using Postfix) are routed through the VPN tunnel and exit from the root-server (using its global IP address).