multihome setup in Linux

July 15, 2008

linux

This is an older article that I’ve brought back to live This was original written at the time of Linux 2.6.0

So be ware!

update

As it turns out, the script below never did work correctly (see the bottom of this page for an updated version). The reason it did work for me was that sshn INET_2 never blocked outgoing port 25…until October the 8th. This was at the same time I was experimenting with linux2.6 (go figure). When sshn started to block port 25 outgoing, the script broke. For telnet session to port 25 it worked correctly, but actual sending of email was already done from a high port. This was always (incorrectly) routed through INET_2.

See below (“stopped working”) for an updated (working) script.

network layout

                                                       ________    
                                           +------------+        /
                                           | INET_1     |       |
                             +-------------+ Chello     +-------
         __                  |             | 10Mb/cable |     /
     ___/  \_         +------+-------+     +------------+    |
   _/        \__      |    eth0      |                      /
  /             \ eth3|              |                      |
 | Local network -----+ Linux router |                      |     Internet   
  \_ 192.168/16__/    |              |                      |
    \__     __/       |    eth2      |                      \
       \___/     eth1 +------+-------+     +------------+    |
      ___             |      |             | INET_2     |     \
   __/   \___         |      +-------------+ SSHN       +-------
  /          \        |                    | 100Mb/fiber|       |
 |   WaveLan  \       |                    +------------+        \________   
  \_172.16/16  -------+
    \__      _/
       \____/

 Based upon: http://lartc.org/howto/lartc.rpdb.multiple-links.html

My server is located in the LAN (192.16816) and does mail (port 25), cvs (port 2401) and www (port 80). These ports are redirected from interface eth2 to the local address of the server: 192.168.1.2.

The firewall runs the external DNS and the ntp time protocol.

The main problem here is that the on INET_2 I cannot use port 25 ‘cause it is filtered by the provider. Thus all my email must be routed via INET_1. It is forwarded from INET_1:25 to 192.168.1.2:25.

first try Is was very helpful to look at: Routing for multiple uplinks/providers but this howto stops where is gets interesting: using DNAT and SNAT and multiple routes to the internet.

The biggest problem for me was that I couldn’t get email to be routed back correctly. I’ve had the following lines in my firewall scripts:

# mark mail packets
iptables -A PREROUTING -t mangle -p tcp --dport 25 -s 192.168.1.2 -j MARK --set-mark 2
iptables -A FORWARD -t mangle -p tcp --dport 25 -s 192.168.1.2 -j MARK --set-mark 2
iptables -A INPUT -t mangle -p tcp --dport 25 -s 192.168.1.2  -j MARK --set-mark 2
# REDIRECT mail seperate
iptables -A PREROUTING -t nat -p tcp -i ${INET} --dport 25 -j DNAT --to 192.168.1.2:25

And then used, ip rule add fwmark 2 pref 10 table mail.out to get the mail out on the correct interface.

BUT THIS DIDN’T WORK!

I saw packets coming to my server but they were not routed back correctly.

solution My mistake was that I was marking packets with destination port 25 (the --dport 25 part in the rules above). But due to the fact that packets ogoing to port 25 where already DNATed, the destination port was altered. In stead of marking packets going to port 25 I should have marked packets coming from port 25 (--sport 25). So the rules now look like this:

# mark mail packets
iptables -A PREROUTING -t mangle -p tcp --sport 25 -s 192.168.1.2 -j MARK --set-mark 2
iptables -A FORWARD -t mangle -p tcp --sport 25 -s 192.168.1.2 -j MARK --set-mark 2
iptables -A INPUT -t mangle -p tcp --sport 25 -s 192.168.1.2  -j MARK --set-mark 2
# REDIRECT mail separate
iptables -A PREROUTING -t nat -p tcp -i ${INET} --dport 25 -j DNAT --to 192.168.1.2:25

Again routing on the mark with ip rule add fwmark 2 pref 10 table mail.out gives the desired result. My email is routed over the correct interface. Of course the MX records for my domains only list INET_1.

