User Tools

Site Tools


doc:howto:tce

This is an old revision of the document!


X2Go-ThinClientEditon-Live (TCE-Live, formerly known as TCE-NG)

This page is very much Work in Progess. Please leave a note on x2go-user@lists.x2go.org if you're interested in trying this out, so we can guide you along if something goes wrong.
If you are looking for installation instructions for the classic, NFS-filesystem-based X2Go-ThinClient, please go here

History, Rationale, Outlook

During the time of Debian Wheezy being Debian's stable release, we started developing a new ThinClientEdition then called TCE-Next Generation, or TCE-NG for short - one that is based on Debian-Live and thus does no longer rely on NFS (though NFS can still be used to deploy the image - but we do not recommend that approach). Instead, the entire image is loaded into the RAM of the ThinClient machine. To avoid confusion, and because it has since left the “NG” state, we now call it TCE-Live.

The disadvantage is that your ThinClient now needs at least 1 GB of RAM (see below).

However, the huge advantage is that there no longer is a need for any high-availibility setup concerning NFS (nor HTTP/HTTPS/FTP). If you follow our advice of loading the entire image into the ThinClient's RAM, or using local storage, all you need is an HTTP (HTTPS optional for later stages) or FTP server with a dedicated IP, if you want to use netbooting. It is also possible to deploy the image to the ThinClient's local storage, if present, and have it update in the background.

Besides, making changes to/updating the classic, NFS-based TCE (henceforth referred to as TCE-Classic) with the entire filesystem, not just its compressed image, spread out over the NFS share was rather finicky - with the current TCE-Live, you build and deploy a new image every time you make a change, and you can test it on a single client without interrupting your production environment. The local storage feature can also be used to create a portable version of both X2Go-TCE and X2goClient for Windows, sharing the same configuration, on CD/DVD/USB media.

We've also received reports that TCE-Classic wouldn't work with Jessie, or at least it was very hard to get it to work. Our TCE-Live works just fine with Jessie, and we expect it to work in Stretch and hopefully in Buster (Stretch+1) as well. The one catch is that the live-build package in Debian/the Debian-Live project is currently looking for a new maintainer - so there is a slim chance that live-build might be removed from Debian Buster, especially if no new maintainer steps up and the live-build replacement that is currently in the works (called live-wrapper) contains all the required functionality of live-build by then.

ThinClient prerequisites for all TCE-Live variants

  • At least 1 GB of RAM unless you use non-NTFS local storage, in that case, 512MB or even 256MB might work - but would you really want to use a Client that has 4 Megabytes of free RAM (our test result with 256 MB RAM total) and no swapspace?
  • For clients with less than 1 GB of RAM and no local storage, you could also use httpfs= or ftpfs= instead of fetch=, or netboot=nfs nfsroot=ip-of-your-server-here:/path/to/x2go-tce-filesystem.squashfs when netbooting, but this will make you dependent on an uninterrupted network connection again
  • At least an i586-compatible CPU
  • Capability to boot via PXE or sufficient local storage (expect 250-450 MB, depending on what you decide to include)
  • A graphics card and input devices (Keyboard, Mouse/Trackball/Touchpad/Trackpoint/Touchscreen, …) that are supported by the stock Debian X Server

Build system prerequisites for all variants

  • You need a Debian Jessie system to build the image. (Other distributions based on Debian might work, but this is untested.)
  • We suggest using a 64-Bit system, however, it is possible to use a 32-Bit system if you don't want to build a 64-Bit ThinClient image.
  • We suggest leaving at least 4 GB of free disk space so the build won't abort due to insufficient disk space while packages are downloaded, unpacked and copied around.
  • Make sure your package list is up to date by running:
    sudo apt-get update 
  • Install the required packages by running:
    sudo apt-get install genisoimage git-core live-build live-config-doc live-manual-html live-boot-doc

Building your own X2Go-TCE Image

Configuring the Build

# Select ONE of the following git reposities
# this one loosely corresponds to "stable"
export LBX2GO_CONFIG='git://code.x2go.org/live-build-x2go.git::feature/openbox'
# this one loosely corresponds to "heuler"
#export LBX2GO_CONFIG='https://github.com/LinuxHaus/live-build-x2go::feature/openbox'

# Select ONE of the following LBX2GO_ARCH lines and comment out the others 
# (feel free to use long or short options)
# for 64-Bit builds, use:
# export LBX2GO_ARCH='-a amd64 -k amd64' 
# 32-Bit, larger memory footprint, but faster performance on i686 and newer
# export LBX2GO_ARCH='-a i386 -k 686-pae'
# 32-Bit, smallest memory footprint
export LBX2GO_ARCH='--architectures i386 --linux-flavours 586' 

# These options are meant to reduce the image size.
# Feel free to adapt them after consulting "man lb_config"
export LBX2GO_SPACE='--apt-indices none
                     --apt-recommends false
                     --cache false 
                     --checksums none
                     --firmware-binary false
                     --memtest none
                     --win32-loader false'

# These are default values that should not require tuning
export LBX2GO_DEFAULTS='--backports true
                        --firmware-chroot true
                        --initsystem sysvinit
                        --security true
                        --updates true'
                        
export LBX2GO_ARCHIVE_AREAS="main contrib non-free"

# This is to optimize squashfs size, based on a suggestion by intrigeri from the TAILS team
# note that this will permanently change /usr/lib/live/build/binary_rootfs
sed -i -e 's#MKSQUASHFS_OPTIONS="${MKSQUASHFS_OPTIONS} -comp xz"#MKSQUASHFS_OPTIONS="${MKSQUASHFS_OPTIONS} -comp xz -Xbcj x86 -b 1024K -Xdict-size 1024K"#' /usr/lib/live/build/binary_rootfs

# This removes documentation, locales and man pages
# You can safely enable this if you intend to run X2GoClient in fullscreen mode all the time, or when building the ssh-only rescue image.
# For all other uses of the TCE-Live image creator (i.e. Minidesktop), your results may vary ... use at your own risk.
export LBX2GO_TCE_SHRINK="true"

# This patches the squashfs file into the initrd. Only parsed when image type "netboot" is set.
# Will require boot parameter live-media=/ instead of fetch=...
# Both TFTP client and TFTP server must support file transfers >32MB for this to work, if you want to deploy this initrd via TFTP.
# When using iPXE, you can use http instead of TFTP.
# This is especially helpful if you want to netboot via http and cannot use the server's IP, but must specify a DNS name - as "fetch=..." only understands IPs.
export LBX2GO_NOSQUASHFS="false"

# Select ONE of the following LBX2GO_IMAGETYPE lines and comment out the others 
# to create an iso image:
# export LBX2GO_IMAGETYPE='iso'
# to create an iso image that can also be dd'ed to USB media:
# export LBX2GO_IMAGETYPE='iso-hybrid'
# to create a netboot-image:
export LBX2GO_IMAGETYPE='netboot'
# NOT RECOMMENDED:
# to create an image that can be written to a hard disk (always results
# in a "build failed" message, even though the build might have worked):
# export LBX2GO_IMAGETYPE='hdd'
# to create a tar file only (seems to be broken in live-build):
# export LBX2GO_IMAGETYPE='tar'

Live-Patching the Build

This patch is required if you need USB mount capability on the ThinClient while Bug #1136 is still unresolved.

mkdir -p ./patch/includes.chroot/usr/lib/x2go/tce/

cat >./patch/includes.chroot/usr/lib/x2go/tce/x2gousbmount <<'USBMOUNTPATCH'
#!/usr/bin/perl

# Copyright (C) 2007-2017 by X2Go project, http://wiki.x2go.org
#       Oleksandr Shneyder <oleksandr.shneyder@obviously-nice.de>

# X2Go is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# X2Go is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the
# Free Software Foundation, Inc.,
# 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.

use strict;
use File::Path::Expand;
use Sys::Syslog qw( :standard :macros );

my $user;
if ( -d "/lib/live/config" ) {
        $user='user';
} else {
        $user='x2gothinclient';
}

# We need this as chown requires numeric uid/gid
my ($login,$pass,$uid,$gid) = getpwnam($user);

# Some last-ditch efforts to fulfill the prerequisites for File Sharing:
# - This is stuff that should already have happened earlier in the boot process.
# - Also, if a directory already exists, we silently assume that ownership and
#   permissions are correct.  This is so that users that deliberately set
#   different ownership/permission values don't have their settings silently
#   overwritten.

unless ( -d expand_filename("~$user/mounts")) {
        mkdir expand_filename("~$user/mounts");
        chmod 0700, expand_filename("~$user/mounts");
        chown $uid, $gid, expand_filename("~$user/mounts");
}

