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