Multiple VNC Logins on Linux Server


Scenario:

We use a remote "server" (actually a virtual) to do a lot of work for my company. This machine is pretty well protected, and the goal was to allow multiple users to perform remote logins to accomplish their work. Thus, it has vpn and ssh connections defined, has quick links to our knowledge base, all the things that make our time on the computer more productive. If a workstation goes down, we simply set up a new one with vpn and vnc, and our work desktop is still the way we left it.

 

Since there are multiple users, we need customization for each of them. Two of our technicians use laptops almost exclusively, one uses a dual screen Windows platform and also a Linux workstation with a huge screen, and another uses a netbook, a laptop and a dual screen Linux system. Initially, I simply wrote a script for each one. Originally, each user had a script in their home directory with the following four lines.

# start X (display=:2) (set width, height and depth for screen 1 -xkbmap
Xvfb :2 +extension RANDR -screen 1 1400x900x16 &
export DISPLAY=:2
# start the window manager
DISPLAY=:2 startxfce4 &
# start vnc server on this display
DISPLAY=:2 vncserver -rfbport 32555 -depth 16 -geometry 1400x900 -alwaysshared

Each user had this, with different values for DISPLAY, port, geometry and depth. In the case where multiple configurations (ie, different geometry and/or depth) were needed, the above would simply be duplidated.

 

Worked ok, except each time the server was restarted, someone would have to log in via console as root, then become each user and execute their startVNC script. Also, it was a little flaky on startup. Plus, if anyone ever actually tried to log out, it would kill their session and we would have to go in and manully start it up again. One nice thing was that we could share a session, which was handy if one tech was having trouble and wanted another to "look over their shoulder" but, the only scheme I came up with gave no control or indication when this was occuring.

 

It came time to rebuild the server (too much "playing" on it had really messed some stuff up, and I knew some things I wanted different), so it was time to "do it right" on the vnc/window manager thing. I wanted the vnc session to start at the login screen. The problem definition set the following paramters:

  • Use XFCE4 for speed and efficiency
  • Debian Wheezy
  • Each user logs into their own account
  • Multiple geometries and color depth supported "some how"
  • More resilient to pushing the wrong button
  • Ability to share your current session, but have some sensor showing when this occurred and the ability to turn this on or off.

Solutions

All solutions require you have a vnc server running on the target machine. I like tightvncserver since it is very efficient and also has a lot of documentation. Install tightvncserver:

apt-get install tightvncserver

 

Solution 1 - Only one type of connection needed

This solution allows only one geometry set, ie you can set it up for 1024x768x16, and everyone does this. by accident, I discovered that lightdm has this built in (probably other login managers do also, but I am using lightdm). Simply edit the file /etc/lightdm/lightdm.conf and, at the bottom, change the appropriate sections as follows (the ellipsis means there is some stuff in between).

[XDMCPServer]
enabled=true
port=177
#key=
 .... 
[VNCServer]
enabled=true
port=5900
width=1024
height=768
depth=16

Uncomment all sections, set the parameters as you want, then restart lightdm

/etc/init.d/lightdm restart

Open a VNC connection to port 5900 (or whatever you reset it as) and you should see a login screen

 

Solution 2 - Multiple geometry

The problem with the above is that it only allows one geometry, which means everyone connecting must use the least common denominator (something like 1024x768x16, but even that is too big for netbooks and some tablets). This solution is somewhat more complex, but gives you the ability to set up multiple geometries, attaching each one to a different vnc port.

Check if xinetd is installed (generally not in a standard install), then install it if not

 

apt-get install xinetd

 

Now, you should create a file in /etc/xinetd.d. It can be whatever you want, but I just call it vnc. It's initial contents are below.

 

service vnc
{
   disabled    = no
   socket_type = stream
   protocol    = tcp
   wait        = no
   user        = nobody
   server      = /usr/bin/Xvnc
   server_args = -inetd -once -query localhost -geometry 1024x768 -depth 16
   type        = UNLISTED
   port        = 5900
}

 

Now, edit /etc/lightdm/lightdm.conf, enabling the XDMCP Server. I've included the commented out VNC server section in case you tried Solution 1 already

 

[XDMCPServer]
enabled=true
port=177
#key=
 .... 
#[VNCServer]
#enabled=false
#port=5900
#width=1024
#height=768
#depth=32

 

This creates basically the same configuration as Solution 1; a VNC service that will answer on port 5900 giving a 1024x768x16 screen. To try it out, restart xinetd and (if you modified it) lightdm.

 

/etc/init.d/xinetd reload # if it is not started, use "start" instead of "reload"
/etc/init.d/lightdm reload # if you made a change to the configuration file

 

You can now use your favorite VNC viewer to connect on port 5900. It will look the same as Solution 1, ie it will have 1024x768x16.

 

The real reason for this solution, however, is the ability to have different geometries. In our case, we have a netbook (1024x600x16), two laptops (1024x768x16), a workstation with 1400x900 (1400x900x16) and another workstation with a big screen and great network connection (1860x1100x24). All we need do is edit /etc/xinetd.d/vnc and add sections. I named each one with something that made sense to me.

 

service vnc
{
   disabled    = no
   socket_type = stream
   protocol    = tcp
   wait        = no
   user        = nobody
   server      = /usr/bin/Xvnc
   server_args = -inetd -once -query localhost -geometry 1024x768 -depth 16
   type        = UNLISTED
   port        = 5900
}

