Search:  
Gentoo Wiki

X11vnc

This article is part of the HOWTO series.
Installation Kernel & Hardware Networks Portage Software System X Server Gaming Non-x86 Emulators Misc

Contents

Introduction

VNC is a popular remote-desktop protocol. Most implementations of VNC servers on UNIX create their own X display that is not associated with a physical screen. This is very useful for allowing multiple remote users to have desktop sessions through VNC independently of anyone actually sitting at the computer. On the other hand, one might want to access a computer remotely in the following way:

This may be the case, for example, when one wants to use a computer at work remotely from home. One could of course start a further non-physical session on the work computer, if its main attraction is that it is faster or has some tedious proprietary programs not available at home. But if many necessary applications are open, arranged and perhaps currently running some calculation on the physical session then connecting to that physical session is desirable.

Problem

Working with existing X sessions is not supported by normal VNC packages.

To work remotely on a running session on a physical display, one can:

  1. run x11vnc as a user or
  2. configure the (physical display's) X server to support the vnc extension

Limitations

Other Notes


Method 1: x11vnc method

In this method, the user that starts the X session also starts the VNC server. x11vnc is what we are going to use to connect to our current X session.

Note: jpeg and zlib USE flags are required for x11vnc compression
$ echo "x11-misc/x11vnc jpeg zlib" >> /etc/portage/package.use
$ emerge x11vnc -va

Edit the x11vnc config file: ~/.x11vncrc. See

$ man x11vnc

for more details (the config file options are just those from the command line but without the leading "-").

Warning: If you don't plan to access the X session via an ssh tunnel or from the computer where x11vnc is running, omit the "localhost" option.
File: ~/.x11vncrc
forever
localhost
rfbauth /home/your_user_name/.vnc/passwd
display :0
#You can use rfbport to specify a different port (default is 5900).

If it doesn't already exist, create ~/.vnc:

$ mkdir ~/.vnc

For security we have to create a password for the incoming connections to the X session.

$ x11vnc -storepasswd ~/.vnc/passwd

OR, if tightvnc or vnc is installed, just use their utility to do the same:

$ vncpasswd

This passwd file will be used by x11vnc or tightvnc/realvnc servers to authorise incoming connection to displays that you start.

To start the vnc server you need the x11vnc command. This could be put somewhere for starting on login. E.g. make a script in ~/.kde/Autostart/ , perhaps by:

$ echo -en '#!/bin/bash\nx11vnc <OPTIONS> &\n' > ~/.kde/Autostart/x11vnc
$ chmod u+rx ~/.kde/Autostart/x11vnc

Start "gnome-session-properties" from your terminal, if you are GNOME user to setup autostart.

Else, start it manually each time, possibly necessitating logging in from a remote host by ssh and giving the x11vnc command, perhaps as

$ x11vnc >>~/.x11vnc.log  2>&1 &

to allow you to log out leaving it running, and to have its output logged.

If no one is logged into an X session yet, but there is a greeter login program like "gdm", "kdm", "xdm", or "dtlogin" running, you will need to find and use the raw display manager MIT-MAGIC-COOKIE file. Some examples for various display managers:

    gdm:     -auth /var/gdm/:0.Xauth
    kdm:     -auth /var/lib/kdm/A:0-crWk72
    xdm:     -auth /var/lib/xdm/authdir/authfiles/A:0-XQvaJk
    dtlogin: -auth /var/dt/A:0-UgaaXa
    xorg7.0: -auth /var/run/xauth/A:0-TD4u0I

Only root will have read permission for the file, and so x11vnc must be run as root. The random characters in the filenames will of course change, and the directory the cookie file resides in may also be system dependent. Sometimes the command "ps wwaux | grep auth" can reveal the file location.

An example:

$ ssh -L 5900:localhost:5900 root@<target-ip> 'x11vnc -localhost -display :0 -auth /var/lib/gdm/:0.Xauth'

You can also setup x11vnc to autostart when KDE starts, by creating a symlink.

$ ln -s /usr/bin/x11vnc ~/.kde/Autostart/x11vnc

Once you login like this, x11vnc may crash, but your session will load. Start up x11vnc again as normal-user and you'll be able to login to your newly created session.

Tunnelling Script

This simple script takes two arguments, first is open or view, the second is user@target. Written with GDM in mind.

File: vncTunnel.sh
#!/bin/bash

mode=$1         # open | view
target=$2       # format: user@linux-box

case $mode in

        'open')

                if [ "$(echo $target | grep root)" ]; then
                        ssh -L 5900:localhost:5900 $target 'x11vnc -localhost -display :0 -auth /var/lib/gdm/:0.Xauth'
                else
                        ssh -L 5900:localhost:5900 $target 'x11vnc -localhost -display :0'
                fi
        ;;

        'view'|'connect')
                vncviewer -encodings "copyrect tight hextile" localhost:0 -compresslevel 7 -quality 5 -fullscreen
        ;;