unless ( -d expand_filename("~$user/export")) {
        mkdir expand_filename("~$user/export");
        chmod 0700, expand_filename("~$user/export");
        chown $uid, $gid, expand_filename("~$user/export");
}

unless ( -d expand_filename("~$user/logins")) {
        mkdir expand_filename("~$user/logins");
        chmod 0700, expand_filename("~$user/logins");
        chown $uid, $gid, expand_filename("~$user/logins");
}

openlog($0,'cons,pid','user');
setlogmask( LOG_UPTO(LOG_NOTICE) );


sub check_x2gothinclientmode {
        # check if X2GoClient is running in thinclient mode
        # old code would check if x2gothinclientd was running,
        # which fails on X2Go-TCE-live
        my $x=`ps u -C x2goclient`;
        if ( $x=~m/\W*--thinclient\W*/ )
        {
                return 1;
        }
        return 0;
}

if (  check_x2gothinclientmode() ||  ( -d "/usr/share/doc/x2gothinclient-minidesktop" ) )
{

        open (F,">>/var/log/usb");

        my $dev=$ENV{'DEVNAME'};
        my $model=$ENV{'ID_MODEL'};
        my $vendor=$ENV{'ID_VENDOR'};
        my $action=$ENV{'ACTION'};
        my @ldev=split("/","$dev");
        my $ldev=@ldev[@ldev-1];
        # mntdir is not the directory where the mountpoint will be rooted,
        # but where tracking of mount states takes place
        my $mntdir;
        if ( -d expand_filename("~$user/mounts")) {
                $mntdir=expand_filename("~$user/mounts");
        } elsif ( -d "/var/run" ) {
                $mntdir="/var/run";
        } elsif ( -d "/run" ) {
                $mntdir="/run";
        } else {
                die "No directory found that we could use as \$mntdir..."
        }

        my $name="${vendor}_${model}";
        $name=~s/ //g;
        $name=~s/\\//g;
        $name=~s/\///g;
        print F "action: $action,  device: $dev, model: $model ($ldev), total: $name\n";
        mkdir("/media");
        mkdir("/media/$name");
        print F "$name\n";

        if ( $action eq "add")
        {

                ###
                ### ACTION: mount device after it has been added to USB subsystem
                ###

                syslog('notice', "device add action called");

                # prepare mount points
                mkdir("/media");
                mkdir("/media/$name");
                mkdir("/media/$name/$ldev");

                # mount the USB device
                if(system("mount $dev /media/$name/$ldev -o uid=$user,sync,uni_xlate")==0)
                {
                        syslog('notice', "USB device $name ($ldev) successfully mounted");
                        # if mounted, inform x2goclient about it...
                        system("touch $mntdir/$ldev.mounted");
                        open (D,">",expand_filename("~$user/export/$name.$ldev"));
                        print D "export=/media/$name/$ldev\n";
                        close (D);
                }
                else
                {
                        # the mount failed, let's assume that the device is encrypted...
                        my $enc=`ls -1 $mntdir | grep .encrypted`;
                        if(  $enc eq "" )
                        {
                                # use cryptsetup to decrypt the device...
                                system("/sbin/cryptsetup --key-file /etc/keys/keystick.key luksOpen $dev keystick");

                                # mount the ,,decrypted'' USB device via devmapper...
                                if(system("mount /dev/mapper/keystick  /media/$name/$ldev ")==0)
                                {
                                        # inform x2goclient about this...
                                        system("touch $mntdir/$ldev.encrypted");
                                        system("chown -R $user /media/$name/$ldev/dsa.key");
                                        open (D,">",expand_filename("~$user/logins/$name.$ldev"));
                                        print D "login=/media/$name/$ldev\n";
                                        close (D);
                                }
                                else
                                {
                                        # on mount failures release the decrypted device again
                                        system("/sbin/cryptsetup luksClose keystick");
                                }
                        }
                        else
                        {
                                print F "cryptodisk already present\n";
                        }
                }
        }
        elsif ( $action eq "remove" )
        {

                ###
                ### ACTION: unmount device after it has been removed from the USB subsystem
                ###

                syslog('notice', "device remove action called");

                # we rely on our own mount logistics here...
                if ( -e "$mntdir/$ldev.mounted" )
                {
                        # inform x2goclient that the device has been removed
                        system ("umount -ff /media/$name/$ldev");
                        unlink ("$mntdir/$ldev.mounted");
                        open ( D,">",expand_filename("~$user/export/$name.$ldev.unexport"));
                        print D "unexport=/media/$name/$ldev\n";
                        close (D);
                        syslog('notice', "USB device $name ($ldev) successfully unmounted");
                }
                elsif ( -e "$mntdir/$ldev.encrypted" )
                {
                        # inform x2goclient that the device has been removed
                        # release the encrypted device mapping
                        unlink ("$mntdir/$ldev.encrypted");
                        open ( D,">",expand_filename("~$user/logins/$name.$ldev.unexport"));
                        print D "logout=/media/$name/$ldev\n";
                        system("umount /media/$name/$ldev");
                        system("/sbin/cryptsetup luksClose keystick");
                        close (D);
                }
        }

        close (F);
}
USBMOUNTPATCH
chmod 755 ./patch/includes.chroot/usr/lib/x2go/tce/x2gousbmount

Starting the Build

Change to a directory where you want to save your builds, and run the following commands:

# Create Timestamp
LBX2GO_TIMESTAMP=$(date +"%Y%m%d%H%M%S") 

# Set Directory name
LBX2GO_TCEDIR=./live-build-x2go-$LBX2GO_TIMESTAMP

if [ -z "$LBX2GO_ARCH" ] ||
   [ -z "$LBX2GO_SPACE" ] ||
   [ -z "$LBX2GO_CONFIG" ] ||
   [ -z "$LBX2GO_DEFAULTS" ] ||
   [ -z "$LBX2GO_IMAGETYPE" ] ||
   [ -z "$LBX2GO_TIMESTAMP" ] ||
   [ -z "$LBX2GO_ARCHIVE_AREAS" ]; then
    echo -e "One or more of the following variables is unset:"
    echo -e "LBX2GO_ARCH: '${LBX2GO_ARCH}'"
    echo -e "LBX2GO_SPACE: '${LBX2GO_SPACE}'"
    echo -e "LBX2GO_DEFAULTS: '${LBX2GO_DEFAULTS}'"
    echo -e "LBX2GO_CONFIG: '${LBX2GO_CONFIG}'"
    echo -e "LBX2GO_IMAGETYPE: '${LBX2GO_IMAGETYPE}'"
    echo -e "LBX2GO_TIMESTAMP: '${LBX2GO_TIMESTAMP}'"
    echo -e "LBX2GO_ARCHIVE_AREAS: '${LBX2GO_ARCHIVE_AREAS}'"
    echo -e "Please visit http://wiki.x2go.org/doku.php/doc:howto:tce"
    echo -e "and read up on the general prerequisites for X2Go-TCE"