stopped working Wow for some reason it all stopped working. Just when I upgraded everything to linux 2.6.0, although I don’t think that has something to with it. My sendmail daemon DOES NOT send mail from port 25 any more, it now uses a high port. This totally garbles up my scripts as that was the assumption. Stay tuned as I post my updated script.

As stated in the beginning this has nothing to do with linux 2.6.0, but everything with my provider blocking port 25 outgoing was well. Sigh

new solution I had to change the firewall script to look at the destination port. If it was 25 and the packet was coming from my mail server (192.168.1.2) it should be routed over the cable connection. However as I’m also relaying for people who have the same fiber provider (and thus also a blocked port 25) the script is a bit more complicated. I share a internal network with those guys. Within this network we can send mail to port 25. So for these guys the email should be routed over the fiber connection instead over the cable connection.

So the script needs to do this:

  • dnat incoming mail requests to my server
  • route all outgoing email to the cable wire
  • route all outgoing other traffic to the fiber connection
  • make an exception for internally relayed email (3 hosts at the moment)

the script It now looks little this: (I’ve garbled the IP addresses a bit, comments in the code)

# let these guys jump to the ACCEPT rule, thereby NOT marking the packets
# and get them routed via the fiber connection

RELAY="IP1 IP2 IP3"
for i in $RELAY; do

${iptab} -A PREROUTING -t mangle -p tcp --dport 25 -s 192.168.1.2 -d ${i} -j ACCEPT
${iptab} -A FORWARD -t mangle -p tcp --dport 25 -s 192.168.1.2 -d ${i} -j ACCEPT
${iptab} -A INPUT -t mangle -p tcp --dport 25 -s 192.168.1.2 -d ${i} -j ACCEPT
done

## END RELAY ##

# this is the stuff at the looks the dest. port and gives it a mark

# still alive, rule wise?
${iptab} -A PREROUTING -t mangle -p tcp --dport 25 -s 192.168.1.2 -j MARK --set-mark 2
${iptab} -A FORWARD -t mangle -p tcp --dport 25 -s 192.168.1.2 -j MARK --set-mark 2
${iptab} -A INPUT -t mangle -p tcp --dport 25 -s 192.168.1.2  -j MARK --set-mark 2
# mark secure pop3 packets
${iptab} -A PREROUTING -t mangle -p tcp --dport 995 -s 192.168.1.2 -j MARK --set-mark 2
${iptab} -A FORWARD -t mangle -p tcp --dport 995 -s 192.168.1.2 -j MARK --set-mark 2
${iptab} -A INPUT -t mangle -p tcp --dport 995 -s 192.168.1.2  -j MARK --set-mark 2

# also look at the source port, other wise no server can connect to port 25
# to deliver email

# still alive, rule wise?
${iptab} -A PREROUTING -t mangle -p tcp --sport 25 -s 192.168.1.2 -j MARK --set-mark 2
${iptab} -A FORWARD -t mangle -p tcp --sport 25 -s 192.168.1.2 -j MARK --set-mark 2
${iptab} -A INPUT -t mangle -p tcp --sport 25 -s 192.168.1.2  -j MARK --set-mark 2
# mark secure pop3 packets
${iptab} -A PREROUTING -t mangle -p tcp --sport 995 -s 192.168.1.2 -j MARK --set-mark 2
${iptab} -A FORWARD -t mangle -p tcp --sport 995 -s 192.168.1.2 -j MARK --set-mark 2
${iptab} -A INPUT -t mangle -p tcp --sport 995 -s 192.168.1.2  -j MARK --set-mark 2

# DNAT to the mail server
# REDIRECT mail seperate
${iptab} -A PREROUTING -t nat -p tcp -i ${INET} --dport 25 -j DNAT --to 192.168.1.2:25
# pop3ssl
${iptab} -A PREROUTING -t nat -p tcp -i ${INET} --dport 995 -j DNAT --to 192.168.1.2:995

I have this script running right now and it performs wonderful.

None