esac

Method 2: X Server (system-started) method

Install a vncserver package that provides the vnc.so extension module for the X server.

Note: The "server" flag is needed to make vnc build the server parts that we need---otherwise you'll just get the viewer
$ emerge vnc -av

(the vnc ebuild is "realvnc": it works on amd64, and provides a vnc.so module for X11 server)

The Xserver needs to know where to look for authentication information when someone tries to connect. You could make some other file for this, if not wanting to reference a user's home directory (e.g. NFS root_squash or AFS): we'll use the familiar ~/.vnc/passwd here.

Edit /etc/X11/xorg.conf (for Xorg server) or /etc/X11/XF86Config for the old XFree server.

File: /etc/X11/xorg.conf
Section "Module"
  Load     "vnc"
  Load     "freetype"
  Load     "type1"
Section "Screen"
  #This tells X where to locate the VNC password file
  Option     "PasswordFile"    "/home/your_user_name/.vnc/passwd"
 Section "Files"
    ModulePath "/usr/lib/modules/extensions"
    ModulePath "/usr/lib/xorg/modules"

Save your changes and close your editor. You will have to restart X (no need to reboot, just log out (end session in KDE), and hit CTRL-ALT-BACKSPACE when the login window comes back up, then login).

You also need to create your passwd file that you specified above.

Code: ~/.vnc/passwd file
 $ mkdir ~/.vnc
 $ vncpasswd ~/.vnc/passwd
   Password:
   Verify:

If you're using the X.org server, you may need to create a symlink to vnc.so (Note to 64 bit users: use /lib64/ not /lib/)

Code: vnc.so symlink for versions below 4.1.2
 ln -s /usr/lib/modules/extensions/vnc.so /usr/lib/xorg/modules/vnc.so

Restarting X is presumably necessary to see the changes! To debug (if not able to connect by VNC) try the log files /var/log/X* and stopping the display manager (/etc/init.d/xdm stop) then starting X from a terminal to see the messages.

The vnc.so module for VNC 4.1.2 was changed from vnc.so to libvnc.so. If you have VNC 4.1.2, you should make a simlink to /usr/lib/xorg/modules/extensions/libvnc.so from within /usr/lib/xorg/modules.

Note: The module will fail to load if its name libvnc.so so along with the symlink rename it to vnc.so
Code: libvnc.so symlink for 4.1.2 and up
 ln -s /usr/lib/xorg/modules/extensions/libvnc.so /usr/lib/xorg/modules/vnc.so

Connecting

Whichever method (user-started x11vnc or X-started Xorg vnc extension) you have chosen, you should now be able to log in by connecting as

$ vncviewer HOST:DISPLAY

from some host with vncviewer (part of vnc or tightvnc ebuilds---see first section for comparison).

BUT: the catches are the following:

1) You may find that although x11vnc or Xorg's extension is running listening to the physical display :0 (or :1 or whatever), the respective conventional port of 5900 + displaynumber may have been occupied, forcing the tcp listening to be on a higher port: you should be able to find this in the log output of whichever server you used. So you might, for example, need to connect to HOST:2 by vnc to view display :0 ...

2) If you've specified the localhost option for the server, then it will only allow connections _to_ localhost (127.0.0.1) through the loopback interface, accessibly only on the local host---not much use for remote connection, you may think: but a solution is to use SSH tunnelling, which also makes the connection far more secure:

$ vncviewer -via HOST localhost:DISPLAY

