Back in the old days, there was no such thing as a personal computer. Users would use 1 central computer to which they log in from "terminals" (a screen + keyboard combination"). This means that the actual computing (running programs, processing data, ...) would be done on a central machine, but the output would be shown on the terminal of the user in question. The advent of (networked) personal computers turned this concept upside down : PC's do their processing locally : programs are run by the PC. The client-server architecture allowed these (local) programs to get data from a (remote) server.
In the past couple of years, there's been a renewed interest in server-based computing : think Microsoft Terminal Services, or remote desktop sessions. To a Microsoft Windows user, this is (was) quite a revolutionary concept, while Linux and Unix-like systems have always known these concepts. Let's see how it works.
The examples in this article are taken from 2 Linux systems running Ubuntu 6.06 with a minimal server install. That is : only the base system is installed, and additional packages were added as needed. the package names may be debian/ubuntu-specific, but the general principles will apply to all Linux systems.
I use a simple console example here to explain the principle of multi-user systems with remote terminal sessions; we'll be looking at using (graphical) programs later on. Hence, the basics : remote shell sessions.
Look at it this way:
assume the "server" (computer A, Ubuntu or some other Linux distribution) is running, and let someone log in : that's 1 person using that computer.
assume you connect to computer A, from a 2nd computer (computer B), eg with telnet or ssh.
What you get is a command prompt on computer A. If you run a program from that command line, it would execute on computer A, eg if you ls -al /etc, you'd get a directory listing of /etc on the computer A file system. If you compile source code from /home/george/myproject, the compiler would be executed by computer A and the source code would come from a directory on computer A. The only thing happening on computer B is keyboard activity and screen output - sort of.
We will connect to the server by ssh. This requires that you install openssh-server on computer A (the server). ssh is a network protocol that allows secure, encrypted communication and is therefore the preferred method for setting up remote sessions.
This is what it looks like when connecting from an other Linux system : user kn on computer knix logs on to computer kdunix as user root. See how the command prompts change. Any command executed now will be run on kdunix (the server), eg the pwd command shows that your in the home directory of "root" (kdunix), no longer in the home of user kn on knix.
kn@knix:~$ whoami kn kn@knix:~$ hostname knix kn@knix:~$ uname -rs Linux 2.6.15-28-686 kn@knix:~$ kn@knix:~$ ssh root@kdunix root@kdunix's password: Last login: Sat Jun 30 17:44:16 2007 from 192.168.0.127 Linux kdunix 2.6.8-2-386 #1 Thu May 19 17:40:50 JST 2005 i586 kdunix:~# whoami root kdunix:~# pwd /root kdunix:~# uname -rs Linux 2.6.8-2-386 kdunix:~# exit logout Connection to kdunix closed. kn@knix:~$
The communication between to two machines was handled by ssh. This requires an ssh daemon running on the server. On the client-side, you need a ssh client, but most distributions will install it by default because it's such a common, convenient en secure way to handle remote sessions.
From a Windows machine, you could use a terminal emulator such as putty to do this, because it is capable of ssh. You could also just 'telnet' from a Windows command prompt ("DOS window"), but this would require a "telnet server" running on the linux machine. Telnet services are not popular (anymore) on Linux machines : the communication is not encrypted, so for sending passwords or other sensitive information, it is not really save.
Here's puTTY on Windows XP connecting to a linux server server :
Obviously, this can be done from multiple other pc's as well, simultaneously, so you can have lots of people using the same computer A - your "server". You'd say that the users on Computer B, C, D ... all have a 'session' on computer A.
You will have to authenticate with a username and password on the remote system. SSH can also be setup to connect passwordless, i.e. through Public Key authentication, host-based authentication, certificates, and so on.
from the remote command prompt, you can start any application, including those that are "graphical" (use windows and buttons - as opposed to "text"-based command lines). So you can use remote applications - the only additional problem is that instead of just characters, you need their complete "window" to be send back to computer B, C, D, etc.
Graphical, Windows-like output on a Linux system is handled by the X Window System, often just called "X". The server must thus "forward X" to the remote systems. To enable X forwarding in an ssh session -you need to have X11Forwarding yes in the file /etc/ssh/sshd_config. You can check this by running grep "X11Forwarding" /etc/ssh/sshd_config . This setting is enabled by default in ubuntu.
Then, install xauth on the server. xauth is a small utility to control authentication and access to X sessions.
That's it for the server. However, you may want to install some programs so that you can run those remotely later on : e.g. xeyes, xclock, firefox, ...
## install ssh server apt-get install openssh-server ## setup server for remote access to GUI applications (X) grep "X11Forwarding yes" /etc/ssh/sshd_config || echo "X11Forwarding yes" >> /etc/ssh/sshd_config apt-get install xauth ##may be obsolete ## install some applications apt-get install xeyes xclock firefox
Note that you did NOT set up an Xserver / Xwindow system on the server machine : you only need X on the client machine- i.e where the screens are displayed. Install the required X-window system on the client machine :
apt-get install x-window-system-core xserver-xorg xhosts xterm #allow remote system 'hostname' to access local xwindow system xhosts +hostname
Now you can run the applications that you installed on the server by invoking them in an ssh session from the client machine. Note that X-server needs to be running on the client machine. To start a remote GUI application, run startx from your command prompt, then in the resulting xterm, run ssh + name of remote application, eg ssh -X user@server xclock.
You can do this all in one command, from the console, using xinit to start X:
## run remote xeyes peter@client$ xinit -e ssh -X user@server xeyes ## execute firefox on remote server, but visible and usable on client machine peter@client$ xinit -e ssh -X user@server firefox http://www.google.be
For a more pleasant gui experience, you may want to install a desktop manager, a window manager, ... on the client machine. This provides windows with title bars, buttons (iconify, minimize/maximize, close ) and other "decoration". Of course, all of the above will also work from inside a desktop environment such as Gnome or KDE. Here's firefox running of "server" but shown in an Ubuntu Gnome Desktop on the client machine :
A practical application of this may be installing a lightweight file manager (such as xfe) on your server. This allow you to remotely manage files on a server from a drag-and-drop file manager on your desktop. [screenshot]
To do something similar from a Microsoft Windows client machine, you need an X-server that can run on Windows, eg from Cygwin or Xming. You also still need puTTY to set up the ssh-session first.
A "desktop" can be considered just another program. At least, a window manager is an X application so we can run it on the remote machine and pull it's output (the "desktop") to our local computer. Moreover, a window manager will have menus to let us start other applications - and these applications are 'local to the window manager' so they will be executed on the same machine as where the window manager is running - that is: on our server machine.
As proof-of-concept, we set up (as before)
On the client, invoke the window manager (installed on the server) as a remote GUI application :
user@client$ xinit -e ssh -X user@server startfluxbox
fluxbox starts and is visible on the client, allowing you to select firefox, xeyes, ... from it's menu and control the remote applications. Note (in the x-terminal) that the user is @server. Also : none of these applications were installed on the client ...
click the image to enlarge it
Note that in this scenario, the entire desktop lives on the server, but is shown on the client. This is not the same as the earlier example where a (remote) firefox was being shown in a local desktop environment.
Multiple users can connect to the server, and each will have his own session. However, to use such a setup in a real environment, there may be some additional issues to take care of (X configuration, security, user management) , but I'm not addressing them here. We're just looking at how X works.
By now, you'll have realized that "client" and "server" are relative concepts. When we talk server-based computing, the "server" is where the applications run, where the processing is done. However, in the X Window System, an X server is the process that offers displays and screens to these (server-based) applications - so the applications are "(X)clients", and the Xserver is running on the machine where the output has to be shown - i.e. the "client machines", "workstations" or "terminals".
It sounds as if X has it backwards, but it makes sense. It's just a bit confusing, if you are used to think that server = remote.
XDMCP stands for X Display Manager Control Protocol. Up till now, we've started x from the console, with xinit or startx. This requires the user to logon to a console, and have a login shell to start X. X Display managers (such as xdm, gdm , kdm ...) let you boot to a GUI system directly (without a console login and without shell). XDMCP lets you combine a display manager with remote X applications and X servers, and is therefore the preferred way to log on to a remote desktop, in stead of the "running a window manager as a remote X application"- approach described earlier.
VNC (Virtual Network Computing) is a very useful network graphics protocol (applications running on one computer but displaying their windows on another) in the spirit of X, however, unlike X, the viewing-end is very simple and maintains no state. It is a remote framebuffer (RFB) protocol.
vnc enables you to transport screen output over a tcp/ip network, and in that respect it can be used as an alternative for exporting/forwarding X-windows. It requires a vnc-server on the server machine, and a vnc client program on the client machine. There are vnc servers and clients for both Windows and Linux, and they mix, eg you can vnc from a Linux-client to a Windows server and vice versa. However, a Windows vnc server will always export the entire Windows desktop, while a Linux vnc can capture individual applications as well.
In the previous examples, each user had his own session, true to the multi-user nature of Linux / Unix. However, some situations require a session to be shared by multiple users, like when a remote support technician wants to "take over" your desktop to fix something - while you watch what he's doing.
There's an interesting post at Ubuntu forums, describing How to share a terminal session between 2 users, using 'screen'. However, how do we go about sharing 1 desktop between 2 (or more ?) users ?
The following is a summary of x11vnc: a VNC server for real X displays by Karl J. Runge, which explains this in great detail. Ubuntu Community Documentation : x11vn on Ubuntu.
To share a desktop (or a single application), we take the X-server (running on and displaying output on machine 1) and connect to it with a vnc viewer from machine 2, so that the same output is shown on machine 2. We're actually using the X-server as a vnc server, and all it takes is a vnc viewer (on machine2) capable of talking to an X server in stead of to a regular vnc server.
on the remote machine, which runs the desktop that you want to connect to, you need to install (eg apt-get install x11vnc) and run x11vnc. You can start x11vnc yourself (remote shell, ssh), or have the user at the fare-away machine start it, or have it running "always on" as a service.
on the local machine (where you want to display the remote desktop), you install and run a vnc viewer such as xvncviewer or xtightvncviewer.
On computer_1, run x11vnc
On computer_2, run xtightvncviewer. You are prompted for a server. That would be computer_1:0. The :0 is the X display number as reported by x11vnc.
The desktop of computer_1 magically appears on the monitor of computer_2.
Run a program on computer_1, say mousepad, a game, firefox .... computer_2 shows what's happening on computer_1. From computer_2, use the programs running on computer_1. All mouse movements, input, etc are shown on computer_1 as well.
The desktop of a Xubuntu system (client2) captured on a fluxbox desktop.
More info (command options, tips and tricks, troubleshooting .... ) : refer to the links at the beginning of this section.
Normal vnc operation is to have a vnc server running, and connect to it with a vnc client (vncviewer). In remote support scenario's, you may want to reverse this : the vnc-viewer is "always on" (listen mode), and the user who needs support starts his vnc-server whenever he needs support (eg with a "get help" button on the desktop).
more details : HOWTO : Reverse VNC - Ubuntu Forums.
For this to work you may have to open/forward the relevant ports on the respective firewalls. Some additional security (passwords, tunnels, ...) may be in order as well, and you might need a fixed IP address or a DynDNS solution for this to work over internet, but all that is beyond the scope of this article.
The core ideas behind NX are to compress X protocol traffic and to reduce the number of X protocol round-trips across the network by using a proxy X server ( A Look at NoMachine NX, Mark McLoughlin). So basically what you get is "remote X", i.e. an application of the X the features demonstrated earlier, but with better network performance, and in a nicely polishes package with some additional features.
From the NoMachine website:
NoMachine NX is a Terminal Server and Remote Access solution based on a comprising set of enterprise class open source technologies. Thanks to the outstanding compression, session resilience and resource management developed on top of the X-Window system, and the integration with the powerful audio, printing and resource sharing capabilities of the Unix world, NoMachine NX makes it possible to run any graphical application on any operating system across any network connection as if you were sitting in front of your computer.
See also some comments at Ubuntu Forums
So far, we've been investigating the X protocol, X's own networking features that allow remote graphical applications to show up on your screen. There is also a Remote Desktop Protocol (rdp) that is useful to access remote desktops such as Windows XP desktops or Windows Terminal Server sessions. This can be achieved with the Gnome RDP client
(gnome-rdp) or a Microsoft Terminal Service compatible client (tsclient). You may want to set up a vpn tunnel before running rdp sessions if you want to keep them secure.
A A Minimal GUI system for Linux servers.
Some additional links collected here : Remote Desktop Connections (Linux Questions), and this How to Export your X display.
xmove : utility to move X between displays / screens / monitors. man page debian package
network boot booting and running thin clients and diskless workstations.