service vnc_netbook
{
   disabled    = no
   socket_type = stream
   protocol    = tcp
   wait        = no
   user        = nobody
   server      = /usr/bin/Xvnc
   server_args = -inetd -once -query localhost -geometry 1024x600 -depth 16
   type        = UNLISTED
   port        = 5901
}

service vnc_workstation
{
   disabled    = no
   socket_type = stream
   protocol    = tcp
   wait        = no
   user        = nobody
   server      = /usr/bin/Xvnc
   server_args = -inetd -once -query localhost -geometry 1400x900 -depth 16
   type        = UNLISTED
   port        = 5902
}

service vnc_big_workstation
{
   disabled    = no
   socket_type = stream
   protocol    = tcp
   wait        = no
   user        = nobody
   server      = /usr/bin/Xvnc
   server_args = -inetd -once -query localhost -geometry 1860x1100 -depth 24
   type        = UNLISTED
   port        = 5903
}

Reload xinetd so it knows about the new parameters

/etc/init.d/xinetd reload

Now, you will get a different resolution depending on how you connect (which port you use).

 

PortGeometry
5900 1024x768x16
5901 1024x600x16
5902 1400x900x16
5903 1860x1100x24

 

Efficiency

Efficiency is a trade off between the amount of bandwidth necessary to transmit the screen, the usefulness of the resultant image (your view is a series of changing images) and the amount of processor required to compress the changes before being transmitted. Increasing one of these will decrease the other two.

 

When you move a window, open a new appilication, or even simply move your mouse across the screen, most VNC servers will determine only what has changed and simply transmit the changes. Much better than retransmitting the entire screen every few milliseconds. When you make a change on the screen, a good system will do the following:

  1. Create a list of pixel changes between the previous and current picture
  2. Compress the changes in a manner the client knows how to decompress
  3. Transmit the changes to the client
  4. Look for additional activities

This is a very simplified description. The bottom line is, decreasing the amount of information that needs to be transmitted from the server to the client greatly increases the usability of the system. Watching a video on a remote terminal is feasible, if you have a few dedicated processors on both machines (to compress/decompress), a very fast, dedicated network and don't mind a few skipped frames. But, there are better solutions.

However, to work across an VPN connection to a virtual where you want to support multiple users with the minimum amount of cpu, memory and bandwidth is a different story. The bottom line here is remove all eye candy. The following helps.

  • Remove any background on the server's session. When you move, resize, open or close a window, if it is overwriting a solid image (no background), there is less information to be transmitted and solid backgrounds are very fast and easy to compress well. (Settings | Desktop, change image to None).
  • Turn off color gradients. Use solid color for the whole background. Same reason as above. (Settings | Desktop, change colors to solid). I usually set the background color to something that helps me read easily like blue or black, but feel free to have something best for you. But, something with lots of F's and 0's really works on lower color depths.
  • Turn off screen savers. They are useless in this environment and can greatly delay the wake up time. Also, if you leave a session open and it has a screen saver running, I've seen it peg a processor making all the pretty stuff. (Settings | Screen Savers | Mode: Disable)
  • In XFCE4, open the Window Manager (Settings | Window Manager | Advanced) and place check's in "Hide contents of windows when resizing" and "Hide contents of windows when moving"
  • In XFCE4, open Window Manager Tweaks (Settings | Window Manager Tweaks | Compositor) and uncheck Enable display compositing
  • Use the minimum color depth you can work with. 8 bit color uses four times less information than 16 bit color. That is a 75% savings at the beginning; compression, transmission, decompression and display are all sped up greatly. This is the single most important tweak you can make. 16 bit is the absolute maximum as far as I'm concerned, and 8 bit beats the fire out of it. In our case, most of the reason we are using the GUI is to open multiple terminal sessions, so 8 bit is more than sufficient. Anything more than 24 bit can not even be discerned by most humans and is really only useful for camera post processing.
  • Balance compression (processor intensive) with bandwidth (network intensive). Generally, this can be accomplished via a flag on the client, generally called compression (higher numbers take more processor and memory to calculate, but decrease the amount of information going over the network.

I go overboard a little in that I don't even want the splash page on lightdm to have a background image. To fix this, edit /etc/lightdm/lightdm-gtk-greeter.conf and commount out the line in section [greeter] which sets the background:

[greeter]
#background=/usr/share/images/desktop-base/login-background.svg

again, restarting lightdm is required for this to take effect.

 

Choosing a client

There are many, many clients and they all have good things. I choose tightvncviewer because it is fast, I can script it, and it works well with xtightvncserver.

apt-get install xtightvncviewer

My friend Dave gave me what he thinks is the best command line for this. I don't know, but until I find something I like better, I'll go with it.

vncviewer -compresslevel 6 -encodings "copyrect tight hextile zlib corre rre raw" -quality 5 ip:port

Where IP and port are the IP and port numbers for the target, separated by a colon. To turn this into a script, simply create a file with #! /bin/bash at the beginning, copy the above command, chmod it to 755 and put it where you can find it (I use my desktop).

 

Sharing Desktop

As I said at the beginning, the only disadvantage to this is sharing a desktop, ie letting people look over your shoulder. For this, I use a very basic server installed on the server machine, the x11vnc server

apt-get install x11vnc

I'm not going to go into the configuration of this right now; simply look in Internet menu item for X11 VNC Server.

 

Bibliography

Last update:
2013-12-01 08:08
Author:
Rod
Revision:
1.4
Average rating: 4 (1 Vote)

You cannot comment on this entry

Chuck Norris has counted to infinity. Twice.

Records in this category

Tags