xrdp

There are quite a lot of ways to get a remote graphical desktop when connecting to a unix system. X windows itself has always been a network based protocol, so if you had an X terminal or a PC running an X server, or even another unix system, you could always connect in that way. However, in more modern times with locked down Windows desktops in corporations, VNC has become very popular. Since something like the tightvnc client is just a standalone executable (and doesnt require installation), it’s often the simplest way of getting a graphical desktop going from a Windows PC. Another advantage is that VNC just uses a single tcp port connection, so it’s often a simple port forward and you can connect.

I’ve used VNC for years, and it is indeed handy, but it’s never been a speed demon. Sure there are various compressions and encodings you can choose, but it’s never that great (however I have discovered tigervnc in the course of researching this article, and it does look very promising). I often end up running vnc in bgr233 (8 bit) mode in order to make the desktop more responsive, but at the expense of screwing up most of the colours on the screen. Of course, if you look at other remote screen technologies they tend to be a lot better. Windows terminal server (RDP) client access always seems quite fluid to me. Citrix always seems pretty good too, NoMachine is very good, but I always find it difficult to set up. The Sunray protocol is very good too.

So recently, I started looking at xrdp. It’s been around for ages, and almost looks like a dead project at times … but if you look closely at the mailing list … it is still ticking over. I always thought it was a RDP server for linux. Well it is sort of. Regardless of what it is, it provides you with a very responsive remote desktop experience.

So xrdp seems to do a few things. The main uses are as an authentication gateway to VNC or other RDP server. So if you run xrdp on your system it starts listening on port 3389 like a normal RDP server. You can connect to it with rdesktop or the Windows terminal services client. Basically you see a login screen. There’s a dropdown (yep the square grey box is a dropdown) that allows you to select different connection profiles. You define these yourself in /etc/xrdp/xrdp.ini. You always get a few examples in this file but they’re never really explained anywhere.

All the examples have a [xrdp] header. I’m not sure if they have to be [xrdp1], [xrdp2] etc. Below is an example of a profile that connects to a VNC server running on :1 (port 5901). name is what you see in the drop down. lib = libvnc.so means that you want xrdp to connect to a VNC server and then convert it back and forth between VNC and RDP. You need to start up your VNC server before hand though. You may think “Why not just use a VNC viewer and connect to the VNC server directly?”. Responsiveness. I find that accessing a typical linux desktop via this RDP to VNC method is actually a fair bit better than just connecting via VNC (and this is just on a local LAN). The other params are reasonably obvious. username=na means to not prompt for a username. password, ip and port are reasonably obvious. If they are set to ‘ask’ then you get to fill them in at the login screen. Obviously you can make this connect to any VNC server by using password=ask, ip=ask, port=ask

[xrdp1]
name=VNC5901
lib=libvnc.so
username=na
password=ask
ip=127.0.0.1
port=5901

This next example is more interesting;

[xrdp4]
name=sesman-any
lib=libvnc.so
ip=ask
port=-1
username=ask
password=ask

It still uses libvnc.so so it’s obviously converting between RDP and VNC still. The interesting bit is the username=ask. Most VNC servers don’t take a username. What this profile does is to prompt for a username and password and ip. As part of the xrdp startup it always starts up a daemon called sesman. This is like a login authenication daemon which can spawn a command once authenticated. By default sesman listens on port 3350, so xrdp takes your user/pass and connects to the ip you specified on port 3350. The sesman on that port should respond and authenticate the user (typically the ip is always 127.0.0.1). Then the cool bit is that it starts up Xvnc as your user on the ‘next available DISPLAY setting above :10’, and assuming the Xvnc startup works, xrdp starts the whole RDP to VNC conversion. So you no longer need to start up Xvnc beforehand. Another good thing about this method is that if you just exit your RDP client (ie. don’t choose to logout), then the Xvnc session keeps running in the background, and if you RDP in again later it’s all still working where you left off. Conversely, if you choose to ‘log out’ then the Xvnc process and any windows you had open ends as you log out.

But there are more lib= types you can use. Look at this example from xrdp.ini that uses lib=librdp.so

[xrdp5]
name=windows
lib=librdp.so
ip=ask
port=3389

librdp.so allows you to sort of proxy through your xrdp server to another RDP server (eg. a windows PC)

Then there’s this sesman-X11rdp example;

[xrdp6]
name=sesman-X11rdp
lib=libxup.so
username=ask
password=ask
ip=127.0.0.1
port=-1

