How To Set Up A Terminal Server In Linux Using Ubuntu 9.10 And FreeNX

What was once old is new again and the desktop-centric computing is making way for return of thin client/mainframe computing again. This tutorial will walk you through setting up a Ubuntu desktop to act as a "mainframe", capable of being accessed by a thin clients or regular desktops, using the excellent FreeNX server.

FreeNX is an open source implementation of NoMachine's NX Server. It is a bit more akin to Microsoft's RDP protocol that the usual VNC, so while keeping bandwidth to a minimum, it maintains good visual quality and responsiveness. You can connect using NoMachine's monetarily free NX Client, which is available for Windows, OS X, Linux or Solaris. Also, by default, all traffic is via SSH, so your connections are encrypted.

There are quite a few scenarios where this is useful. At work our sensitive data is on a network that is not directly connected to the internet. To access the internet, users remotely connect to the NX server. This requires opening only a single port (22) in one direction, and is quite secure. It saves a huge hardware layout, eases administration, and as it's a locked down linux computer, there's considerably less worry about viruses and malware (our network is predominately Windows).

Personally, I run a similar setup on my workstation at home, which gives me access to my computer's full performance and all my files from my netbook, wherever I have a connection to the internet. Using a NX server in conjuction with the Linux Terminal Server Project can repurpose old, antiquated desktops for new applications.

I should put a disclaimer here. These instructions work for me. They should work for you too, though they may not. Network security is a complex subject. While such a setup has the potential to be highly secure, I'm not covering all the facets that may be involved. So, follow these instructions at your own risk.

Having said that, let's get started.


Operating System

First thing to do is install Ubuntu 9.10. I'm not going to step through the specifics on this as it's fairly straightforward and there are already excellent instructions located elsewhere, such as here:

Steps 1-3 would be a minimum, but feel free to customize it further as need be.



Open a terminal window by click on Applications -> Accessories -> Terminal, and then elevate your privileges to root.

sudo su -l

We're going to install a required package and a couple useful ones. Openssh-server is a requirement for the FreeNX server and fail2ban will lock out those attempting to log on with incorrect credentials, which helps mitigate brute force attacks. I'm using firehol to help write the iptables firewall.

aptitude update && aptitude install openssh-server fail2ban firehol

Let's test that our ssh server is running:


You should get a listing of an RSA key fingerprint and a query on whether you want to continue to connect. You might jot the fingerprint down. We'll be comparing it in a later step. Hit Control-C because we don't want to connect here, we just want to know that our ssh server is running.

Go ahead and leave that terminal window open. We'll be getting back to it shortly.



Next let's configure networking. Because this will be a server that's remotely accessed, we'll want to set up a static IP address. Other options include setting a statically assigned IP address from the DHCP server, but that's beyond this tutorial. You may also want an IP address on a different network. If you want any of these, than chances are you know what you're doing and do not need my help configuring your network, so go ahead and set up your network and let's meet up after the network config. Otherwise, let's set up you up with a static IP address.

My examples here are correct for my network, but you'll need to modify them for your network. A good place to start is seeing what network settings were already assigned to you. From your terminal window type in:

ifconfig eth0

Note the addr (IP address), Bcast (broadcast) and Mask (netmask) settings. Next type

cat /etc/resolv.conf

and note your DNS servers (nameserver). Finally, type:


and note down the Gateway address next to the line that starts with default. This is your default gateway.

So from these, you'll need to pick out an IP address that is within the same network range as your current settings, but is not assigned by your DHCP server, so as to avoid network conflicts down the road. Once you've got that, let's add these settings in statically:

nano /etc/network/interfaces

If the following line exists, you're going to change dhcp to static.

iface eth0 inet dhcp

If it doesn't, then add the following:

iface eth0 inet static

And then we're going to add a few lines. Make sure to use your network settings, not mine:


Then and save (control-o) and exit (control-x).

I'm going to put a plug in for Google's public DNS servers, which I find considerably faster than my ISP's and way easier to remember.

Let's test the settings by typing

/etc/init.d/networking restart

And if all went according to plan, you should be able to open Firefox and browse the internet. Make sure this works before continuing.

Next, let's configure our firewall. Again, if you know what you're doing and want to configure this different, that's fine. Otherwise, back to our terminal window and type the following:

nano /etc/default/firehol

And change the line:




And let's update firehol's list of reserved IP addressess with the following command:


Cool. So feel free to configure this differently, but for these tutorial, we're going to set the firewall to allow incoming connections at port 22 (ssh), and nothing else. We're not going to restrict outgoing connections. To do this:

nano /etc/firehol/firehol

And at the bottom of the config file, add the following line:

server ssh accept 

Save the config file and start firehol with the following command:

firehol start

You should see:

Activating new firewall (47 rules): OK

And if you're curious, you can see the rules generated with the following command:

iptables --list



OK, so it's time to install FreeNX. Luckily, the FreeNX implementation on Ubuntu is in an add-on repository, so we can easily install it with the following commands:

add-apt-repository ppa:freenx-team
aptitude update
aptitude install freenx
/usr/lib/nx/nxsetup --install

