LVS
lvs-users
Google
 
Web LinuxVirtualServer.org

Setting up a one network VS-NAT LVS

To: lvs-users@xxxxxxxxxxxxxxxxxxxxxx
Subject: Setting up a one network VS-NAT LVS
From: Joseph Mack <mack@xxxxxxxxxxx>
Date: Thu, 18 Jan 2001 15:41:06 -0500 (EST)
From the next version of the HOWTO. Comments gladly accepted.

Joe

7.1.2 One network VS-NAT

The disadvantage of the 2 network VS-NAT is that the real-servers
are not able to connect to machines in the network of the VIP.
You couldn't make a VS-NAT setup out of machines already on
your LAN, which were also required for other purposes to stay
on the LAN network.

Here's a 1 network VS-NAT LVS.
                        ________
                       |        |
                       | client |
                       |________|
                       CIP=192.168.1.254
                           |
                        (router)
                           |
             __________    |
            |          |   |   VIP=192.168.1.110 (eth0:110)
            | director |---|   DIP=192.168.1.1 (eth0)
            |__________|   |   DIIP=192.168.1.9 (eth0:9)
                           |
                           |
          ------------------------------------
          |                |                 |
          |                |                 |
   RIP1=192.168.1.2   RIP2=192.168.1.3  RIP3=10.1.1.4 (all eth0)
    _____________      _____________     _____________
   |             |    |             |   |             |
   | real-server |    | real-server |   | real-server |
   |_____________|    |_____________|   |_____________|

The problem:

A return packet from the real-server (with address RIP->CIP) 
will be sent to the real-server's default gw (the director).
ICMP redirects will be sent from the director telling the 
real-server of the better route directly to the client. 
The real-server will then send the packet directly to the 
client and it  will not be demasqueraded by the director.
The client will get a reply from the RIP rather than the VIP
and the connection will hang. 

The cure:

In the previous HOWTO I said that initial attempts to handle this 
by turning off redirects had not worked. The problem appears now 
to be solved.

Thanks to michael_e_brown@xxxxxxxx and Julian ja@xxxxxx
for sorting this out.

To get a VS-NAT LVS to work on one network -  

1. On the director, turn off icmp redirects

director:/etc/lvs# echo 0 > /proc/sys/net/ipv4/conf/all/send_redirects
director:/etc/lvs# echo 0 > /proc/sys/net/ipv4/conf/default/send_redirects
director:/etc/lvs# echo 0 > /proc/sys/net/ipv4/conf/eth0/send_redirects

(Note: eth0 may be eth1 etc, on your machine).

2. Make the director the default and only route for outgoing packets.

You will probably have set the routing on the real-server up like this

realserver:/etc/lvs# netstat -r
Kernel IP routing table
Destination     Gateway         Genmask         Flags   MSS Window  irtt Iface
192.168.1.0     0.0.0.0         255.255.255.0   U         0 0          0 eth0
127.0.0.0       0.0.0.0         255.0.0.0       U         0 0          0 lo
0.0.0.0         director        0.0.0.0         UG        0 0          0 eth0

Note the route to 192.168.1.0/24. This allows the real-server to send packets 
to the client by just putting them out on eth0, where the client will
pick them up directly (without being demasqueraded) and the LVS will
not work.

Remove the route to 192.168.1.0/24. 

realserver:/etc/lvs#route del -net 192.168.1.0 netmask 255.255.255.0 dev eth0

This will leave you with

realserver:/etc/lvs# netstat -r
Kernel IP routing table
Destination     Gateway         Genmask         Flags   MSS Window  irtt Iface
127.0.0.0       0.0.0.0         255.0.0.0       U         0 0          0 lo
0.0.0.0         director        0.0.0.0         UG        0 0          0 eth0

The VS-NAT LVS now works. If LVS is forwarding telnet, you can 
telnet from the client to the VIP and connect to the real-server. 

You can ping from the client to the real-server.

You can also connect _directly_ to services on the real-server not
being forwarded by LVS (in this case e.g. ftp).

You can no longer connect directly to the real-server for services
being forwarded by the LVS. Here telnet ports are not being rewritten
by the LVS (ie telnet->telnet). 

