Gentoo Wiki




  1. LTSP Client
  2. LTSP Server
  3. LTSP Desktop
  4. LTSP Configuration
  5. GNU Modular Network Management System


Existing Server

This system is the one which actually serves all of the LTSP files necessary for the client machines to boot up. This could be an existing file- or dhcp-server. Very likely, you use this machine to authenticate your users, and will need to ensure that PAM is set up on the desktop correctly to do so. If you are doing this in your basement, you'll probably set this up to be your desktop system as well. Administrative issues that you encounter will likely occur here.


The easiest configuration is to set an existing dhcp server to hand out IP addresses to the thin clients along with appropriate paths to boot images, kernels and boot parameters.

Almost as easy is to set up a new dhcp server in a network that does not already have DHCP servers. A complete guide HOWTO setup DHCP explains the details of how to set up a DHCP server on your Gentoo box.

But if, for some reason, you don't have access to the main DHCP server on the network or your DHCP server is a dumb box like a cheap xDSL router box, you need to set up a new DHCP server that does some more or less ugly hacks to serve the thin clients. The text below explains some possible configurations to make the LTSP system work.

The ugliest solution is to set up two conflicting DHCP servers on the network with the default settings. This has some drawbacks - the thin clients most probably will be able to get the pxe/etherboot -image from the network since their first dhcp request is a bit special in a way that the client requires the server to send a bootrom image. But the second request (made by the booting kernel) has to choose between two competing servers.

Usually the dumb DHCP server is authoritative and "wins" most of the requests made by the clients. If it isn't, you can improve the bets of your #2 server by making it authoritative. The drawback here is that all non-thin clients will also receive their addresses from your #2 server if you don't limit the operation to specific MAC addresses. IMHO conflicting servers is definitely not a proper way to do this.

Luckily there are two more elegant solutions to this. First, you can bind your #2 DHCP server to port 1067. The bootrom images from rom-o-matic support alternative DHCP port 1067, but if you're using a stock PXE bootrom, you have to bind a #2 DHCP server also to port 67. Configuration for Etherboot is located in dhcpd.conf, PXE users should append the kernel options to their pxe config file.

Second, you can use the primary DHCP server to offer your clients their IP addresses, but use the #2 server to send out bootrom images and kernel configuration. The special trick is to use nfsroot kernel parameter. The drawback here is that if the primary DHCP server does not provide thin clients with a host name, you're not able to use the localdev support (I think). Still, AFAIK localdev support is not supported on Gentoo ATM. The third option is to use different subnets for different clients, but I haven't had time to test it yet.

More solutions are described here:

You can create a bootrom using alternative DHCP port 1067 by selecting Configure -> [X] ALTERNATE_DHCP_PORTS_1067_1068 from the rom-o-matic web site.

Setting the server to use alternative ports can be done by setting

File: /etc/conf.d/dhcp
 DHCPD_OPTS="-p 1067"

Setting up two separate dhcp servers (ports 67 & 1067) on the same server machine is possible, but you have to create a custom init script for the second server.

Ok, now let's do some configuration. Here's a sample dhcpd.conf to start with:

File: Installing dhcp
# Global defaults
not authoritative;				# only primary servers use authoritative
default-lease-time		28800;		# 8 hours
max-lease-time			86400;		# 1 day
use-host-decl-names		on;		# Push hostname to clients (on/off)
ddns-update-style		none;		# Dynamic DNS update style (off,interim,ad-hoc)
#range;			# Comment this if you have another DHCP server

# Network
option subnet-mask;	# Duh
option broadcast-address;	# Duh
option routers;	# The default gateway
option domain-name-servers;	# Our router / firewall manages DNS
option log-servers;	# The box that accepts remote logging
option nntp-server;	# The Novell box is our time server
next-server;	# Machine server tftp
#option ip-forwarding		off;		# ???

# Boot
boot-unknown-clients		false;		# Prevent random machines
						# from accidently net booting
allow booting;					# Duh
allow bootp;					# Duh

# PXE & legacy options
option option-128		code 128 = string; # required for PXE boot
option option-129		code 129 = text;   # required for PXE boot
option option-128		e4:45:74:68:00:00; # magic value for PXE booting