else
    # This will create a timestamped subdirectory for the build
    mkdir -p $LBX2GO_TCEDIR
    cd $LBX2GO_TCEDIR

    lb config $LBX2GO_ARCH $LBX2GO_SPACE $LBX2GO_DEFAULTS \
       --config $LBX2GO_CONFIG --binary-images $LBX2GO_IMAGETYPE \
       --archive-areas "$LBX2GO_ARCHIVE_AREAS"
    if [ -d "../patch" ] ; then
        cp -a ../patch/* config/
    fi
    if [ "$LBX2GO_TCE_SHRINK" = "true" ] ; then
        echo '#!/bin/sh' >./config/hooks/0112-remove-folders.hook.chroot
        echo 'set -e' >>./config/hooks/0112-remove-folders.hook.chroot
        echo '# Remove folders' >>./config/hooks/0112-remove-folders.hook.chroot
        echo 'rm -rf ./usr/share/doc/*' >>./config/hooks/0112-remove-folders.hook.chroot
        echo 'rm -rf ./usr/share/locale/*' >>./config/hooks/0112-remove-folders.hook.chroot
        echo 'rm -rf ./usr/share/man/*' >>./config/hooks/0112-remove-folders.hook.chroot
        [ "$LBX2GO_IMAGETYPE" != "netboot" ] && echo 'rm -rf ./var/lib/apt/lists/*' >>./config/hooks/0112-remove-folders.hook.chroot
        chmod 755 ./config/hooks/0112-remove-folders.hook.chroot
    fi
    if lb build ; then
        echo -e "Build is done: '$LBX2GO_TCEDIR'"
        ln ./binary/live/filesystem.squashfs ./x2go-tce-filesystem.squashfs
        if [ "$LBX2GO_IMAGETYPE" = "netboot" ] ; then
            ln ./tftpboot/live/vmlinuz ./x2go-tce-vmlinuz
            ln ./tftpboot/live/initrd.img ./x2go-tce-initrd.img
            if [ "$LBX2GO_NOSQUASHFS" = "true" ] ; then
                (cd binary; echo live$'\n'live/filesystem.squashfs |cpio -o -H newc | gzip --fast) >./x2go-tce-filesystem.cpio.gz
                cat ./x2go-tce-initrd.img ./x2go-tce-filesystem.cpio.gz >./x2go-tce-initrd-with-fs.img
                rm ./x2go-tce-filesystem.cpio.gz ./x2go-tce-filesystem.squashfs ./x2go-tce-initrd.img
            fi
        fi
        if [ "$LBX2GO_IMAGETYPE" = "iso" ] || [ "$LBX2GO_IMAGETYPE" = "iso-hybrid" ] ; then
            ln ./binary/live/vmlinuz ./x2go-tce-vmlinuz
            ln ./binary/live/initrd.img ./x2go-tce-initrd.img
            genisoimage -o ./x2go-tce-squashfs-only.iso -R -J -graft-points live/filesystem.squashfs=./x2go-tce-filesystem.squashfs 
            [ -e ./live-image-i386.hybrid.iso ] && ln ./live-image-i386.hybrid.iso ./original-x2go-tce-live-image-i386.hybrid.iso
            [ -e ./live-image-i386.iso ] && ln ./live-image-i386.iso ./original-x2go-tce-live-image-i386.iso
            mv ./x2go-tce-filesystem.squashfs ./original-x2go-tce-filesystem.squashfs
        fi
        lb clean
        rm -rf ./cache
    else
        # note that imagetype hdd always ends here,
        # due to a harmless error that can be safely ignored, but which sets the error code to != 0
        echo -e "Build failed: '$LBX2GO_TCEDIR'"
    fi
    cd ..
fi

Netbooting

Prerequisites

  • You need an existing DHCP/PXE/TFTP setup with the usual pxelinux.0/pxelinux.cfg boot and configuration files, and a directory where kernel and initrd can be stored. This is not covered here, though we might add a separate howto for that some time later on.
    • Note that whoever manages to spoof this server name can deploy rogue images to your ThinClients. If this is a serious issue for you, consider using local storage media and the autoupdater instead.
    • It might be possible to already use HTTPS in this early stage when using iPXE. This is untested and requires building your own iPXE image. see http://ipxe.org/crypto for details. Alternatively, use ipxe.lkrn (from http://boot.ipxe.org/ipxe.lkrn) and pxelinux.0 in combination with scripted ipxe commands in the pxelinux.cfg.
  • You will also need an HTTP/HTTPS/FTP server with a dedicated IP (no name-based virtual hosts) for the squashfs image. - Note: set LBX2GO_NOSQUASHFS=true and use iPXE (e.g. with ipxe.lkrn + pxelinux.0) if you cannot use an IP for your host. Another option (untested) is explained here
    • This image cannot be deployed via TFTP as it is too large - some TFTP servers refuse to serve files lager than 32MB, and some TFTP clients have problems with that as well.
    • Also, even if you have a TFTP server/client combination that handles files larger than 32 MB, it will still be waaaay slower than the HTTP/FTP transfer.
    • Note that whoever manages to spoof this server name can deploy rogue images to your ThinClients. If this is a serious issue for you, consider using local storage media and the autoupdater instead.
    • It might be possible to use HTTPS with the fetch= command. This is untested.
  • Once your setup fulfills all the requirements listed above, go ahead and build the image using the scripts listed in Configuring the Build - make sure to choose export LBX2GO_IMAGETYPE='netboot' (this should be the default)

Setting up your own netbootable X2Go-TCE environment

Adding the X2Go-TCE files to your Boot and Web Server(s)

This is assuming you already have an existing, working PXE/TFTP and HTTP (with optional HTTPS) or FTP server setup.

Once you see the message “Build is done:”, go to the directory mentioned there, and copy x2go-tce-vmlinuz and x2go-tce-initrd.img to a suitable subdirectory under your TFTP root.

We suggest using ./x2go-tce.

To verify that both your installation in general and the newly copied files are reachable via TFTP, use a TFTP client - we suggest atftp - and perform these steps:
 cd $(mktemp -d)
 atftp your-tftp-server-ip-here
 tftp> get pxelinux.cfg/default
 tftp> get x2go-tce/x2go-tce-vmlinuz 
 tftp> get x2go-tce/x2go-tce-initrd.img 
 tftp> quit

Next, copy x2go-tce-filesystem.squashfs from the directory mentioned after “Build is done:” to a suitable subdirectory under your HTTP, HTTPS, or FTP root.

We suggest using ./x2go-tce.

To verify that both your installation in general and the newly copied file are reachable via HTTP, HTTPS, or FTP, use an HTTP/HTTPS/FTP client - we suggest wget - and perform these steps:
 cd $(mktemp -d)
wget -Y off http://your-http-server-ip-here/
wget -Y off http://your-http-server-ip-here/x2go-tce/x2go-tce-filesystem.squashfs

In case of an FTP URL, replace http with ftp in the example above. Same goes for https when trying to get that to work.

Note that you MUST use an IP address. X2Go-TCE WILL NOT WORK with a DNS name, even though this test here will accept IPs and DNS names alike. The only exception is when a template actually spells out that you should input a DNS name.

Adding the configuration files to your Boot Server

Again, this is assuming you already have an existing, working PXE/TFTP server setup.

  • change to the pxelinux.cfg directory in your tftproot.
  • create a file x2go-tce there, using the template below and adjusting it to your needs
  • read section Boot Parameters for X2Go-TCE to find out what changes to make and what to put where it says FURTHER-OPTIONS-GO-HERE
x2go-tce
DEFAULT x2go-tce
PROMPT 0
MENU TITLE Linux Boot Menu
MENU COLOR TITLE 1 #ffffff #000000 std
MENU COLOR SEL 0 #ffffff #444444 std
MENU COLOR TABMSG 0 #999933 #000000 std
MENU COLOR UNSEL 0 #aaaaaa

LABEL x2go-tce
TIMEOUT 50
MENU LABEL X2Go-TCE
KERNEL x2go-tce/vmlinuz
APPEND initrd=x2go-tce/initrd.img boot=live components noswap aufs rd.luks=0 rd.lvm=0 rd.md=0 rd.dm=0 kernel.sysrq=1 keep_bootcon sysrq_always_enabled rd.driver.pre=loop rd.noverifyssl rd.skipfsck rd.live.overlay.check rd.live.overlay.reset rd.live.ram log_buf_len=1M quickreboot consoleblank=0 kernel.sysrq=1 keep_bootcon sysrq_always_enabled rootwait=120 silent quiet splash lang=de vconsole.keymap=de keyboard-layouts=de locales=de_DE.UTF-8 hostname=localhost noroot nouser fetch=http://your-http-server-ip-here/x2go-tce/x2go-tce-filesystem.squashfs FURTHER-OPTIONS-GO-HERE

Required unless using the X2Go Session Broker: Adding the x2go-tce.sessions session configuration file to your HTTP or FTP Server

Again, this is assuming you already have an existing, working HTTP or FTP server setup.

  • run X2GoClient on any computer you like, and configure a session the same way it should appear on the ThinClient <note tip>when using a Windows client, run x2goclient.exe –portable, or it will store the session information in the registry, rather than in a “sessions” file.</note>
  • locate the “sessions” file you just created - it should be at ~/.x2goclient/sessions
  • copy it to x2go-tce.sessions
  • using an editor of your choice, edit x2go-tce.sessions so it contains only the sessions you want to appear on the ThinClient, and none that might have been created earlier.
  • log on to your HTTP or FTP server and change to the x2go-tce directory in your webroot/ftproot.
  • copy the x2go-tce.sessions file with your desired configuration to this directory.

Optional: Adding the x2go-tce.authorized_keys keyfile to your HTTP or FTP Server

Again, this is assuming you already have an existing, working HTTP or FTP server setup.

  • locate your current authorized_keys file - it should be at ~/.ssh/authorized_keys
  • copy it to x2go-tce.authorized_keys
  • using an editor of your choice, edit x2go-tce.authorized_keys so it contains only the keys you want to appear on the ThinClient, and none that might have been created for a different purpose.
  • log on to your HTTP or FTP server and change to the x2go-tce directory in your webroot/ftproot.
  • copy the x2go-tce.authorized_keys file with your desired configuration to this directory.
  • make sure the file is chmodded 644, not 600

Optional: Adding the x2go-tce.xorg.conf file to your HTTP or FTP Server

Again, this is assuming you already have an existing, working HTTP or FTP server setup.

  • copy the xorg.conf file from the working system to x2go-tce.xorg.conf - actually, to something that lets you tell which hardware it is made for, like x2go-tce-P4-whitebox-with-crappy-VGA.xorg.conf
  • log on to your HTTP or FTP server and change to the x2go-tce directory in your webroot/ftproot.
  • copy the x2go-tce.xorg.conf file (or whatever you named it) with your desired configuration to this directory.

Final Steps to boot a ThinClient

To boot your first X2Go-TCE ThinClient

Again, this is assuming you already have an existing, working PXE/TFTP server setup in place.

  • Determine the MAC address of your ThinClient. In the following example, we will assume it is AA-BB-CC-DD-EE-FF.
  • Change to the pxelinux.cfg directory in your tftproot.
  • create a symlink with the name 01-AA-BB-CC-DD-EE-FF (note the extra “01-” at the beginning) pointing to x2go-tce.
  • After that, your ThinClient should boot the X2Go-TCE image.

To make the X2Go-TCE image the default and only boot image

  • Change to the pxelinux.cfg directory in your tftproot.
  • run ls -lah default
  • Make a note where this symlink points to, if it is a symlink.
  • If it is not a symlink, but a regular file, rename it e.g. to default-before-x2go-tce
  • create a new symlink named default that points to x2go-tce

To create several configurations to accommodate varying hardware/use cases, but all booting the same basic image

  • Change to the pxelinux.cfg directory in your tftproot.
  • copy the file x2go-tce to an appropriate name, like x2go-tce-debug or x2go-tce-P4-whitebox-with-crappy-VGA
  • you can create as many such configuration files as you want, and edit them according to the use case
  • to make a particular client boot a particular configuration,
    • Determine the MAC address of your ThinClient. In the following example, we will assume it is AA-BB-CC-DD-EE-FF.
    • create a symlink with the name 01-AA-BB-CC-DD-EE-FF (note the extra “01-” at the beginning) pointing to x2go-tce-whatever-name-you-chose.
    • After that, your ThinClient should boot the X2Go-TCE image.
    • Note that it is possible to use partial matching, so a symlink starting with “01-AA-BB-CC” would match all ThinClients with a MAC address starting with “AA-BB-CC” and so on.
    • For further matching options (IP-based, for example), please consult the pxeboot documentation. In short, it should be possible (i.e. untested by us), but it a) requires you to assign static DHCP IPs and b) you need to translate the IP to its hexadecimal value and use that value as the symlink name, so e.g. 192.168.0.1 becomes C0A80001 → x2go-tce.

Booting from local storage media

This section explains how to create images for local storage media.

Basically, proceed as shown for netboot above, but set LBX2GO_IMAGETYPE to iso-hybrid (recommended) or iso. Do not select hdd or tar - even though we are creating a local storage media installation.

  1. On your local storage media, create the following folders: /boot/X2Go-live1, /boot/X2Go-live2, /boot/X2Go-live-download.
  2. If you have serious space constraints, you can limit yourself to /boot/X2Go-live1, but you will be unable to use the autoupdater then.
  3. Copy ./x2go-tce-vmlinuz, ./x2go-tce-initrd.img, and ./x2go-tce-squashfs-only.iso to /boot/X2Go-live1/ (and to /boot/X2Go-live2/, if present).

Installing a boot loader

The next step is to install a boot loader. Currently, there are three choices, GRUB-legacy, syslinux, and GRUB4DOS.

  • Use GRUB-legacy for ext* file systems.
  • Use syslinux when installing on FAT* file systems. Should work with ext* file systems as well (using extlinux), if you don't want GRUB-legacy.
  • Use GRUB4DOS when dealing with an NTFS file system (say, you're trying to turn an existing Windows XP installation into a ThinClient).
  • read section Boot Parameters for X2Go-TCE to find out what changes to make and what to put where it says FURTHER-OPTIONS-GO-HERE
Note that GRUB-legacy (and possibly GRUB4DOS as well) has a limit of 256 characters for /proc/cmdline. Current syslinux implementations double that value to 512 characters. So if you're seeing issues like X2Go-TCE hanging at boot when it comes to downloading config files, or certain parameters being ignored, when you specify a lot of and/or long parameters, you can either go ahead and shorten file names and paths (e.g. use “vml” instead of “x2go-tce-vmlinuz” and “http://host/” instead of “http://host.example.com/”, or switch to a different bootloader.

Installing GRUB-legacy

  • mount /dev/targetpartition to (mountpath)
  • create a folder (mountpath)/boot/grub
  • install grub-legacy into it:
    • apt-get -y install grub-legacy # note this will remove grub2 from your system if it is installed, but will not cause any change to your boot sequence
    • grub-install –recheck –root-directory=(mountpath) /dev/targetdevice # entire device, not partition
    • check, and, if required, edit the contents of (mountpath)/boot/grub/device.map
    • if you had to make changes, re-run grub-install –root-directory=(mountpath) /dev/targetdevice # entire device, not partition
    • optional: apt-get -y install grub2 # reinstall grub2 if that is what you were using before
    • create a boot loader configuration file using the following template:
menu.lst
# sample grub-legacy menu.lst for booting X2Go-TCE from local media
# Depending on your setup, this goes either into C:\menu.lst or C:\boot\grub\menu.lst, or /boot/grub/menu.lst.
# C:\menu.lst is recommended for NTFS, /boot/grub/menu.lst for ext*. 
# Make sure you do not have menu.lst files at both locations.

default 0

timeout         5
color cyan/blue white/blue
# This says "password" in md5
password --md5 $1$v4.0xYdG$32uzkKsup9c1RsHZlzfQs1

title           X2Go-live1
find            /boot/X2Go-live1/x2go-tce-vmlinuz
root
kernel          /boot/X2Go-live1/x2go-tce-vmlinuz boot=live components noswap aufs rd.luks=0 rd.lvm=0 rd.md=0 rd.dm=0 kernel.sysrq=1 keep_bootcon sysrq_always_enabled rd.driver.pre=loop rd.noverifyssl rd.skipfsck rd.live.overlay.check rd.live.overlay.reset rd.live.ram log_buf_len=1M quickreboot consoleblank=0 kernel.sysrq=1 keep_bootcon sysrq_always_enabled rootwait=120 lang=de vconsole.keymap=de keyboard-layouts=de locales=de_DE.UTF-8 hostname=localhost noroot nouser silent quiet splash findiso=/boot/X2Go-live1/x2go-tce-squashfs-only.iso FURTHER-OPTIONS-GO-HERE
initrd          /boot/X2Go-live1/x2go-tce-initrd.img

title           X2Go-live2
find            /boot/X2Go-live2/x2go-tce-vmlinuz
root
kernel          /boot/X2Go-live2/x2go-tce-vmlinuz boot=live components noswap aufs rd.luks=0 rd.lvm=0 rd.md=0 rd.dm=0 kernel.sysrq=1 keep_bootcon sysrq_always_enabled rd.driver.pre=loop rd.noverifyssl rd.skipfsck rd.live.overlay.check rd.live.overlay.reset rd.live.ram log_buf_len=1M quickreboot consoleblank=0 kernel.sysrq=1 keep_bootcon sysrq_always_enabled rootwait=120 lang=de vconsole.keymap=de keyboard-layouts=de locales=de_DE.UTF-8 hostname=localhost noroot nouser silent quiet splash findiso=/boot/X2Go-live2/x2go-tce-squashfs-only.iso FURTHER-OPTIONS-GO-HERE
initrd          /boot/X2Go-live2/x2go-tce-initrd.img

Installing syslinux

  • install syslinux and mbr: apt-get install -y syslinux mbr
  • run syslinux –install /dev/targetpartition # if that fails or media won't boot, try syslinux -s –install /dev/targetpartition
  • note that you have to mark /dev/targetpartition as “active” in the partition table. You can do that e.g. by calling sfdisk -A number-of-target-partition /dev/targetdevice
  • if your system doesn't boot like that, it might be due to an empty Master Boot Record. You can use install-mbr /dev/targetdisk to fix this.
  • for syslinux, use these three files as templates:
syslinux.cfg
menu title X2Go-TCE
# This says "password" in md5
menu master passwd $1$v4.0xYdG$32uzkKsup9c1RsHZlzfQs1
UI menu.c32
default X2Go-live1
prompt 0
timeout 50
include X2Go-live1.cfg
include X2Go-live2.cfg
X2Go-live1.cfg
label X2Go-live1
        menu label X2Go-Live^1
        menu default
        linux /boot/X2Go-live1/x2go-tce-vmlinuz
        initrd /boot/X2Go-live1/x2go-tce-initrd.img
        append boot=live components noswap aufs rd.luks=0 rd.lvm=0 rd.md=0 rd.dm=0 kernel.sysrq=1 keep_bootcon sysrq_always_enabled rd.driver.pre=loop rd.noverifyssl rd.skipfsck rd.live.overlay.check rd.live.overlay.reset rd.live.ram log_buf_len=1M quickreboot consoleblank=0 kernel.sysrq=1 keep_bootcon sysrq_always_enabled rootwait=120 lang=de vconsole.keymap=de keyboard-layouts=de locales=de_DE.UTF-8 hostname=localhost noroot nouser silent quiet splash findiso=/boot/X2Go-live1/x2go-tce-squashfs-only.iso FURTHER-OPTIONS-GO-HERE
X2Go-live2.cfg
label X2Go-live2
        menu label X2Go-Live^2
        menu default
        linux /boot/X2Go-live2/x2go-tce-vmlinuz
        initrd /boot/X2Go-live2/x2go-tce-initrd.img
        append boot=live components noswap aufs rd.luks=0 rd.lvm=0 rd.md=0 rd.dm=0 kernel.sysrq=1 keep_bootcon sysrq_always_enabled rd.driver.pre=loop rd.noverifyssl rd.skipfsck rd.live.overlay.check rd.live.overlay.reset rd.live.ram log_buf_len=1M quickreboot consoleblank=0 kernel.sysrq=1 keep_bootcon sysrq_always_enabled rootwait=120 lang=de vconsole.keymap=de keyboard-layouts=de locales=de_DE.UTF-8 hostname=localhost noroot nouser silent quiet splash findiso=/boot/X2Go-live2/x2go-tce-squashfs-only.iso FURTHER-OPTIONS-GO-HERE

Installing GRUB4DOS

Installing GRUB4DOS allows you to keep the original Windows bootloader installed. The method below also allows you to write-mount the NTFS file system and thus to deploy updates using the autoupdater. This is done by chainloading GRUB4DOS from the native Microsoft Windows Bootloader

  • copy GRLDR and GRLDR.mbr from the GRUB4DOS temporary directory into C:\
  • make the appropriate changes to activate the changes:
    • Note: These steps all require Administrator privileges.
    • For Windows XP, you need to edit C:\boot.ini
      1. attrib -r -h -s C:\boot.ini
      2. Edit C:\boot.ini and add an entry C:\grldr=“Start ThinClient” somewhere below the section [operating systems]
      3. To make booting in ThinClient mode the default, in section [boot loader], change the line starting with default to default=C:\grldr
      4. attrib +r +h +s C:\boot.ini
    • For Windows Vista and newer, run this script:
insertgrub.cmd
@echo off
setlocal
set BCDEDIT=%SYSTEM%\bcdedit.exe
if not exist %BCDEDIT% exit 1
for /f "tokens=3" %%A in ('%BCDEDIT% /create /d "PXE boot" /application bootsector') do set guid=%%A
%BCDEDIT% /set %guid% device partition=%SystemDrive%
%BCDEDIT% /set %guid% path \grldr.mbr

REM you can use /addfirst instead, if you want
%BCDEDIT% /displayorder %guid% /addlast

REM this sets a 5 second timeout until the default entry is booted
REM feel free to adjust to your needs, but NEVER set it to 0 or 1
REM in combination with using /default below unless you don't ever
REM intend to boot back into Windows again.
%BCDEDIT% /timeout 5

REM "bootsequence" means only the single, next reboot will default to this
%BCDEDIT% /bootsequence %guid% /addfirst

REM alternatively, you can uncomment this and make the ThinClient 
REM boot option the default boot option
REM %BCDEDIT% /default %guid%

endlocal
  • create the boot loader configuration file(s):
    • you can use the template for GRUB-Legacy from above, but in that case, you cannot use the autoupdate feature, as the boot partition will be locked in read-only mode.
    • to be able to use the autoupdater, use the template below
    • you must replace the xxx'es in the ntfs-uuid= parameter with the Volume Serial Number listed in the output of vol c: (Windows command) or with the UUID from the output of blkid /dev/targetpartition
menu.lst
# sample grub-legacy menu.lst for booting X2Go-TCE from NTFS-formatted local media
# Depending on your setup, this goes either into C:\menu.lst or C:\boot\grub\menu.lst.
# C:\menu.lst is recommended. 
# Make sure you do not have menu.lst files at both locations.

default 0

timeout         5
color cyan/blue white/blue
# This says "password" in md5
password --md5 $1$v4.0xYdG$32uzkKsup9c1RsHZlzfQs1

title           X2Go-live1
find            /boot/X2Go-live1/x2go-tce-vmlinuz
root
kernel          /boot/X2Go-live1/x2go-tce-vmlinuz boot=live components noswap aufs rd.luks=0 rd.lvm=0 rd.md=0 rd.dm=0 kernel.sysrq=1 keep_bootcon sysrq_always_enabled rd.driver.pre=loop rd.noverifyssl rd.skipfsck rd.live.overlay.check rd.live.overlay.reset rd.live.ram log_buf_len=1M quickreboot consoleblank=0 kernel.sysrq=1 keep_bootcon sysrq_always_enabled rootwait=120 lang=de vconsole.keymap=de keyboard-layouts=de locales=de_DE.UTF-8 hostname=localhost noroot nouser silent quiet splash findiso=/boot/X2Go-live1/x2go-tce-squashfs-only.iso toram ntfs-uuid=xxxxxxxxxxxxx FURTHER-OPTIONS-GO-HERE
initrd          /boot/X2Go-live1/x2go-tce-initrd.img

title           X2Go-live2
find            /boot/X2Go-live2/x2go-tce-vmlinuz
root
kernel          /boot/X2Go-live2/x2go-tce-vmlinuz boot=live components noswap aufs rd.luks=0 rd.lvm=0 rd.md=0 rd.dm=0 kernel.sysrq=1 keep_bootcon sysrq_always_enabled rd.driver.pre=loop rd.noverifyssl rd.skipfsck rd.live.overlay.check rd.live.overlay.reset rd.live.ram log_buf_len=1M quickreboot consoleblank=0 kernel.sysrq=1 keep_bootcon sysrq_always_enabled rootwait=120 lang=de vconsole.keymap=de keyboard-layouts=de locales=de_DE.UTF-8 hostname=localhost noroot nouser silent quiet splash findiso=/boot/X2Go-live2/x2go-tce-squashfs-only.iso toram ntfs-uuid=xxxxxxxxxxxxx FURTHER-OPTIONS-GO-HERE
initrd          /boot/X2Go-live2/x2go-tce-initrd.img

Booting from CD/DVD/USB

  1. set the variables as shown in Configuring the Build
  2. after that, continue with export LBX2GO_IMAGETYPE=“iso-hybrid” (recommended) or export LBX2GO_IMAGETYPE=“iso”.
  3. see Boot Parameters for X2Go-TCE for a description of possible options, make your choices, add them where it says FURTHER-OPTIONS-GO-HERE and follow up with
    export LBX2GO_DEFAULTS+=" --bootappend-live boot=live components noswap aufs rd.luks=0 rd.lvm=0 rd.md=0 rd.dm=0 kernel.sysrq=1 keep_bootcon sysrq_always_enabled rd.driver.pre=loop rd.noverifyssl rd.skipfsck rd.live.overlay.check rd.live.overlay.reset rd.live.ram log_buf_len=1M quickreboot consoleblank=0 kernel.sysrq=1 keep_bootcon sysrq_always_enabled rootwait=120 silent quiet splash lang=de vconsole.keymap=de keyboard-layouts=de locales=de_DE.UTF-8 hostname=localhost noroot nouser live-media-path=live FURTHER-OPTIONS-GO-HERE
  4. after that, you can Start the Build.
  5. if you actually intend to write the image to CD/DVD or USB media, the only file you need is located at ./original-x2go-tce-live-image-i386.hybrid.iso after running the build script.
  6. if the image fails to boot, check the file system - there should be a folder live containing a file filesystem.squashfs. Adjust the value of live-media-path= accordingly.

Burning to CD/DVD

Use xorriso -as cdrecord -v dev=/dev/your-writer-device -dao ./original-x2go-tce-live-image-i386.hybrid.iso or whatever cd burning software you like. See https://wiki.debian.org/BurnCd for some additional suggestions.

Writing to USB media

When using iso-hybrid, this file can be dd'ed straight to USB media, no need to unpack, format, fiddle with a boot loader, etc.

So just do dd if=./original-x2go-tce-live-image-i386.hybrid.iso of=/dev/targetdevice and wait until it finishes.

Also, when using iso-hybrid and USB media, there are a few “cheats” to reclaim unused space on the USB media, and to turn it into a solution that allows you to run X2GoClient in portable mode on Windows, and boot it as X2Go-TCE, with a shared configuration file.

Boot Parameters for X2Go-TCE

These are always required for security reasons, unless you are working on a debug image:
  • noroot - do not allow the local user account on the ThinClient (named “user”) to become root, e.g. using sudo Always set this unless you are debugging an image and need to log in locally!
  • nouser - do not allow the local user account on the ThinClient (named “user”) to log in at the console or remotely (using password “live”) Always set this unless you are debugging an image and need to log in locally!

Options already present in the templates that you may/should change to your needs

  • options ending in =de and =de_DE.UTF-8 should be set to match your desired country/locale setting
To have different hostnames for each thin client:
  • assign DNS names for your thin clients
  • set your DHCP server to reply to “request host-name” requests from dhclient
  • use hostname=localhost as shown above.

If you remove hostname=localhost entirely, all thin clients will share the hostname debian, which is the Debian-Live default host name. Similarly, if you set hostname=someothervalue, all thin clients booting this configuration will share the hostname someothervalue.

What options are available under FURTHER-OPTIONS-GO-HERE?

  • Where it says FURTHER-OPTIONS-GO-HERE, you can (must!) add one or more of the options explained below. All options are separated from the next option using a single blank (space bar), just like the options before that placeholder. DO NOT use newlines. All “APPEND” options must be on one and the same line.
  • Options containing “tftp|rsync|https|http|ftp://your-http-server-ip-here” should be replaced with the proper HTTP, HTTPS, FTP, or, where mentioned as an alternative, TFTP or rsync URL for your server. HTTPS is always preferred for security reasons. Be sure to use only the IP, not a DNS name.
  • Options containing “tftp|rsync|https|http|ftp://your-http-server-ip-or-dns-here” should be replaced with the proper HTTP, HTTPS, FTP, or, where mentioned as an alternative, TFTP or rsync URL for your server. HTTPS is always preferred for security reasons. IP or DNS name may be used.

These two are mutually exclusive, i.e. never put both of them in the same config

  • sessionsurl=https|http|ftp://your-http-server-ip-or-dns-here/x2go-tce/x2go-tce.sessions - use this to specify a sessions file. You need this unless you are using a session broker. See below for how to add this file to your HTTP, HTTPS, or FTP server. Note that whoever manages to spoof the server name can inject rogue session config files into your ThinClients. To mitigate this risk, use HTTPS, where the attacker would have to spoof both server name and matching certificate.
  • broker-url=ssh://your-broker-address-here - this allows you to specify an X2Go Session Broker instead of a sessions file (not limited to an ssh-based broker, works with an http-based broker as well)

These are entirely optional

  • xorg-resolution=HRESxVRES - will force the horizontal resolution to HRES and the vertical resolution to VRES, e.g. xorg-resolution=1280×1024, useful if autodetection for the correct screen size fails, but you do get as far as seeing the X2Go GUI
  • xorgconfurl=tftp|http|https|ftp://your-http-server-ip-or-dns-here/x2go-tce/x2go-tce.xorg.conf - when a client outright refuses to boot into the graphical X2Go login screen, but gets stuck at the console or a black screen instead, yet you can get the GUI to work using a regular Linux on the same hardware, you can disable the X Server's autodetection and force it to use the xorg.conf specified here. Note that you should use a more descriptive name for the file, as described below. Also note that whoever manages to spoof the server name can inject rogue xorg config files into your ThinClients. To mitigate this risk, use HTTPS, where the attacker would have to spoof both server name and matching certificate.
  • pubkey=tftp|http|https|ftp://your-http-server-ip-or-dns-here/x2go-tce/x2go-tce.authorized_keys - Allows you to add an ssh public key file to the ThinClient, so your administrators can log in remotely using SSH. Note that this file needs to be chmodded 644, not 600, on the web server. Attention: Whoever manages to spoof this server name will have root access to your ThinClients. Using HTTPS will mitigate this - an attacker would not only have to spoof the server name, but also the matching certificate.
  • xinerama=left-of|right-of|above|below|same-as - Allows you to specify how multiple screens are handled (same-as clones the primary screen to all secondary screens, the other commands will cascade and thus expand the screen). Note that the current implementation will enforce “same-as” if it detects a touch screen driver (wacom) and no other pointing device. This is so you won't get stuck being unable to log off, for example, due to your touch device being limited to one screen.
  • ldap=ldap.example.com:389:cn=cngoeshere,dc=example,dc=com - this allows you to specify an LDAP server to connect to - note that this is not needed for LDAP-based authentication, only when you intend to store entire session profiles in LDAP. You should really consider using the X2Go Session Broker instead.
  • ldap1=ldap-backupserver-1.example.com:389 - this allows you to specify the first of up to two LDAP backup servers when using LDAP authentication
  • ldap2=ldap-backupserver-2.example.com:389 - this allows you to specify the second of up to two LDAP backup servers when using LDAP authentication
  • blank=n|n:n:n - Will disable (blank=0) or set screensaver timeout. Use blank=n:n:n to set DPMS Standby/Suspend/Off values. Standby value equals screensaver timeout value. All values are given in seconds.
  • nodpms - Will not touch DPMS settings at all (by default, blank=0 does both xset s off and xset -dpms). Use this along with blank=n if you do want to blank the screen, but your screen is confused by DPMS settings.
  • tcpprint - Will allow you to use local LPT/USB printers like “dumb” network printers (listening to port 9100 and above). Requires MAC→IP mapping in DHCP server (and optionally, DNS→IP mapping), or static IPs - else your print jobs will end up on random devices. This setup is preferred over the X2GoClient's built-in printing for locally attached printers if X2GoServer and ThinClients are on the same network. It is not recommended when your X2Go connection goes across the internet or when the ThinClient is actually a laptop roaming between different networks. Attention: When used without tcpprintonlyfrom (see below), this means anyone that can reach your thin client via e.g. ping can also send print jobs to it!
  • tcpprintonlyfrom=x.x.x.x - Will allow you to specify which IP address may connect to Port 9100 and above for printing to a locally attached LPT/USB printer. This should be the IP of your CUPS server or whatever print server system you use. Understands the same syntax as xinetd's only_from.

These are only intended to be used with TCE images stored on local media

  • updateurl=rsync|https|http|ftp://your-http-server-ip-or-dns-here/path-to-update-files - Will allow you to update an image in the background when using local storage instead of PXE. Download task will start at a randomized interval to avoid unintentional dDOSing of the update server/network infrastructure. The updater will even work when using NTFS for local storage, but only if the toram boot option is used. Regardless of NTFS or not, the updater requires three directories: /boot/X2Go-live1, /boot/X2Go-live2, /boot/X2Go-live-download Attention: Whoever manages to spoof the server name can deploy rogue images to your ThinClients. Even though it is slower, using an HTTPS web server is the safer way of doing this. Be sure that your web server delivers a last-modified header for all files.
  • updatesleep=nnnnn - Will allow you to specify the upper limit (in seconds) of the update timer's randomizer. Allowed range for upper limit: 240-32767. Will default to 900 if unset or set to an out-of-range value. Lower limit is fixed at 120 seconds.
  • bwlimit=nnn - Will allow you to specify a bandwidth limit (valid values: 1-100) in percent for the backgrounded update task.
  • ntfs-uuid= - Will be required for updating images stored on NTFS filesystems. Full UUID as shown under /dev/disk/by-uuid/ is preferred, but can work with the volume serial number shown in the output of “vol c:” as well.

Troubleshooting a booted X2Go-TCE image

You can see the X2Go login screen, but the screen size (resolution) is wrong

Determine the correct resolution for your screen and set boot parameter xorg-resolution=HRESxVRES accordingly, e.g. to xorg-resolution=1280×1024

The screen is entirely black (though you might notice an illuminated backlight in case of a TFT)

If the screen is entirely black, try pressing [Ctrl]+[Alt]+[F1] and see if that takes you to the text login screen.

You can see a text login screen with grey/white, green, and possibly red letters against a black background

If you end up at the text login, this means the X Server's autodetection failed. There's not much you can do from inside X2Go-TCE at this point. Make a note of the MAC address (the GREEN text), shut down the ThinClient and try to boot a different Linux distribution on it. Try, for example, KNOPPIX Live Linux, other Distribution's Live Images (a recent Fedora or Arch, maybe?).

If you can get X running in one of these, proceed as follows:

In the running Linux where you have a working X Server on that particular hardware:

  • change to a command shell
  • try to run Xorg :$(($(ps -C Xorg -o args= | awk ' $2 ~ /^:[0-9]/ { print $2 }' | tr -d ':' | sort -n)+1)) -configure
  • if that fails, stop the currently running X server, then run Xorg -configure
  • this should output ~/xorg.conf.new, which could then be saved somewhere else (LAN share, USB media, …).
  • once saved, shut down the ThinClient again.

Next steps:

  • rename the saved xorg.conf.new to x2go-tce.xorg.conf.name-of-your-stubborn-hardware and place it in the x2go-tce directory of the tftp|http|https|ftp server you use to deploy your images.
  • When using netbooting, do the following on your PXE/TFTP Server
    • create a separate configuration file “name-of-your-stubborn-hardware” for this hardware, based on the default file,
    • create a symlink matching “01-”, followed by the first three out of the six bytes of your hardware address, each separated by “-” (say, 01-AA-BB-CC when the full MAC was shown as AA:BB:CC:DD:EE:FF), that points to the file “name-of-your-stubborn-hardware”.
  • In your boot configuration file (either “name-of-your-stubborn-hardware”, when using netbooting, or menu.lst, when using local or USB storage media and grub-legacy, or X2Go-live1.cfg/X2Go-live2.cfg, when using local or USB storage media and syslinux), add the boot parameter xorgconfurl=tftp|http|https|ftp://your-http-server-ip-here/x2go-tce/x2go-tce.xorg.conf.name-of-your-stubborn-hardware

Support Tools available in X2Go-TCE

Remote Access to the ThinClient's local display (before any connection is made)

X2Go-TCE comes with x11vnc installed. If you want to see what's on the ThinClient's X11 screen, before a server connection has been established, proceed as follows:

  • On Linux/macOS/Unix:
    1. spawn a VNC listening client, like so: xvncviewer -listen 5500
    2. run ssh -R 5500:localhost:5500 root@thinclient 'x11vnc -display :0 -rfbport 0 -coe localhost'
  • On Windows:
    1. Start a VNC listening client, for example vncclient.exe -listen 5500
    2. Start PuTTY, connect to root@thinclient
    3. Select Connections/SSH/Tunnels in PuTTY
    4. Enter Source Port 5500, Destination localhost:5500, Remote, Auto, and, very important, hit Add before you hit Apply, or your changes will not be saved
    5. run x11vnc -display :0 -rfbport 0 -coe localhost in the PuTTY window

To see what a user is doing once a connection has been established, connect to the X2GoServer yourself and use X2Go's built-in Desktop Sharing (session shadowing). Install package x2godesktopsharing on the server, if you haven't done so already - this will deliver way better performance. See below for more.

Remote Access to the ThinClient's running X2Go Session

Please see the Desktop Sharing (session shadowing) HowTo for details.

Determining the ThinClient's IP and/or MAC when there is no network connection

When you are unable to connect to the ThinClient, you might want to ascertain its MAC and/or IP address(es), to make sure you and the user you are trying to support are talking about the same machine. Tell the user to press [Ctrl]+[Alt]+[F1] and to read out

  • the GREEN text if you want to know the MAC address(es)
  • the RED text if you want to know the IP address(es) - if there is no red text, it means that the client was unable to acquire a DHCP lease. Check cabling.

To return to the login screen, have the user press [Ctrl]+[Alt]+[F7] ([Alt]+[F7] should work, too), or, once you've successfully logged in over the network, issue the chvt 7 command.

Checking the ThinClient's local printer setup (when using the ''tcpprint'' boot parameter)

There are several ways to check whether a ThinClient has detected any local printers:

  • Assuming you have remote access to the ThinClient, run ls -lah /etc/xinetd.d/jetdirect* and examine the files listed there.
  • When connected remotely, you can also look at the messages printed during the local printer setup phase, by running cat /dev/vcs9 (you might have to pipe it through less to see the entire screen).
  • If you do not have remote access, tell the user to press [Ctrl]+[Alt]+[F9] and to read out what's on the screen. To return to the login screen, have the user press [Ctrl]+[Alt]+[F7] ([Alt]+[F7] should work, too), or, once you've successfully logged in over the network, issue the chvt 7 command.

Checking the ThinClient's update status (when using local storage)

There are several ways to check a ThinClient's update status:

  • Assuming you have remote access to the ThinClient, look at the messages printed during the update phase, by running cat /dev/vcs10 (you might have to pipe it through less to see the entire screen) when connected remotely
  • If you do not have remote access, tell the user to press [Ctrl]+[Alt]+[F10] and to read out what's on the screen, preferably starting with the bottom line and continuing upward. To return to the login screen, have the user press [Ctrl]+[Alt]+[F7] ([Alt]+[F7] should work, too), or, once you've successfully logged in over the network, issue the chvt 7 command.

List of open ToDos/FIXMEs for this page

FIXME This page is missing a section/subpage that explains how to use the content of the tar file located in the build directory if no PXE/TFTP/HTTP server is present yet.

Basically, debian-live/live/filesystem.squashfs becomes (webroot)/x2go-tce/x2go-tce-filesystem.squashfs and everything from tftpboot/ goes into the TFTP root directory. After that, one should proceed as described above regarding creation of files and symlinks.

Sample contents of live-image-i386.netboot.tar:

drwxr-xr-x root/root         0 2016-12-15 23:46 debian-live/
drwxr-xr-x root/root         0 2016-12-15 23:54 debian-live/live/
-rw-r--r-- root/root 271536128 2016-12-15 23:50 debian-live/live/filesystem.squashfs
-rw-r--r-- root/root     11579 2016-12-15 23:52 debian-live/live/filesystem.packages
-rw-r--r-- root/root        74 2016-12-15 23:52 debian-live/live/filesystem.packages-remove
drwxr-xr-x root/root         0 2016-12-15 23:54 tftpboot/
drwxr-xr-x root/root         0 2016-12-15 23:54 tftpboot/live/
-rw-r--r-- root/root  31942749 2016-12-15 23:52 tftpboot/live/initrd.img
-rw-r--r-- root/root   2831760 2016-12-15 23:52 tftpboot/live/vmlinuz
drwxr-xr-x root/root         0 2015-04-28 14:01 tftpboot/pxelinux.cfg/
-rw-r--r-- root/root        57 2014-10-25 14:21 tftpboot/pxelinux.cfg/default
-rw-r--r-- root/root       351 2016-12-15 23:54 tftpboot/live.cfg
-rw-r--r-- root/root    116624 2015-08-19 15:17 tftpboot/ldlinux.c32
-rw-r--r-- root/root       270 2016-12-15 23:54 tftpboot/menu.cfg
-rw-r--r-- root/root     26188 2015-08-19 15:17 tftpboot/vesamenu.c32
-rw-r--r-- root/root       268 2016-12-15 23:54 tftpboot/install.cfg
-rw-r--r-- root/root       508 2016-12-15 23:54 tftpboot/stdmenu.cfg
-rw-r--r-- root/root     34739 2016-12-15 23:54 tftpboot/splash.png
-rw-r--r-- root/root     23480 2015-08-19 15:17 tftpboot/libutil.c32
-rw-r--r-- root/root       153 2016-12-15 23:54 tftpboot/advanced.cfg
-rw-r--r-- root/root    182552 2015-08-19 15:17 tftpboot/libcom32.c32
-rw-r--r-- root/root     42988 2015-08-19 15:17 tftpboot/pxelinux.0
-rw-r--r-- root/root    164096 2015-08-19 15:17 tftpboot/hdt.c32

FIXME This page is missing a section/subpage that explains how to speed up the netboot process using iPXE.

Basically:

apt-get install ipxe
cd /your-tftp-root
mkdir -p {bios,uefi}
ln -s /usr/lib/ipxe/undionly.kpxe ./bios/
ln -s /boot/ipxe.efi ./uefi/
FQDN=DNS-name-of-your-server-here
IP_OF_FQDN=`dig $FQDN +short`
cat <<EOF>x2go-tce-ipxe
#!ipxe
dhcp
kernel http://$FQDN/x2go-tce-vmlinuz EVERYTHING-FROM-THE-LINE-STARTING-WITH-APPEND-IN-THE-X2GO-TCE-SAMPLE-FILE-ABOVE
initrd http://$FQDN/x2go-tce-initrd.img
boot
EOF

After that, create a symlink/symlinks that point(s) from “default” or a part of the MAC or the entire MAC, or the UUID, or the hex-encoded IP to x2go-tce-ipxe.

Then add this to your dhcpd.conf

   if substring ( option vendor-class-identifier , 19,1 ) = "0" {
           filename "bios/undionly.kpxe";
   }
   else if substring ( option vendor-class-identifier , 19,1 ) = "7" {
           filename "uefi/ipxe.efi";
   }
   else {  
           log (info, concat ( "Unhandled vendor class Arch: ", substring ( option vendor-class-identifier , 19,1 )));
   }
   if exists user-class and option user-class = "iPXE" {
	set hwmac = concat (
	suffix (concat ("0", binary-to-ascii (16, 8, "", substring(hardware,1,1))),2), ":",
	suffix (concat ("0", binary-to-ascii (16, 8, "", substring(hardware,2,1))),2), ":",
	suffix (concat ("0", binary-to-ascii (16, 8, "", substring(hardware,3,1))),2), ":",
	suffix (concat ("0", binary-to-ascii (16, 8, "", substring(hardware,4,1))),2), ":",
	suffix (concat ("0", binary-to-ascii (16, 8, "", substring(hardware,5,1))),2), ":",
	suffix (concat ("0", binary-to-ascii (16, 8, "", substring(hardware,6,1))),2)
	);

      filename = concat( "http://DNS-name-of-your-server-here/", hwmac );
   }

FIXME Document how to add second partition to USB media after dd'ing the iso-hybrid image, and how to add X2GoClient-Portable to it.

  • The catch is that on USB media, Windows will only see the partition with the partition number 1, even if there is more than 1 partition.
  • However, it doesn't care whether the partition bearing the number 1 is actually the first partition. It will happily display the contents of the second partition as long as it bears the number 1.
  • So, one has to change the partition number of the dd'ed image to 2, then create a new partition in the remaining space and assign it the number 1 and a partition type of FAT (NTFS *might* work, but is untested.)
  • After that, partition “number 1” - actually the second partition on the USB media - can be formatted.
  • Once formatted, one can install X2GoClient for Windows on it, and add a short batch script or similar to run it in portable mode (x2goclient.exe –portable –session-conf=sessions).
  • Stefan has written a script to automate this as good as possible, but it is still too fragile to release (fixed paths, many assumptions, no error checking = potential for serious breakage including data loss).

FIXME Document that using updateurl along with an rsync://FQDN/x2go-tce URL is the most efficient way to deploy updates. Note that the syntax is rsync://FQDN/x2go-tce, NOT rsync://FQDN::x2go-tce.

  • On a stock Debian system with rsync installed, this needs RSYNC_ENABLE=true in /etc/default/rsync as well as an additional configuration file:
/etc/rsyncd.conf
lock file = /var/run/rsync.lock
log file = /var/log/rsyncd.log
pid file = /var/run/rsyncd.pid

[x2go-tce]
    path = /var/www/x2go-tce
    # change this to the path where you intend to keep the images
    comment = X2Go TCE files
    uid = root
    gid = root
    read only = yes
    list = yes
    hosts allow = 192.168.0.0/255.255.0.0
    # change this to your local subnet(s)
  • after you have prepared all this, execute service rsync start
  • Note that whoever manages to spoof the server name can deploy rogue images to your ThinClients. Even though it is slower, using an HTTPS web server is the safer way of doing this. Be sure that your web server delivers a last-modified header for all files.

FIXME Some of the optional steps above could be moved to a separate subpage to reduce clutter.

FIXME The steps for the build process could probably streamlined into an x2go-tcebuilder.deb Debian package

Ideas:

  • instead of the “exports” stuff, use a config file e.g. under /etc/x2go/x2go-tcebuilder/config and source its contents
  • instead of copy-pasting the build commands, turn most of it into a script as /usr/bin/x2go-tcebuilder or something (the remaining config parts in the copy-paste block would have to be moved into the config file)
  • our config would be used as suggestion by linking to it; a user could create their own by replacing the link with a regular file (similar to how /etc/x2go/applications works)
  • our additional live-scripts would be shipped inside the package and similar to how apache does it with sites-available and sites-active - not pulling in content from git each time
    • /etc/x2go/x2go-tcebuilder/scripts-active (dir with symlinks to all active scripts)
    • /etc/x2go/x2go-tcebuilder/scripts-available (dir with symlinks to our templates and with regular user-created files)
    • /usr/share/x2go-tcebuilder/template-scripts (scripts we ship, with a big fat header that they should not be changed, but copied)
  • store the results somewhere under /var/lib/x2go-tcebuilder/ or whatever the proper place according to FHS and Debian would be
  • turning it into a package would mean we could add dependencies as well, so the manual apt-get install would not be neccessary
  • additional scripts could be added that work “automagically” if there's no PXE/TFTP/HTTP/FTP server yet - maybe in a separate package x2go-tce-setup-aids.deb which then has dependencies on atftpd and apache|lighttpd, …

FIXME To avoid re-generating SSH Server keys on each ThinClient on every boot, they could be stored

  • in a file on a HTTP(S)/FTP/RSYNC server
  • on local storage (/etc/ssh)
  • a script 1155-openssh-readsshserverkeys would have to inject them before the server starts Tricky parts:
    • reading to local media means you need a way to determine where to read them from (in case of “toram”, look for ntfs-uuid and findiso path)
    • reading from a remote server means you should use https, rsync, and/or some kind of signature check
  • a script 1165-openssh-writesshserverkeys would have to save them to local media/upload them after initial generation. Tricky parts:
    • saving to local media means you need a way to determine where to save them (in case of “toram”, look for ntfs-uuid and findiso path)
    • saving to a remote server means you need some kind of login credentials that could be abused

FIXME To be checked: Does the live-config “builtin” command live-config.nottyautologin do the same as our nouser command? If yes, nouser could be removed. Note that live-config.nottyautologin might mean “there's a login prompt, but you just need to enter username user and password live to login” - this is not what we want. We need a solution to entirely block user logons.

FIXME It would be cool if there was some kind of autodetection for SSH private keys, on local storage media and/or on USB media. For USB media, this may require adding an automounter.

  • Stefan once wrote a script 2500-x2go-keychange for this, but it only handles local storage media, also, it needs to be adapted to the current TCE.
  • 1150-openssh-readsshprivatekeys or 1150-x2go-readsshprivatekeys would probably be the proper names
  • Maybe it would be better to split the process into 2 scripts, one that fetches the keys from local storage/USB media, and one that patches the sessions file
  • 2800-x2go-thinclientconfig would also have to be changed so it uses the keyfile(s) when in broker mode (–broker-ssh-key)
  • https://packages.debian.org/jessie/usbmount might come in handy - needs to be configured to mount everything read-only
  • udev can be used to trigger an action when a block device gets plugged in or plugged out: /lib/udev/rules.d/80-do-something.rules SUBSYSTEM==“block”, RUN+=“/usr/bin/some-command”
  • all keys found on “real” (non-USB) disks that weren't already mounted should be copied to the ramdisk, mimicking the directory structure, and the device should be umounted immediately afterwards (so we don't interfere with the update script when running from NTFS)
  • once a key has been selected, it should be copied to /home/user/.ssh/id_[d|r]sa, and all other in-memory copies of keys should be wiped
  • directory scan
    • scan USB devices first
    • scan already mounted block devices belonging to fixed disks next (parse output of df or /proc/mounts)
    • then start ro-mounting remaining partitions
    • scan for .ssh and ssh folders in /, /home/*/ and /*/ (in case /home was a separate mount point), but no subdirectories underneath them
    • check every file using the file command - output ends e.g. in PEM RSA private key
    • should we abort on first match?
  • how do we treat multiple keys?
    • no keys on USB and exactly one key on disk → use key
    • exactly one key on USB → takes precedence over key/keys found on disk? Or present chooser based on gxmessage?
    • multiple keys → Present chooser based on gxmessage?
  • problem with gxmessage as chooser is that it can only display 6 buttons on 640×480 (Which we should assume as minimum screen size)
    • 4 key choices, back, next?

FIXME a boot parameter to specify a session name would be neat (to pass –session=foo to x2goclient)

FIXME 2200-xserver-xorg-getxorgconf should be taught to understand file:// URLs.

doc/howto/tce.1500676704.txt.gz · Last modified: 2017/07/21 22:38 by stefanbaur