For added security, you can generate new keys, but at that point you have to distribute your key along with the client software. My personal opinion is that on an internal network, this is not an issue, but if your NX server is outward-facing, you should generate your own. It will generate the custom keys for you. Make a copy of the key (you'll need it when setting up clients) and keep it in a safe place if you do so.


Client installation

So, your NX server should be running now. Let's install a client. Switch over to a second computer and fire up the following web site:

Download the appropriate NX Client product for your OS and install it. You do not need any of the add-ons.

The first time you run it, the NX Connection Wizard will show up. Make up a name for the session, type in the IP address of the server, and set what speed network connection you have to the server, most likely LAN.

The next screen has a few more options. Since we're using Ubuntu 9.10, which by default comes with the Gnome desktop environment, you've got to change the default from KDE to Gnome. Set the screen resolution and hit Next.

If you generated custom keys, check the box for Show the Advanced Configuration dialog. If not, hit Finish. In the Advanced Configuration Dialog, next to Server section there is a button named Key. You'll need to import your custom key there, if you generated one.

So now we're ready to log in remotely. Type in your username and password, and click Login. The first time you connect, it'll ask you verify the RSA key fingerprint. This is your SSH key again, and the fingerprint should match our SSH test from earlier. You should accept this key, but note that if this pops up again at a later time, that should set off sirens in your head — it could be malicious.

And if everything goes according to plan, you should be logged in remotely.

From here, you can make new log ons for each person who you want to connect. Simply go to System -> Administration and select Users and Groups.

Congratulations, you've now got a working FreeNX server. There's a few other steps you can take depending on what you plan to do with the server. To enable remote access, on your router you can forward port 22 to the IP address of your server, which will allow you to to connect to your server from outside your network. In a business environment, you can add a firewall between your NX server and your internal network, again forwarding port 22. If you do this, you should generate custom keys and distribute it with your NX Client software. With such a setup, you could avoid setting up a potentially costly or complex VPN setup.

Further documentation:

Share this page:

6 Comment(s)

Add comment



Just wanted to say thanks - I needed a quick, straight-forward and easy to follow guide to do this and yours worked flawlessly.

Cheers!  :)

From: gfang

Ubuntu LTSP is a much more complete solution for setting up a terminal server on a LAN.  Client machines don't need an OS or even a hard drive because they boot directly from their ethernet hardware.  I use it so my whole family can use different clients at the same time, and I only need to administer one OS on one machine. 

 Using FreeNX requires the "client", host its own OS, and is better suited for connecting to your home/office machine from a remote location.

From: Anonymous

 Using FreeNX requires the "client", host its own OS. 

This is not true. If one sets up a TFTP server one can deliver an operating system to a diskless, operating system-less, thin client (zero client). I personally deliver the thinstation operating system including the nxclient. then one simply logs in to the freenx server. Between the main office and our branch offices, I set up OPENVPN, then access the freenx server via a "tun" tunnel. Works brilliantly !


I have succesfully tested Ubuntu 9.04 LTSP clients with NX / FreeNX environment with NX client installed in clients chroot and running by openbox session on client, but i am not using this solution, because i have LTSP setted to anonymous student's login (as guest login) and do not get guest login via NX to work yet.

But i am using NX client installed in client chroot as the locallapps to launch one application (kicad works very slow in LTSP). The kicad is launched by simple bash script. Only one problem, which i have, is X autentication, but this is probably my disconfiguration and i solved this by running "ltsp-locallapps xhost +..." for now - for this is mentioned script needed.

This solution has one disadvantage - by improper user's logout, the nxserver processes don't exits and sometime i need terminate these sessions manualy.

From: Roger

I would very much like to know how you did that...

I have been looking for a tutoral on this but so far no luck...


From: brian mullan

Multimedia is still a tough issue for NX as with any remote desktop s/w. I had exchanged some information with one of the FreeNX developers recently regarding audio problems and received the following advice:

If you are using the client on a Ubuntu machine you will want to build
a custom nxesd.
And replace the one at /usr/NX/bin/nxesd.
Ubuntu don't work well with the one that comes with the nxclient nxesd.
I've noticed that when I was hacking on sound support a long time ago.
So I am not sure about the status right now.

But I think this is causing the choppy audio.

> never have thought I'd had to OPEN those TCP ports
> but I was curious about the way NoMachine described the audio as needing TCP port 8001 (actually something between (8000 and 8200)

Yep, I really don't like this approach.

NX proxy port
       displaynumber + 4000
       5000 - 5200
X11 port
       displaynumber + 6000
       7000 - 7200
NX CUPS service port
       displaynumber + 2000
       3000 - 3200
NX SMB/CIFS share service port
       displaynumber + 3000
       4000 - 4200
NX Media service port
       displaynumber + 7000
       8000 - 8200
NX X11 auxiliary channel port
       displaynumber + 8000
       9000 - 9200

Marcelo also told me to make sure I added the following:

You will need something like this:
$ pactl load-module module-esound-sink sink_name=remote  ($ESPEAKER should be $DISPLAY+7000 --- check that its set using printenv | grep ESPEAKER)
or if not... set the env variable then execute the pactl cmd.
$ pactl load-module module-esound-sink sink_name=remote