client:~# telnet realserver
Trying 192.168.1.11...
^C

(i.e. connection hangs)

Here's tcpdump on the director (which can see all packets).
The client initiates telnet. `netstat -a` on the client 
shows a SYN_SENT from port 4121.

director:/etc/lvs# tcpdump
tcpdump: listening on eth0
16:37:04.655036 realserver.telnet > client.4121: S 354934654:354934654(0) ack 
1183118745 win 32120 <mss 1460,sackOK,timestamp 111425176[|tcp]> (DF)
16:37:04.655284 director > realserver: icmp: client tcp port 4 121 unreachable 
[tos 0xc0]

(repeats every second until I kill telnet on client)

I don't know why I don't see the connect request from client->real-server.
The first packet I see is the ack from the real-server, 
which will be forwarded via the director.
The director will rewrite the ack to be from the director.
The client will not accept an ack to port 4121 from director:telnet.

Various debugging techniques (in discussion with Julian) in
case you want to know more:

The routes added with the route command go into the kernel FIB 
(Forwarding information base) route table. The contents are
displayed with the route (or netstat -a) command.

Following an icmp redirect, the route updates go into the kernel's
route cache (route -C). 

Here's the route cache on the real-server before any packets are sent.
(You can flush the route cache with 

        echo 1 > /proc/sys/net/ipv4/route/flush
or
        ip route flush cache
)

realserver:/etc/rc.d# route -C
Kernel IP routing cache
Source          Destination     Gateway         Flags Metric Ref    Use Iface
realserver      director        director              0      1        0 eth0
director        realserver      realserver      il    0      0        9 lo

With icmp redirects enabled on the director, repeatedly running 
traceroute to the client shows the routes changing from 2 hops to 1 hop.

realserver:/etc/rc.d# traceroute client
traceroute to client (192.168.1.254), 30 hops max, 40 byte packets
 1  director (192.168.1.9)  0.932 ms  0.562 ms  0.503 ms
 2  client (192.168.1.254)  1.174 ms  0.597 ms  0.571 ms
realserver:/etc/rc.d# traceroute client
traceroute to client (192.168.1.254), 30 hops max, 40 byte packets
 1  director (192.168.1.9)  0.72 ms  0.581 ms  0.532 ms
 2  client (192.168.1.254)  0.845 ms  0.559 ms  0.5 ms
realserver:/etc/rc.d# traceroute client
traceroute to client (192.168.1.254), 30 hops max, 40 byte packets
 1  client (192.168.1.254)  0.69 ms *  0.579 ms
 
Although the route command shows no change in the FIB, the route cache
has changed. (The new route of interest is bracketted by >< signs.) 

realserver:/etc/rc.d# route -C
Kernel IP routing cache
Source          Destination     Gateway         Flags Metric Ref    Use Iface
client          realserver      realserver      l     0      0        8 lo
realserver      realserver      realserver      l     0      0     1038 lo
realserver      director        director              0      1      138 eth0
>realserver      client          client                0      0        6 eth0<
director        realserver      realserver      l     0      0        9 lo
director        realserver      realserver      l     0      0      168 lo

Packets to the client now go directly to the client instead of via
the director.

It takes about 10mins for the client's route cache to expire 
(experimental result). The timeouts may be in /proc/sys/net/ipv4/route/gc_*, 
but their location and values are well encrypted in the sources :).
Here's the route cache after 10mins.

realserver:/etc/rc.d# route -C
Kernel IP routing cache
Source          Destination     Gateway         Flags Metric Ref    Use Iface
realserver      realserver      realserver      l     0      0     1049 lo
realserver      director        director              0      1      139 eth0
director        realserver      realserver      l     0      0        0 lo
director        realserver      realserver      l     0      0      236 lo

There are no routes to the client anymore. Checking with traceroute, 
shows that 2 hops are initially required to get to the client (i.e.
the routing cache has reverted to using the director as the route
to the client). After 2 iterations, icmp redirects route the packets
directly to the client again.

realserver:/etc/rc.d# traceroute client
traceroute to client (192.168.1.254), 30 hops max, 40 byte packets
 1  director (192.168.1.9)  0.908 ms  0.572 ms  0.537 ms
 2  client (192.168.1.254)  1.179 ms  0.6 ms  0.577 ms