For a long time I never really understood what this one did. In fact in 99% of all xrdp installs out there it does absolutely nothing. It asks for your username so that means that sesman thing is involved. So it will authenticate your user/pass with sesman, but instead of starting Xvnc, it starts X11rdp. Chances are you do not have X11rdp. Most linux distros do not include it as part of their ‘xrdp’ packages, so what is it?

X11rdp is a real X server that instead of thinking its talking to say an Nvidia or ATI hardware video card, it is talking to an abstracted ‘RDP’ video card. Similarly the mouse and keyboard are abstracted to come down the RDP protocol connection. So it still talks the X protocol, so that typical X client programs (eg. xterm) still think they’re talking to an X server, but ‘out the other side’ it’s all RDP traffic. I don’t think it talks RDP over a network connection though (not sure). I think the role of libxup.so is to provide the ‘link’ to it.

So where do you get X11rdp? I couldn’t find many references to it on the net but came across this post that mentions that there is an svn repository containing a modified Xorg 7.1 server that when compiled produces the X11rdp binary. Compiling the old Xorg drivers takes a long long time, but I had success following those notes. So here’s what I did;

cd some_temp_dir_with_plenty_of_space
svn co svn://server1.xrdp.org/srv/svn/repos/main/x11rdp_xorg71
cd x11rdp_xord71
mkdir /opt/X11rdp
sh buildx.sh /opt/X11rdp
# and now wait a long long time

That post on linuxquestions.org mentioned some changes to font directory paths inside the buildx.sh script. I didn’t have to change it at all the first time I tried compiling. I used a Debian Lenny 64 bit host to compile. However, I wanted to put this on a Centos 5.3 32 bit system as well and it wasn’t so good. basically there are a couple of changes to the buildx.sh script. First it compiled libfreetype as a 64 bit binary, so I had to add in the CC=”gcc -m32″ bit below

# freetype
if ! test -f $PCFILEDIR/freetype2.pc
then
  cd freetype-2.1.10
  CC="gcc -m32" ./configure --prefix=$PREFIXDIR
  if ! test $? -eq 0
  then
    echo "error freetype"

And the font path in Centos is a bit different to what the script was expecting, so I had to do the following (adding in the last elif bit)

# make a symbolic link to your local font directory
if ! test -d $X11RDPBASE/lib/X11/fonts
then
  if test -d /usr/share/fonts/X11
  then
    ln -s /usr/share/fonts/X11 $X11RDPBASE/lib/X11/fonts
  elif test -d /usr/X11R6/lib/X11/fonts
  then
    ln -s /usr/X11R6/lib/X11/fonts $X11RDPBASE/lib/X11/fonts
  elif test -d /usr/share/X11/fonts
  then
    ln -s /usr/share/X11/fonts $X11RDPBASE/lib/X11/fonts
  fi
fi

I also compiled for a Debian 32 bit build and had to put ‘CC=”gcc -m32″;export CC’ at the very top of the build script (but that might be because of the virtual machine I was compiling in).

So once you have X11rdp compiled, make sure it’s in your path (perhaps create a symlink from /usr/bin/X11rdp to wherever you have it).

So for me xrdp plus X11rdp works great, but you could never copy and paste between your local environment and your remote environment … until now. As well as the stable releases of xrdp, there is also a CVS repository, and one of the more recent commits (sept 2009) is to add clipboard support (thank you Jay). To get and compile the cvs version you need to check it out.

mkdir workdir
cd workdir
cvs -d:pserver:anonymous@xrdp.cvs.sourceforge.net:/cvsroot/xrdp checkout xrdp
cd xrdp
./bootstrap
./configure
make install

You might have to do some fiddling with various paths to get it all going (most distro’s seem to run xrdp as a non-root user. If you run the cvs version this way it will have trouble writing the pid file when xrdp starts … unless you change the path to the pid file … or do a ./configure –prefix=/usr/local/xrdp … or similar. The best way is to just use strace when launching the binaries to see what’s going on)

You run xrdp then xrdp-sesman (which used to be called just ‘sesman’). The easy way is to run both as root, though you might want to invest the time to get xrdp to run as a non-root user. For example;

su - xrdp -c /usr/local/sbin/xrdp
/usr/local/sbin/xrdp-sesman

The clipboard support just ‘works’ for the most part. I had a few issues with using the Windows XP mstsc client, but rdesktop and the Windows 7 mstsc seem to work fine (UPDATE: It’s only the XP SP2 mstsc that I can’t get to work with the clipboard. The mstsc out of XP SP3 works fine … and in fact works fine if you copy it to a SP2 machine)