[2024-feb-29] Sad news: Eric Layton aka Nocturnal Slacker aka vtel57 passed away on Feb 26th, shortly after hospitalization. He was one of our Wiki's most prominent admins. He will be missed.

Welcome to the Slackware Documentation Project

This is an old revision of the document!


Starting ''Xvnc'' on-demand

A nice refinement is to configure the remote host to automatically create for each user a permanent virtual terminal.

The virtual terminal gets created when the user first connects. The user can detach from their terminal and reattach from elsewhere, providing true persistent terminal service. The terminal persists until either

(i) the user destroys it by logging out, or

(ii) the system operator destroys it by rebooting.

Remote host listener

The remote host needs an inetd running. Assign each user a display in inetd.conf. The lines in inetd.conf might look something like this:

5901 stream tcp wait arfon  /usr/bin/Xvnc Xvnc -Log *:syslog:30 passwordFile=/home/arfon/.vnc/passwd  -inetd -query localhost -once
5902 stream tcp wait metaed /usr/bin/Xvnc Xvnc -Log *:syslog:30 passwordFile=/home/metaed/.vnc/passwd -inetd -query localhost -once
5903 stream tcp wait doe    /usr/bin/Xvnc Xvnc -Log *:syslog:30 passwordFile=/home/doe/.vnc/passwd    -inetd -query localhost -once
5904 stream tcp wait roe    /usr/bin/Xvnc Xvnc -Log *:syslog:30 passwordFile=/home/roe/.vnc/passwd    -inetd -query localhost -once

This arranges that when a VNC viewer connects to port 5901, an Xvnc is started for user arfon, creating virtual terminal :1. User metaed uses port 5902 and gets terminal :2, and so on down the list.

If this is the first time you’ve used inetd, you might need to get it running. Example:

# chmod 755 /etc/rc.d/rc.inetd
# /etc/rc.d/rc.inetd start
# pgrep -l inetd
27849 inetd

Connection procedure

To use, there is a two step procedure. First, the end user connects using ssh to the remote host and tunnels their assigned port number to their physical terminal. In PuTTY, user arfon would go to Connection, SSH, Tunnels, and set Source to 5901 and Destination to localhost:5901. An equivalent ssh command line would be:

$ ssh -L 5901:localhost:5901 arfon@terminalserver.example.com

Second, the end user connects using vncviewer to the local end of the tunnel (localhost:5901).

I've seen at least one VNC viewer (bVNC) that has builtin support for ssh and combines these into one step, but haven't tried that.

Display manager configuration

This depends entirely on which display manager you have available, and is really outside the scope of this how-to. Here is just a simple example. Supposing you want to use bog-standard xdm. You would:

  • Open /etc/X11/xdm/xdm-config.
  • Edit the line DisplayManager.requestPort: 0.
  • Disable the line by inserting a ! at column 1. This lets xdm listen on its UDP port for session requests. As noted below under Security considerations, you do NOT punch a hole in your firewall for this port.
  • Open /etc/X11/xdm/Xaccess.
  • Edit the line #* #any host can get a login window.
  • Change the * at column 2 to localhost.
  • Enable the line by deleting the # at column 1. This lets only virtual displays local to your remote host get a login window.

You might not want your xdm trying to manage the console. If that is so:

  • Open /etc/X11/xdm/Xservers.
  • Edit the line :0 local /usr/bin/X :0.
  • Disable the line by inserting a # in column 1. This tells xdm not to try to manage the console.

You will also need to change the remote host’s default runlevel from 3 to 4. This tells init to run your display manager by spawning /etc/rc.d/rc.4, and respawn it if it dies.

  • Open /etc/inittab.
  • Edit the line id:3:initdefault:.
  • Change 3 to 4 in column 4.
  • To make the change immediately without rebooting, run telinit 4.

For extra credit, you can customize rc.4 by creating a file /etc/rc.d/rc.4.local. See rc.4 for details.

After authentication, xdm runs the user’s $HOME/.xsession script. You, or they, will have to provide one. A dirt simple one could be:

xterm &
twm

Security considerations

There are several layers of security available to protect the remote virtual terminals from unauthorized use.

Firewall

The first layer of security is the remote host’s firewall. Firewall configuration is outside the scope of this how-to, but here is a brief outline of what you need. The firewall ought to deny remote connections by default. So if you already block all ports by default, no change is needed. You will NOT be punching holes in your firewall to make this work. Supposing your remote host provides only SSH service, and you use the nftables firewall, you probably have a rule chain something like this:

type filter hook input priority 0; policy drop;
ct state vmap { 0x1 : drop, 0x2 : accept, 0x4 : accept }
iifname "lo" accept
tcp dport 22 accept

With such a firewall in place, you are properly secured.

Encryption

Configured as recommended above, all VNC traffic between the remote host and the local terminal is encrypted, because it travels on the ssh tunnel.

Authentication

There are several authentication layers available.

  1. An ssh key is needed to create the tunnel.
  2. The terminal can be secured using vncpasswd, to prevent another authenticated user from “walking up to your terminal”.
  3. The -query localhost option tells Xvnc to ask a display manager process for an assist. The display manager prompts the user to authenticate using a password, just the way a physical terminal would, before creating the user session.
  4. The user can xlock the display before detaching. This will prompt for the user password.

References

 talk:howtos:window_managers:vnc ()