where host is the host on which the vnc server is running, and which must have the SSH service accepting connections! You will then be asked for your system login followed by the vnc password for the display you've chosen.

3) Even if you didn't specify localhost, there may be packet-filtering preventing incoming connections, so either open the relevant ports or use SSH tunnelling as above.

Bear in mind that the type and level of compression of the picture is very important to good performance. It seems that when SSH tunnelling is used, and the VNC display is "localhost", the automatic compression selection can go for very low compression (assuming a true local connection).

Some good command-line options are:

$ vncviewer -PreferredEncoding ZRLE -FullColour -Shared 1 HOST:DISPLAY

to use full colour, tight encoding, and allow multiple simultaneous users of the session! See the manual page for more details.

As an example of some vncviewer options from the previous version of this page (the compression-related ones don't work with my client, in RHEL4):

$ vncviewer -encodings "copyrect tight hextile" -compresslevel 7 -quality 5  -fullscreen

Add these or read the manual, if wanting compression more suited to slower connections. Correctly set, vnc allows very efficient use of bandwidth and impressive speed of working even on quite low-rate connections: don't tolerate low colour or sluggish response without playing with the variables, unless you

Note that as vnc essentially sends a load of pictures, fast movement makes it much more sluggish. So, those streams of text churning down an open console can use 100% CPU on the server for compressing the images, then fill up the network connection too. Just minimising all unneeded such windows is a very good start to avoiding this problem!

Optional: Localhost-only option for X server daemon

Even though X is handling the VNC connections directly through the vnc.so module, it is still possible to force it to listen on the localhost interface only, or bind to a specific interface at your choosing.

For the 'localhost' option, add the following to the "Screen" section of your xorg.conf file:

File: /etc/X11/xorg.conf
Section "Screen"
   Identifier  "Screen0"
   #... omitted rows ...
   # Tells the VNC module to only accept connections from 'localhost'
   Option "localhost"
EndSection

Restart your X server (Ctrl-Alt-Backspace) and verify that your VNC connections are now only listening on your localhost interface:

Command: sudo lsof -i -n -P | grep :5900
X         27426          root   19u  IPv4 6548414       TCP 127.0.0.1:5900 (LISTEN)

You should now be able to tunnel your VNC connections over SSH to localhost:5900. Please Google for other docs on tunneling connections over SSH. This setup will provide two things: 1) Two sets of verification credentials to access your system (SSH and VNC itself), and 2) An encrypted session.

Note: If you want to add any other vncserver or Xvnc options, you can add them in a similar fashion as shown above to the respective Screen section. (ie Option "argument" "value")
Warning: While not required, it is HIGHLY recommended that this option be used in combination with SSH tunneling (as opposed to accepting connections directly) since VNC connections are not encrypted by default.

Dual-Head Displays

Depending on your particular setup, the vnc.so module for X will allow connections to either one or both monitors. If you desktop spans both monitors (effectively one X session stretched across two monitors), then no further configuration [should be] needed.

Another common setup is to have a separate session for each monitor that allows for mouse movement between them (normally a single video card with dual outputs). In this scenario, VNC will only allow for a connection to one head/monitor per session (you can of course run two remote sessions concurrently). Your primary monitor will listen on port tcp/5900. The second head will listen on port tcp/6900. How you connect to the second head is dependent on your particular viewer application. Most will simply require that you append ':6900' to the connection string.

Note: You may also need to duplicate the "Option" statements for each Screen section in your xorg.conf, although I haven't verified whether that is the case.

Once configured, you can check to see if your X server is listening on the proper ports.

Command: sudo lsof -i -n -P | grep :.900
X        27426    root   19u  IPv4 6548414       TCP 127.0.0.1:5900 (LISTEN)
X        27426    root   20u  IPv4 6548415       TCP 127.0.0.1:6900 (LISTEN)
Note: Yet a third scenario may present with two displays on separate video cards. In this case, VNC will most likely use ports tcp/5900 and tcp/5901, rather than tcp/6900.

Links

Retrieved from "http://www.gentoo-wiki.info/X11vnc"

Last modified: Mon, 04 Aug 2008 09:19:00 +0000 Hits: 94,041