# Describe workstations
shared-network LTSPCLIENTS {			# Because there is another DHCP server
  option domain-name	"ltsp.domain.tld";	# A fake domain-name for our thin-clients
  option root-path	""; # NFS root path for the kernel

  if substring (option vendor-class-identifier, 0, 9) = "PXEClient" {
    filename "/pxe/pxelinux.0";		        # PXE bootrom
  else if substring (option vendor-class-identifier, 0, 9) = "Etherboot" {
    filename "/lts/vmlinuz-";	# Etherboot kernel

  subnet netmask {
    # dynamic IP range for DHCP clients

    # this range is assigned to both BOOTP and DHCP clients
    range dynamic-bootp;

    group DESKTOP {
      host desktop {
        hardware ethernet	00:C0:4F:AD:5C:BC;
    group LIBRARY {
      # ws with support for alternative DHCP port 1067 (Etherboot)
      host ws100 {
        hardware ethernet	00:C0:4F:AD:5C:BC;
        option option-129	"DPORT=1067";
      # support for DHCP port 1067 & slow 3Com ISA NIC
      host ws101 {
        hardware ethernet	00:60:08:5C:CB:BE;
        option option-129	"DPORT=1067 NIC=3c509 MOPTS=nolock,ro,wsize=2048,rsize=2048";
      # another client with a slow ISA NIC
      host ws102 {
        hardware ethernet	00:C0:4F:AD:5D:55;
        option option-129	"NIC=ne IO=0x300";
    group LAB {
      # trick to use, when there are two conflicting DHCP servers
      # and the dumb one is authoritative
      host ws103 {
        hardware ethernet	00:C0:4F:AD:5D:55;
        option option-129	"nfsroot=";

#shared-network OPENMOSIXSERVERS {
#  option domain-name "cluster.domain.tld";	# domain-name for servers
#  option root-path   "";	# NFS root path for the kernel
#  # Append /tftpboot if your tftpd isn't chrooted
#  filename         "/om/vmlinuz-???-om";
#  subnet netmask {
#    #range dynamic-bootp;
#    host srv13 {
#      hardware ethernet	00:C0:4F:AD:5C:BC;
#      fixed-address;
#    }
#  }


Now you can test your configuration by starting the dhcp server. It's possible that it will fail to start, in which case I find that forgetting to put a ; at the end of each line is the most common problem.

Code: Installing dhcp
 /etc/init.d/dhcp start
 rc-update add dhcp default

Boot up your LTSP client and you should get as far as

Loading ...


You can also use dnsmasq instead of dhcp. Add these lines to the dnsmasq configuration file:

File: /etc/dnsmasq.conf
# root path

(change to the ip address of your ltsp server)

On the ltsp server I did also create this symlink, else PXE couldn't find the configuration file "default":

ln -sf /tftpboot/pxelinux.cfg /tftpboot/pxe


Many sources use xinetd as a superserver to start tftpd. I guess this improves security, when properly set up, but it's not mandatory. It might also save some memory, if you're already running xinetd for other reasons, because xinetd only starts up services upon valid requests. Create /etc/xinetd.d/tftp with the contents below.

Code: /etc/xinetd.d/tftp
service tftp
        disable = no
        socket_type = dgram
        protocol = udp
        wait = yes
        user = root
        server = /usr/sbin/in.tftpd
        server_args = -s /tftpboot

If you want additional security, set xinetd to run tftpd as user 'nobody'. I haven't tested this, but it should work.


tftpd or in.tftpd comes in at least 4 flavors. LTSP Wiki recommends atftp and tftp-hpa. The previous author of this section had some problems with tftp-hpa, but I think those have been fixed now. We'll stick with tftp-hpa for now.

Code: installing tftp-hpa
 emerge tftp-hpa
 rc-update add in.tftpd default   # if you don't plan on using xinet.d
 /etc/init.d/in.tftpd start   # if you don't plan on using xinet.d
Code: /etc/conf.d/in.tftpd
# /etc/conf.d/in.tftpd

# Path to server files from

# For more options, see tftpd(8)

Alternative location for /tftpboot is /var/lib/tftpboot. For some reason the maintainer of ltsp ebuild / ltsp folks have selected the current IMO "non-standard" location. You can change it if you wish.

Flag -s tells tftpd to run chrooted. The '-u nobody' flag is there to improve security. When using '-u' you also need to change file permissions: (Don't forget this important step!!! You may need to repeat this in the future as you add / modify files.)

Code: chown
 mkdir /tftpboot
 chown nobody:nobody -R /tftpboot

Added Note: I've added this command to the /etc/init.d/in.tftpd under the start() method I've included chown -R nobody:nobody -R /tftpboot so each time you start the service, it resets all the permissions. my $.02

I'd be interested in any comments about the other tftp daemons that DO work with xinetd AND chroot to a specified directory or how the example above could be more complete. That is to say, if you have something to contribute. You can ask a question... but I'm not the expert here.

Firewall Rule

1. Save your current firewall rules iptables-save > /etc/iptables.bak
2. Open /etc/iptables.bak in your favorite text editor
3. Add the following rule(s) in appropriate order (according to your existing rules).

Firewall Rule: tftp
 -A INPUT -p udp -m state --state NEW -m udp --dport 69 -j ACCEPT

4. Restore all rules to be part of your current configuration iptables-restore /etc/iptables.bak


You can test the server is running tftpd:

Code: testing tftpd
 netstat -apn|grep ":69 "

Netstat should say something like

udp      0    0 *                    12125/in.tftpd

Boot up your LTSP client and you should get as far as

Loading .TFTP error 1 (File not found)
Unable to load file


Want to build your own LTSP environment? Index:LTSP

LTSP only comes in one official pre-packaged flavor. You might be able to find someone else's build on the net, but I'm lame, thus we're using the standard ebuild here. The configuration here is EXTREMELY complex, such that most mere mortals can't manage it so be sure to pay close attention.

Code: Install and Simple Configure
 emerge ltsp
 # [enter]
 # [c]
 # [8]
 # [enter]
 # [10]
 # [enter]
 # [11]
 # [enter]
 # [q]
 mkdir /tmp/{mnt,var}
 cd /opt/
 ln -s ltsp-${VER} ltsp
 cd /tftpboot/
 mv pxelinux.cfg/ pxe/
 ln -s pxe/pxelinux.cfg pxelinux.cfg

NOTE: Since the configuration tool isn't specifically for Gentoo I'd say don't bother with any of the other settings. Instead, do them by hand.

NOTE2: I got an error:

Checking xdmcp.........Unable to open /etc/X11/default-display-manager: No such file or directory

when running ltspcfg. Running touch /etc/X11/default-display-manager prior to running ltspcfg fixed the issue.

NOTE3: Another "error" you may see is "Checking xdm ........ found: none". This can be corrected by editing /usr/sbin/ltspcfg, add the missing directories/files for your display managers. i.e. add '"/usr/kde/3.5/bin/kdm",' to 'my @kdm_locs' and '"/usr/kde/3.5/share/config/kdm/kdmrc",' to 'my @kdmrc_locs'

Setting the Display (Desktop) Server

Be sure to change the server IP address to match your situation.

File: /opt/ltsp/i386/etc/lts.conf
       SERVER             =
       # using defaults for the rest
       XF86CONFIG_FILE = XF86Config.ltn
       # this machine has an ltn monitor which needs special configuration


Boot up your LTSP client and you should get as far as

Kernel Panic: Tried to kill init!
No root path

NOTE: If you have installed nfs-utils and are still getting this message, it may be due to another DHCP server on your network. Please read the the section about configuring the DHCP server for more info.


If you've been playing by numeber here, the last error you got was probably something about a kernel panic: attempted to kill init. That's because none of the filesystems are yet available to be mounted. Installing and configuring nfs will fix that. You will also need portmap. Be sure to have NFS support compiled in your kernel or at least have it installed as modules. You will find the NFS Support for the kernel in "File systems > Network File Systems > NFS server support".

NOTE: Since NFS and SYSKLOGD are inherently vulnerable to attack, it is important that you have some established level of trust betwixt yourself and your users! In example: a malicious user could fill the hard drive on the server by misusing the NFS swapfile mount or generating innumerable bogus errors to make the logfile on the server get big.

Code: nfs-utils
 echo "net-fs/nfs-utils tcpd" >> /etc/portage/package.use
 emerge nfs-utils
 mkdir -p /var/opt/ltsp/swapfiles
 vim /etc/exports
File: /etc/exports
# NFS file systems being exported.  See exports(5).

Firewall Rule

Because of the way the many different components of NFS work, it's a little tricky to set up a firewall for it. Please follow the firewall portion of this guide: NFS/Share Directories


Code: nfs-utils
 /etc/init.d/portmap start
 rc-update add portmap default
 /etc/init.d/nfs start
 rc-update add nfs default

Boot up your LTSP client and you should notice two things: An error about the system logger not accepting connections scrolls by on bootup:

 system logger couldn't connect

And the fact that X loads to a blank grey screen with an X in the center... and not much else is happening for you


You need a logger which allows remote logging so that the clients can write logs to the main server. There are two loggers which are very easy to set up for this.

If your current logger is different, you'll have to unmerge it:

Code: Uninstall the current logger
 LOGGER=`emerge -p logger | cut -d']' -f2 | cut -d'[' -f1`
 /etc/init.d/${LOGGER} stop
 emerge --unmerge ${LOGGER}


Code: sysklogd
 emerge sysklogd logrotate
 vim /etc/conf.d/sysklogd
 rc-update add sysklogd default
 /etc/init.d/sysklogd start
File: /etc/conf.d/sysklogd
 SYSLOGD="-m 0 -r"
 KLOGD="-c 3 -2"


Code: syslog-ng
 emerge syslog-ng logrotate
 vim /etc/syslog-ng/syslog-ng.conf
 rc-update add syslog-ng default
 /etc/init.d/syslog-ng start

I don't know how well the default gentoo conf for syslog-ng handles remote logging; I recommend this one:

You'll still need to make a slight modification to these lines:

File: /etc/syslog-ng/syslog-ng.conf
tcp(port(5140) keep-alive(yes));

Firewall Rule / Services

Code: Allow Remote Logging
 iptables-save > /root/iptables.bak
 vim /etc/services
 vim /root/iptables.bak
 iptables-restore /root/iptables.bak
File: /etc/services
 syslog          5140/tcp
File: /root/iptables.bak
 -A INPUT -p udp -m state --state NEW -m udp --dport syslog -j ACCEPT
 -A INPUT -p tcp -m state --state NEW -m tcp --dport syslog -j ACCEPT


/etc/init.d/sysklogd start
rc-update add sysklogd default

Boot up your LTSP client and you should notice the fact that X loads to a blank grey screen with an X in the center... and not much else is happening for you... on the client side

But notice what is happening on the server!

  1. grep -r ws241 /var/log/

/var/log/user.log:Feb 14 16:28:45 test rpc.mountd: authenticated mount request from for /opt/ltsp-4.1/i386 (/opt/ltsp-4.1/i386) /var/log/syslog.0:Feb 14 16:28:45 test rpc.mountd: authenticated mount request from for /opt/ltsp-4.1/i386 (/opt/ltsp-4.1/i386) /var/log/syslog.0:Feb 14 16:28:47 syslogd started: BusyBox v0.60.4 (2004.07.12-19:22+0000) /var/log/syslog.0:Feb 14 16:28:51 init: Entering runlevel: 5 /var/log/syslog.0:Feb 14 16:43:06 test gdm[7936]: gdm_slave_xioerror_handler: Fatal X error - Restarting /var/log/syslog.0:Feb 14 17:19:47 test gdm[9646]: Ping to failed, whacking display!

NOTE: `grep -r` is probably the most usefull command in all of *nix-dom. I urge you to remember that when you're trouble shooting - from error logs to source code, grep is your friend!

TIP: Webmin LTSP

Haven't messed with this much yet:

emerge webmin
tar xzpf ltsp-webmin-0.5.99.tar.gz -C /usr/libexec/webmin/
# tar xpf ltsp-webmin-0.5.99.wbm -C /usr/libexec/webmin/ # if you get the wbm instead
cp /usr/libexec/webmin/ltsp/config-redhat-linux /usr/libexec/webmin/ltsp/config-gentoo-linux
vim /etc/webmin/webmin.acl # add ltsp to root's list
vim /usr/libexec/webmin/ltsp/ltsp-webmin/ # uncomment lines 32-45
# I'd suggest just using
# wget
# tar xjpf etherboot-5.4.0.tar.bz2 ./
/etc/init.d/webmin start
rc-update add webmin default

Order of operations seems important, edit the webmin.acl before starting webmin for the first time

firefox https://localhost:10000/ # log in
firefox https://localhost:10000/ltsp/ # configure ltsp

Order of Operations

I recommend separating the server from the desktop. One reason for this is that your desktop houses the most problematic part of this equation - users. If you happen to host the school webservices on your server, you wouldn't want to have to disrupt it because of a problem with a zombie user process or mounting operation that necessitated a reboot.

See Also

Retrieved from ""

Last modified: Mon, 22 Sep 2008 03:48:00 +0000 Hits: 23,678