realserver:/etc/rc.d# traceroute client
traceroute to client (192.168.1.254), 30 hops max, 40 byte packets
 1  director (192.168.1.9)  0.695 ms  0.552 ms  0.492 ms
 2  client (192.168.1.254)  0.804 ms  0.55 ms  0.502 ms
realserver:/etc/rc.d# traceroute client
traceroute to client (192.168.1.254), 30 hops max, 40 byte packets
 1  client (192.168.1.254)  0.686 ms  0.533 ms *

If you now turn off icmp redirects on the director.

director:/etc/lvs# echo 0 > /proc/sys/net/ipv4/conf/all/send_redirects
director:/etc/lvs# echo 0 > /proc/sys/net/ipv4/conf/default/send_redirects
director:/etc/lvs# echo 0 > /proc/sys/net/ipv4/conf/eth0/send_redirects

Checking routes on the real-server -

realserver:/etc/lvs# netstat -rn
Kernel IP routing table
Destination     Gateway         Genmask         Flags   MSS Window  irtt Iface
127.0.0.0       0.0.0.0         255.0.0.0       U         0 0          0 lo
0.0.0.0         director        0.0.0.0         UG        0 0          0 eth0

nothing changed here.

Flush the kernel routing table and show the kernel routing table -

realserver:/etc/lvs# ip route flush cache
realserver:/etc/lvs# route -C
Kernel IP routing cache
Source          Destination     Gateway         Flags Metric Ref    Use Iface
realserver      director        director              0      1        0 eth0
director        realserver      realserver      l     0      0        1 lo

There are no routes to the client.

Now when you send packet to the client, the route stays via the director
needing 2 hops to get to the client. There are no one hop packets
to the client.

realserver:/etc/rc.d# traceroute client
traceroute to client (192.168.1.254), 30 hops max, 40 byte packets
 1  director (192.168.1.9)  0.951 ms  0.56 ms  0.491 ms
 2  client (192.168.1.254)  0.76 ms  0.599 ms  0.574 ms
realserver:/etc/rc.d# traceroute client
traceroute to client (192.168.1.254), 30 hops max, 40 byte packets
 1  director (192.168.1.9)  0.696 ms  0.562 ms  0.583 ms
 2  client (192.168.1.254)  0.62 ms  0.603 ms  0.576 ms
realserver:/etc/rc.d# traceroute client
traceroute to client (192.168.1.254), 30 hops max, 40 byte packets
 1  director (192.168.1.9)  0.692 ms *  0.599 ms
 2  client (192.168.1.254)  0.667 ms  0.603 ms  0.579 ms
realserver:/etc/rc.d# traceroute client
traceroute to client (192.168.1.254), 30 hops max, 40 byte packets
 1  director (192.168.1.9)  0.689 ms  0.558 ms  0.487 ms
 2  client (192.168.1.254)  0.61 ms  0.63 ms  0.567 ms
realserver:/etc/rc.d# traceroute client
traceroute to client (192.168.1.254), 30 hops max, 40 byte packets
 1  director (192.168.1.9)  0.705 ms  0.563 ms  0.526 ms
 2  client (192.168.1.254)  0.611 ms  0.595 ms *
realserver:/etc/rc.d# traceroute client
traceroute to client (192.168.1.254), 30 hops max, 40 byte packets
 1  director (192.168.1.9)  0.706 ms  0.558 ms  0.535 ms
 2  client (192.168.1.254)  0.614 ms  0.593 ms  0.573 ms

The kernel route cache 

realserver:/etc/rc.d# route -C
Kernel IP routing cache
Source          Destination     Gateway         Flags Metric Ref    Use Iface
client          realserver      realserver      l     0      0       17 lo
realserver      realserver      realserver      l     0      0        2 lo
realserver      director        director              0      1        0 eth0
>realserver      client          director              0      0       35 eth0<
director        realserver      realserver      l     0      0       16 lo
director        realserver      realserver      l     0      0       63 lo

shows the the only route to the client (labelled with >< ) is via the director.

#end

--
Joseph Mack mack@xxxxxxxxxxx



<Prev in Thread] Current Thread [Next in Thread>