'Dynamic DNS for LTSP'

This is a disputable question if LTSP workstations need their DNS. I have decided they do. Besides with the setup there is another problem solved. When setting up DHCP for workstations you have to configure a fixed adress for each workstation ...

Something like this:

host x402c {
          o hardware ethernet 00:E0:4D:05:3D:AD; option host-name "x402c"; fixed-address x402c; 

or if the host can not be resolved - somthing like this:

host x201e {
            hardware ethernet 00:E0:4D:05:EA:95; option host-name "x201e"; fixed-address; 

Besides you have to configure DHCP not assign this ips. The ips must be excluded from the range of DHCP served ips.

There is another way to make sure there are no DHCP ip conflicts. You can setup DHCP server to use a very long lease time and maybe reboot workstations over night. Then you do not have to setup a dixed lease for each workstation.

If you do not like this - there is another way.

Another aproach is to use a dhcp-client on the workstation and use normal life dhcp environment. The question is how to start the client. There are 2 possible aproaches. One is to use the dhcp client from initrd. But if you do this you will not be able to umount initrd. The other solution is to start dhcp client on the workstation after the bootstrap process. But to do this you have to configure the dhcp client not to REINITIALISE the network card so the workstation does not loose its root. Luckily this is not hard to do with dhcp3-client package.

  1. install the dhcp3-client package in the diskless root.
  2. Edit /etc/dhcp3/dhclient.conf in the diskless root to make dhcp client use a custom script instead of /sbin/dhclient-script
    This is from my config: script "/etc/dhcp3/ltsp-dhclient-script";

  3. Copy the /sbin/dhclient-script to make the new script and edit it not to initialise network card on starttup. The onle section that needs editing is the preinit clause in case. Make it look like this

              o # Do nothing ;; 

Here is my file


# dhclient-script for Linux. Dan Halbert, March, 1997.
# Updated for Linux 2.[12] by Brian J. Murrell, January 1999.
# Modified for Debian. Matt Zimmerman and Eloy Paris, December 2003
# Modified to remove useless tests for antiquated kernel versions that
# this doesn't even work with anyway, and introduces a dependency on /usr
# being mounted, which causes cosmetic errors on hosts that NFS mount /usr
# Andrew Pollock, February 2005
# Modified to work on point-to-point links. Andrew Pollock, June 2005
# Modified to support passing the parameters called with to the hooks. Andrew Pollock, November 2005

# The alias handling in here probably still sucks. -mdz

make_resolv_conf() {

     if [ -n "$new_domain_name" -o -n "$new_domain_name_servers" ]; then
          o local new_resolv_conf=/etc/resolv.conf.dhclient-new rm -f $new_resolv_conf if [ -n "$new_domain_name" ]; then

                  echo search $new_domain_name >>$new_resolv_conf 
            fi if [ -n "$new_domain_name_servers" ]; then
                + for nameserver in $new_domain_name_servers; do

                        echo nameserver $nameserver >>$new_resolv_conf 
                + done 
            else # keep 'old' nameservers

                  sed -n /^\w*[Nn][Aa][Mm][Ee][Ss][Ee][Rr][Vv][Ee][Rr]/p /etc/resolv.conf >>$new_resolv_conf 
            fi chown --reference=/etc/resolv.conf $new_resolv_conf chmod --reference=/etc/resolv.conf $new_resolv_conf mv -f $new_resolv_conf /etc/resolv.conf 


run_hook() {

     local script="$1" local exit_status shift # discard the first argument, then the rest are the script's if [ -f $script ]; then
          o $script "$@" 

      if [ -n "$exit_status" ] && [ "$exit_status" -ne 0 ]; then
          o logger -p daemon.err "$script returned non-zero exit status $exit_status" save_exit_status=$exit_status 
      fi return $exit_status 


run_hookdir() {

     local dir="$1" local exit_status shift # See run_hook if [ -d "$dir" ]; then
          o for script in $(run-parts --list $dir); do

                  run_hook $script "$@" || true exit_status=$? 
      fi return $exit_status 


# Must be used on exit. Invokes the local dhcp client exit hooks, if any. 
exit_with_hooks() {

     exit_status=$1 # Source the documented exit-hook script, if it exists if ! run_hook /etc/dhcp3/dhclient-exit-hooks "$@"; then
          o exit_status=$? 
      fi # Now run scripts in the Debian-specific directory. if ! run_hookdir /etc/dhcp3/dhclient-exit-hooks.d "$@"; then
          o exit_status=$? 
      fi exit $exit_status 


set_hostname() {

     local current_hostname=$(hostname) if [ -z "$current_hostname" -o "$current_hostname" = "(none)" ]; then
          o hostname "$new_host_name" 


if [ -n "$new_broadcast_address" ]; then

     new_broadcast_arg="broadcast $new_broadcast_address" 

fi if [ -n "$old_broadcast_address" ]; then

     old_broadcast_arg="broadcast $old_broadcast_address" 

fi if [ -n "$new_subnet_mask" ]; then

     new_subnet_arg="netmask $new_subnet_mask" 

fi if [ -n "$old_subnet_mask" ]; then

     old_subnet_arg="netmask $old_subnet_mask" 

fi if [ -n "$alias_subnet_mask" ]; then

     alias_subnet_arg="netmask $alias_subnet_mask" 

fi if [ -n "$new_interface_mtu" ] && [ $new_interface_mtu -ge 575 ]; then

     mtu_arg="mtu $new_interface_mtu" 

fi if [ -n "$IF_METRIC" ]; then

     metric_arg="metric $IF_METRIC" # interfaces(5), "metric" option 


# The action starts here

# Invoke the local dhcp client enter hooks, if they exist. run_hook /etc/dhcp3/dhclient-enter-hooks run_hookdir /etc/dhcp3/dhclient-enter-hooks.d

# Execute the operation case "$reason" in

          o # Do nothing ;; 
          o # Do nothing ;; 
          o set_hostname if [ -n "$old_ip_address" -a -n "$alias_ip_address" -a \
                + "$alias_ip_address" != "$old_ip_address" ]; then
                + # Possible new alias. Remove old alias. ifconfig $interface:0- inet 0 
            fi if [ -n "$old_ip_address" -a \
                + "$old_ip_address" != "$new_ip_address" ]; then
                + # IP address changed. Bringing down the interface will delete all routes, # and clear the ARP cache. ifconfig $interface inet 0 
            fi if [ -z "$old_ip_address" -o "$old_ip_address" != "$new_ip_address" -o \
                + "$reason" = "BOUND" -o "$reason" = "REBOOT" ]; then ifconfig $interface inet $new_ip_address $new_subnet_arg \
                      # $new_broadcast_arg $mtu_arg 
                  for router in $new_routers; do
                      # route add default dev $interface gw $router $metric_arg 
            fi if [ "$new_ip_address" != "$alias_ip_address" -a -n "$alias_ip_address" ];
                + then ifconfig $interface:0- inet 0 ifconfig $interface:0 inet $alias_ip_address $alias_subnet_arg route add -host $alias_ip_address $interface:0 
            fi make_resolv_conf ;; 
          o if [ -n "$alias_ip_address" ]; then
                + # Turn off alias interface. ifconfig $interface:0- inet 0 
            fi if [ -n "$old_ip_address" ]; then
                + # Shut down interface, which will delete routes and clear arp cache. ifconfig $interface inet 0 
            fi if [ -n "$alias_ip_address" ]; then
                + ifconfig $interface:0 inet $alias_ip_address $alias_subnet_arg route add -host $alias_ip_address $interface:0 
            fi ;; 
          o if [ -n "$alias_ip_address" ]; then
                + ifconfig $interface:0- inet 0 
            fi ifconfig $interface inet $new_ip_address $new_subnet_arg \
                + $new_broadcast_arg $mtu_arg 
            set -- $new_routers first_router="$1" if ping -q -c 1 $first_router; then
                + if [ "$new_ip_address" != "$alias_ip_address" -a \
                      # -n "$alias_ip_address" ]; then ifconfig $interface:0 inet $alias_ip_address $alias_subnet_arg route add -host $alias_ip_address dev $interface:0 
                  fi # point to point if [ "$new_subnet_mask" == "" ]; then
                      # for router in $new_routers; do
                            * route add -host $router dev $interface 
                  fi for router in $new_routers; do
                      # route add default dev $interface gw $router $metric_arg 
                  done make_resolv_conf 
                + # Changed from 'ifconfig $interface inet 0 down' - see Debian bug #144666 ifconfig $interface inet 0 exit_with_hooks 2 "$@" 
            fi ;; 


exit_with_hooks 0
  1. To activate the client you may use standard debian way - /etc/network/interfaces. The file is created with ltsp scripts. So edit /etc/network/interfaces in ltsp chroot to use dhcp for eth0. Here is my file:

    # The loopback network interface auto lo iface lo inet loopback
    # The primary network interface auto eth0 iface eth0 inet dhcp
  2. For normal operations dhcp3-client needs /var/lib/dhcp3 writable. So edit /etc/default/ltsp-client-setup in workstations chroot.

    rw_dirs="/var/lib/xkb /var/log /var/spool /var/tmp /tmp /var/lib/discover /etc/console-setup /var/lib/dhcp3 "

That is it. Now you have a normal dhcp environment and you can configure anything you want. And dynamic DNS update with dhcp too. For configuring dynamic update refer to http://www.ops.ietf.org/dns/dynupd/secure-ddns-howto.html or any other internet resources.

Here is my dhcpd.conf file on the server. Maybe you will find it usefull.