03/04/2008

VNC server over a secure SSH connection

The standard way provided by openSuSE to get a remote graphical login to your linux desktop is Krfb. It uses an obscure kind of 'invitation' system and I never got the hang of it. TightVNC works like any old VNC server on Linux: start a VNC X session and log in with password protection from a remote machine via a VNC viewer like Krdc (KDE3 version works for me, KDE4 doesn't). Unhappily, a VNC connection is not exactly secure, anyone sniffing into your network might find out what you are doing at the moment on the remote machine (e.g. typing passwords). A safe alternative would be to export the VNC session over a SSH tunnel as follows.


HOWTO:
a) remote machine

Install tightvnc with YaST. Start a VNC server for the first time, set a password when asked for
(the read-only one is not necessary), and kill it immediately after (the number of the display to kill is provided by the 'vncserver' console output).
avocadohead@xanthippe> vncserver
...
New 'X' desktop is xanthippe:2
...
avocadohead@xanthippe>
vncserver -kill :2
Edit your VNC startup script, which by now ought to have been created as ~/.vnc/xstartup:
#!/bin/sh

xrdb $HOME/.Xresources
# xsetroot -solid grey
xterm -geometry 80x24+10+10 -ls -title "$VNCDESKTOP Desktop" &
# twm &
/opt/kde3/bin/startkde &

If you don't care for a KDE session, keep the twm & line, this will give you a rather spartan window manager. The port on which the server is running is by default 590x, x is the display number (like the 2 in xanthippe:2).

You can additionally change your display settings (size, colour depth) at calling the vncserver script, e. g.:
user@remote> vncserver -geometry 1024x768 -depth 16
By default, openSuSE shouldn't have any ports opened for VNC, we want to keep it that way. Check the following settings in YaST:
  • YaST->Security and Users->Firewall->Allowed Services->SSH allowed.
  • YaST->Network Services->Remote Administration (VNC)->Allow remote administration, but do not open firewall port!

Make sure that you run a SSH daemon and your preferred external user has access to it.

b) local machine
On the local machine, open a terminal:
user@local> ssh -L <anyport>:localhost:590x <username>@<IPofremotemachine>
590x is the VNC port specified above. This will give you a password protected encrypted SSH session. Start your preferred VNC viewer on localhost:<anyport>, use the password set for your remote VNC. Adding the -C option gives you additional ssh compression, which is nice if you have fast machines on a slow connection.
user@local> ssh -L <anyport>:localhost:590x -C <username>@<IPofremotemachine>

If SSH is not running on the default port 22 (which is advisable for security reasons, change it in /etc/ssh/sshd_config and restart the SSH server), add the -p option as specified by daWuzz here.

Note: Unlike a VNC server on Windows, you can't access a current user X session on the remote machine in this way; TightVNC runs on a different virtual display. However, you can access the VNC session from the normal session by connecting to localhost:590x. Weird, but works.

On the other hand, you can also just install rfb on the remote machine, run x0rfbserver instead of vncserver (port 5900 for xserver :0, of course), give a password when asked for and do everything else as described above. This gives you access to the physical display of the remote machine, but the connection is slower and system performance drops.

2 comments:

DaWuzzzz said...

Just in case you want to have a ssh secured VNC session on a Windows box (yes, I know, this is a LINUX blog, but still...)
The same works for the current user session in Windows with a VNC server of your choice and an ssh daemon. There are several available e.g.
http://www.freesshd.com/
Make sure you open your preferred ssh port (standard is 22) in your local firewall and - if applicable - forward the ssh port in your router/NAT.

DaWuzzzz said...

Just a side note to the listening viewer. If you want to user another port than the standard port 5900 for the listening viewer of RealVNC, you can do so by invoking it with the command argument:

vncviewer.exe -listen <portnumber>