Difference between revisions of "Building Scalable TFTP Cluster using LVS"

From LVSKB
Jump to: navigation, search
 
(Introduction)
Line 1: Line 1:
 
== Introduction ==
 
== Introduction ==
  
 +
TFTP is a bit tricky because of how the protocol works.  The client sends Ack's to the same port from which the data came from the server.  This is problematic with a port based  LVS setup because the client ends up sending packets to the VIP on a port that it is not expecting packets.  The answer to this is to use firewall marks.
 +
 +
TFTP Protocol:
 +
# Client:12345 -> LVS: 69  (Request File)
 +
# LVS:23456 -> Client: 12345 (Data)
 +
# Client:12345 -> LVS: 23456 (Ack)
 +
 +
And this is where the problem is, with a port based config, the LVS router doesn't know to listen on some random high port so the packet is dropped.  The Real Server is listening on that port, but the client doesn't know anything about the real server.
 +
 +
This is where firewall marks come in to play, set up iptables rules on the lvs servers that mark all of your TFTP packets.  Since TFTP uses any unprivileged port it's kind of like the carpet bombing of port selection.  And this will limit you to making TFTP the only UDP service that uses unprivileged ports for that particular Virtural Service IP.
 +
 +
iptables -t mangle -A PREROUTING -i eth0 -p udp -s 0.0.0.0/0 -d <VIRTUAL IP> --dport 69 -j MARK --set-mark 1
 +
iptables -t mangle -A PREROUTING -i eth0 -p udp -s 0.0.0.0/0 -d <VIRTUAL IP> --dport 1024:65535 -j MARK --set-mark 1
 +
 +
You will want to put those in an init script, or rc.local that runs on both of your LVS Directors.
 +
 +
Then in the lvs.cf it's super simple, instead of the port option you use the fwmark option.  I left the port option for fun, but I think it's ignored.
 +
 +
virtual tftp {
 +
    active = 1
 +
    address = <VIRTUAL IP> eth0:1
 +
    vip_nmask = 255.255.255.0
 +
    fwmark = 1
 +
    port = 69
 +
    persistent = 45
 +
    expect = "OK - answer from server"
 +
    use_regex = 0
 +
    send_program = "/usr/local/bin/check_tftp --connect %h"
 +
    load_monitor = none
 +
    scheduler = wlc
 +
    protocol = udp
 +
    timeout = 6
 +
    reentry = 15
 +
    quiesce_server = 1
 +
    server ftp1 {
 +
        address = 10.0.0.2
 +
        active = 1
 +
        weight = 1
 +
    }
 +
    server ftp2 {
 +
        address = 10.0.0.3
 +
        active = 1
 +
        weight = 1
 +
    }
 +
}
 +
 +
You can get the check_tftp script from the nagios plugins.
  
 
== Architecture ==
 
== Architecture ==

Revision as of 16:22, 8 June 2007

Introduction

TFTP is a bit tricky because of how the protocol works. The client sends Ack's to the same port from which the data came from the server. This is problematic with a port based LVS setup because the client ends up sending packets to the VIP on a port that it is not expecting packets. The answer to this is to use firewall marks.

TFTP Protocol:

  1. Client:12345 -> LVS: 69 (Request File)
  2. LVS:23456 -> Client: 12345 (Data)
  3. Client:12345 -> LVS: 23456 (Ack)

And this is where the problem is, with a port based config, the LVS router doesn't know to listen on some random high port so the packet is dropped. The Real Server is listening on that port, but the client doesn't know anything about the real server.

This is where firewall marks come in to play, set up iptables rules on the lvs servers that mark all of your TFTP packets. Since TFTP uses any unprivileged port it's kind of like the carpet bombing of port selection. And this will limit you to making TFTP the only UDP service that uses unprivileged ports for that particular Virtural Service IP.

iptables -t mangle -A PREROUTING -i eth0 -p udp -s 0.0.0.0/0 -d <VIRTUAL IP> --dport 69 -j MARK --set-mark 1
iptables -t mangle -A PREROUTING -i eth0 -p udp -s 0.0.0.0/0 -d <VIRTUAL IP> --dport 1024:65535 -j MARK --set-mark 1

You will want to put those in an init script, or rc.local that runs on both of your LVS Directors.

Then in the lvs.cf it's super simple, instead of the port option you use the fwmark option. I left the port option for fun, but I think it's ignored.

virtual tftp {
    active = 1
    address = <VIRTUAL IP> eth0:1
    vip_nmask = 255.255.255.0
    fwmark = 1
    port = 69
    persistent = 45
    expect = "OK - answer from server"
    use_regex = 0
    send_program = "/usr/local/bin/check_tftp --connect %h"
    load_monitor = none
    scheduler = wlc
    protocol = udp
    timeout = 6
    reentry = 15
    quiesce_server = 1
    server ftp1 {
        address = 10.0.0.2
        active = 1
        weight = 1
    }
    server ftp2 {
        address = 10.0.0.3
        active = 1
        weight = 1
    }

}

You can get the check_tftp script from the nagios plugins.

Architecture

Configuration Example

Conclusion

LVS.png "Building Scalable TFTP Cluster using LVS" is an LVS Example related stub. You can help LVSKB by expanding it