2. Setting up the server

  1. We will want to store prototype systems and snapshots in time of those systems. Each of these is a tree of files for a full client system, and so might occupy perhaps 4GB of disk space, assuming a conservative selection of packages. For a test setup involving a single prototype system with two snapshots, we'll want space for three of these, giving a rough estimate of 12GB as the minimum required disk space, on top of the space required for the server's normal filesystem.

    1. Begin installing Fedora Core 3 test1 on the server. If you select automatic partitioning, the installer will use the Logical Volume Manager (LVM) technology, putting all of your physical disk space (apart from a boot partition) into one large Volume Group, which contains logical volumes for swap space and the root partition. This is good for normal use, but the stateless-snapshooter tool will be able to operate more efficiently if we tune the setup of LVM so that our stateless systems are stored in separate logical volumes.

    2. Edit the results of the automatic partitioning, by shrinking the root partition to free up space in the Volume Group. Once this is done you can reduce the size of the Volume Group. You should then be able to create spare physical disk partitions (preferably on an entirely separate disk to the main install).

    3. Create an LVM volume group called e.g. VGStateless to hold prototype systems and their snapshots. Assign plenty of space on physical volumes (disk partitions) to it, but do not create any logical volumes inside it yet - we will do this later on.

  2. Select a Server installation; we will customise the exact package selection later on.

  3. After the installation, reboot. Don't set up any users yet.

  4. Install the latest versions of the readonly-root and stateless-server packages onto the server.

    You can do this by editing /etc/yum.conf and appending these lines:

    [StatelessLinux] 
    name=Stateless Linux
    baseurl=http://people.redhat.com/dmalcolm/stateless
    

    and then running:

    yum install readonly-root stateless-server
    

    At this stage the following packages should be installed:

    • anaconda

    • anaconda-runtime

    • bogl

    • bogl-bterm

    • booty

    • busybox-anaconda

    • openldap-clients

    • openldap-servers

    • rsync

    • httpd

    • openssl-perl

    • tftp-server

    • stateless-server

    • stateless-common

    • readonly-root

  5. Set up LDAP database (for storing information on users and on Stateless Linux clients and servers):

    1. Generate a root password for the LDAP server by running slappasswd. This will output an encrypted version of your password.

    2. Edit /etc/openldap/slapd.conf

      1. Edit the suffix line (about halfway down) from "dc=my-domain, dc=com" to match your setup, e.g. to "dc=stateless-test, dc=fubar, dc=org"

        Make similar changes to the rootdn line; e.g. from "cn=Manager, dc=my-domain, dc=com" to "cn=Manager, dc=stateless-test, dc=fubar, dc=org"

      2. Add a rootpw line containing the newly generated password.

      3. Add include /usr/share/stateless/stateless.schema near the top, after the other include lines

      4. Add access control rules to allow clients to write information about their current status into the LDAP directory:

        access to dn.regex="dc=status,macAddress=.*,dc=hosts,dc=stateless,ou=services,dc=stateless-test, dc=fubar, dc=org" by anonymous write
        access to * by * read
        

        Append update_anon to the allow line near the top of file in order to allow anonymous updates.

    3. Start the LDAP server:

      chkconfig ldap on
      service ldap start
      
      [Tip]Use slaptest to debug server failures

      If the server fails to start you can use the slaptest utility with debugging enabled to see what's causing the failure:

      slaptest -d 5
      
    4. Create basic structure within the LDAP directory:

      
      ldapadd -x -W -D"cn=Manager, dc=stateless-test, dc=fubar, dc=org" <<EOF
      # Create root entry:
      dn: dc=stateless-test, dc=fubar, dc=org
      dc: stateless-test
      objectClass: domain
      
      # Create entry to hold user accounts:
      dn: ou=people, dc=stateless-test, dc=fubar, dc=org
      objectClass: organizationalUnit
      ou: people
      
      # Create entry to hold groups:
      dn: ou=groups, dc=stateless-test, dc=fubar, dc=org
      objectClass: organizationalUnit
      ou: groups
      
      # Create entry to hold services
      dn: ou=services,  dc=stateless-test, dc=fubar, dc=org
      objectClass: organizationalUnit
      ou: services
      
      # Create entry to hold information of Stateless prototype systems and snapshots
      dn: dc=stateless, ou=services, dc=stateless-test, dc=fubar, dc=org
      objectClass: statelessContainer
      dc: stateless
      
      # Create entry to hold information on Stateless clients:
      dn: dc=hosts, dc=stateless, ou=services, dc=stateless-test, dc=fubar, dc=org
      objectClass: statelessContainer
      dc: hosts
      
      # Create entry to hold information on Stateless servers:
      dn: dc=servers, dc=stateless, ou=services, dc=stateless-test, dc=fubar, dc=org
      objectClass: statelessContainer
      dc: servers
      
      # Need the previous blank line to correctly terminate the above entry
      EOF
      
      
    5. Disable the firewall on the server [1]

      service iptables stop
      
    6. Set up NFS home directories for users:

      
      mkdir /home/users
      cat > /etc/exports << EOF 
      /home/users *.fubar.org(rw,async)
      EOF
      chkconfig nfs on
      service nfs start
      
      
    7. Creating groups manually:

      
      ldapadd -x -W -D"cn=Manager,dc=stateless-test, dc=fubar, dc=org" <<EOF
      dn: cn=demo-group,ou=groups,dc=stateless-test, dc=fubar, dc=org
      objectClass: posixGroup
      cn: demo-group
      gidNumber: 1000
      memberUid: group-name
      
      #
      EOF
      
      

      To create users, run slappasswd to generate a userPassword value. Then run this:

      
      ldapadd -x -W -D"cn=Manager,dc=stateless-test, dc=fubar, dc=org" <<EOF
      dn: uid=demo-user,ou=people,dc=stateless-test, dc=fubar, dc=org
      objectClass: inetOrgPerson
      objectClass: posixAccount
      objectClass: shadowAccount
      uid: demo-user
      uidNumber: 1000
      gidNumber: 1000
      cn: Demo User
      sn: Demo User
      homeDirectory: /home/users/demo-user
      loginShell: /bin/bash
      userPassword: output-from-slappasswd
      
      #
      EOF
      
      
  6. Use Apache to serve a kickstart file for anaconda when creating new caching clients. Set it up as follows:

    
    mkdir -p /var/stateless/http/
    
    cat > /etc/httpd/conf.d/stateless.conf << EOF
    Alias /stateless /var/stateless/http
    
    <Directory /var/stateless/http>
      Options -Indexes
    </Directory>
    EOF
    
    chkconfig httpd on
    service httpd start
    
    

    Create the bootstrap kickstart file:

    
    cp /usr/share/doc/stateless-server-version/ks-example.cfg /var/stateless/http/ks-bootstrap.cfg
    
    

    Edit ks-bootstrap.cfg and change the nfs line to point to an NFS-exported install tree. (In the future ks-bootstrap.cfg will be automatically generated.)

  7. Configure rsync and xinetd to serve out snapshots. First, create an /etc/rsyncd.conf that looks like:

    [stateless]
    path=/srv/stateless/snapshots
    comment=Stateless Linux snapshots
    uid=0
    

    Then turn on rsync.

    chkconfig rsync on
    service xinetd restart
    	
  8. Set up DHCP to serve out IP addresses to client machines, and also to allow diskless booting.

    cat > /etc/dhcpd.conf << EOF
    ddns-update-style interim;
    ignore client-updates;
    
    subnet $subnet netmask $netmask {
      option routers              $gateway;
      option subnet-mask          $netmask;
      option domain-name-servers  $dns_servers;
    
      range dynamic-bootp $ip_range_start $ip_range_end;
      default-lease-time 21600;
      max-lease-time 43200;
    
      class "pxeclients" {
        match if substring(option vendor-class-identifier, 0, 9) = "PXEClient";
        next-server $stateless_server;
        filename "linux-install/pxelinux.0";
      }
    }
    EOF
    
    chkconfig dhcpd on
    service dhcpd start
    
    

    Example values for the above might be as follows (but don't use these specific values):

      subnet = 172.31.0.0
      netmask = 255.255.255.0
      gateway = 172.31.0.1
      dns_servers = 172.31.0.1
      ip_range_start = 172.31.0.128
      ip_range_end = 172.31.0.254
      stateless_server = 172.31.0.3
    
  9. Edit /etc/sysconfig/stateless:

    1. Set SERVER_NAME to the hostname or IP address of this computer; this is used by the snapshoot tool when writing information into the LDAP database

    2. Set LDAP_SERVER to the host name or IP address of your LDAP server

    3. Set LDAP_BASE_DN to the base Distinguished Name as set up above e.g. dc=stateless-test, dc=fubar, dc=org

    4. Set LDAP_ADMIN_DN to the administrative Distinguished Name as set up in rootdn in /etc/openldap/slapd.conf above e.g. to cn=Manager, dc=stateless-test, dc=fubar, dc=org

    5. Set LDAP_ADMIN_PASSWD to the plaintext password you entered above. [2]

  10. Enable TFTP, so that diskless clients can use this protocol to download their kernel and other boot-time data:

    
    chkconfig xinetd on
    chkconfig tftp on
    
    
  11. Configure the server to allow clients to connect using XDMCP, by editing /etc/X11/gdm/gdm.conf. Set RemoteGreeter to /usr/bin/gdmgreeter In the xdmcp section, set Enable to true



[1] We're aware this is a security issue and will be working to resolve it.

[2] This is another security issue. We are working on a better solution to this.