Hi all
I've had a quite a headache with NAT and vservers on my home server/firewall. And as far as I can read on vserver mailling list, a lot of other people have had the same problem. So now when I cracked the nut, I decided to make this little howto.





HOWTO deal with NAT'ing firewalls and source-based routing with vservers

Some *challenges* with source-based routing, MASQUERADE and SNAT: SNAT and MASQUERADE are supposingly doing NAT the same way, except that MASQUERADE purges any connection, when the link of the '-o' interface goes down. However its *NOT* the case.

Consider the following setup:

  +----------------------------------+
  | Some gateway at my ISP:          |
  +-----------------+----------------+
                    |
                    |
  +-----------------+----------------+
  | Homeserver and firewall:         |     +----------+
  | eth0:           dhcp (public ip) |  +--+ vserver1 |
  | dummy0:         192.168.2.1/24   |  |  +----------+
  | dummy0:vserver1 192.168.2.2/24  -+--+
  | dummy0:vserver2 192.168.2.3/24  -+--+
  | eth1:           192.168.1.1/24   |  |  +----------+
  | default gateway is the dhcp addr |  +--+ vserver2 |
  +-----------------+----------------+     +----------+
                    |
                    |
  +-----------------+----------------+
  | Workstation:                     |
  | eth0:            192.168.1.20/24 |
  | default gateway: 192.168.1.1     |
  +----------------------------------+

( I love ASCII drawings; Visio eat your heart out! ;) )

I'm doing source-based routing with iproute2:
    # echo "100     vserver" >> /etc/iproute2/rt_tables
    # ip rule add from 192.168.2.0/24 table vserver
    # ip route add default dev eth0 table vserver
    # ip route add 192.168.1.0/24 dev eth1 table vserver

I'm using MASQUERADE with iptables:
    # iptables -A POSTROUTING -o eth0 -j MASQUERADE

From vserver1 & vserver2:
 * I can ping 192.168.2.1
 * I can ping the other vserver
 * I can ping 192.168.1.1
 * I can ping 192.168.1.20
 * I can ping the dhcp address of eth0 on my homeserver.

But I can *NOT* ping any addresse outside eth0

Packets originating from vservers *should* exit through eth0 and thus get masqueraded as the public dhcp address? But in fact they aren't; they still have their original ip address when hitting any address outside eth0.

But if I use SNAT instead of MASQUERADE:
# iptables -t nat -A POSTROUTING -o eth0 -j SNAT --to-source <dhcp given address>

Then the source address of the packets are translated as it should!

So forget about MASQUERADE. But now I hear you cry: "But then I have to change the SNAT rule every time eth0 changes address!". No I fixed that:

* Install ISC DHCP Client 3.x (on debian do: # apt-get install dhcp3-client). * Download the tarball, http://wheezy.homelinux.net/cgi-bin/viewcvs.cgi/dhclient-scripts.tar.gz?view=tar, and install it (instructions are in the scripts).

Basically this packages provides a small perl script, which is called by the DHCP client, and it is setting a SNAT rule according to the IP address that the DHCP client got. It also removes the rule, if the interface is shutdown, and it updates the rule, if the interface changes address.

If you don't want to use ISC DHCP Client 3.x but for instance ISC DHCP Client 2.x, then you have to find a way to have the dhcp client call snatman.pl with the correct parameters.



Configuring the source-based routing automatically on debian.

Add the entry to /etc/network/interfaces:
auto dummy0
iface dummy0 inet static
address 192.168.2.1
netmask 255.255.255.255

Make a script /etc/network/if-up.d/vserver containing:
#!/bin/sh

if [ "$IFACE" = "dummy0" ]; then
    if ! egrep --quiet \
               --word-regexp \
               vserver /etc/iproute2/rt_tables; then
        echo "You haven't created a vserver table \
in /etc/iproute2/rt_tables"
        echo "Try adding a line like '100     vserver' \
to /etc/iproute2/rt_tables"
        exit 1
    fi
    if [ "${MODE}" = "start" ]; then
        ip rule add from 192.168.2.0/24 table vserver
        ip route add default dev eth0 table vserver
        ip route add 192.168.1.0/24 dev eth1 table vserver
    fi
fi

and make /etc/network/if-up.d/vserver executable:
# chmod 0755 /etc/network/if-up.d/vserver

Also make the script /etc/network/if-down.d/vserver:
#!/bin/sh

if [ "$IFACE" = "dummy0" ]; then
    if ! egrep --quiet \
               --word-regexp \
               vserver /etc/iproute2/rt_tables; then
        echo "You haven't created a vserver table \
in /etc/iproute2/rt_tables"
        echo "Try adding a line like '100     vserver' \
to /etc/iproute2/rt_tables"
        exit 1
    fi
    if [ "${MODE}" = "stop" ]; then
        ip route del default dev eth0  scope link table vserver
        ip route del 192.168.1.0/24 dev eth1  scope link table vserver
        ip rule del from 192.168.2.0/24 lookup vserver
    fi
fi

and make it executable too:
# chmod 0755 /etc/network/if-down.d/vserver


Thats it.

--
--- Mfg. Regards, Mvh.
Valdemar Lemche

127 Brännestadsvägen
297 93 Huaröd
Sweden
Phone: +46 44330423
ICQ#:  28884381
Email: [EMAIL PROTECTED]

"Intuitive Software can easily be learned.
You just have to work at it for a long time."
- Ponder Stibbons, Unseen University
_______________________________________________
Vserver mailing list
[email protected]
http://list.linux-vserver.org/mailman/listinfo/vserver

Reply via email to