VNC, Securely: Part 2
In Part 1 of this series, we learned how to set up transparent usage of a VNC desktop both remotely across a network and on a console, via a display manager, in such a way that the same desktop (and its desktop state) is available from both types of locations. In Part 2 we talk about making this ubiquitous access more secure. We'll be using OpenSSH from www.openssh.org, but other implementations of SSH may work as well.
Our goal is to access our VNC desktop in a secure manner from any location. By secure, we wish to have both strong authentication, thus ensuring only authorized individuals can access the desktop, as well as privacy, so that no one can see the contents of our desktop or what instructions we are sending it.
This article will use Linux computers as both the clients and the server. We will concentrate on using the VNC client called vncviewer and the OpenSSH implementation of the SSH Secure Shell protocol.
As per the first article, we have a VNC-based desktop running on our server. We'll refer to this server as "myhost". Also on this server is sshd, the SSH server. On the client we need to have the SSH client, ssh.
As figure 1 shows, we'll use ssh on the client machine to create an encrypted and authenticated tunnel between client and server. Then we'll configure vncviewer to use that tunnel to show the desktop on the client.
Please refer to "The 101 Uses of OpenSSH: Part I & Part II" by Mick Bauer (Linux Journal, December 2000 and January 2001) for proper setup of OpenSSH, if it hasn't been set up already. My Red Hat 7.1 install has it preconfigured.
As described in those articles, you'll want to configure your client system to use either "null-passphrase" keys or an ssh-agent to cache your passphrase. If you prefer use only passwords, you will not be able to automate the SSH tunnel for our remote VNC desktop via a script.
You might be asking "Is VNC insecure?" As always when dealing with security, the answer is "It depends." The factors it depends on are: what is the likelihood of penetration or exploit, and how bad would it be to be exploited?
The VNC protocol is not without its own defenses. It uses a DES challenge-response handshake for authentication, which is better than sending passwords, like Telnet or FTP do. But with the power of today's commodity computers, DES is not very secure against brute force attacks. Besides this, VNC tries to secure only authentication; it does not make the connection private. SSH can do that for us.
Recall from the first article that we configured VNC to start up in the file /etc/sysconfig/vncserver (on an Red Hat 7.1 system). We added this line:
VNCSERVERS="1:jdimpson"(where jdimpson is your own user name).
The number prepended to the user name, 1 in this case, tells the server what VNC session number is mapped to each user.
For each session number, VNC will listen on three different network sockets. If N is the session number, VNC server will listen on 5800 + N for HTTP connections, on 5900 + N for VNC RFB connections and on 6000 + N. This last port allows X applications to connect to the VNC server. So in our case, the ports that VNC uses are 5801, 5901 and 6001.
We want to prevent any connections to the VNC server from a remote or external client. We do want local applications to be able to connect, though. To do this we will use Linux's built-in firewalling utilities. There are currently two such utilities. On my Red Hat 7.1 box, ipchains and iptables are installed. Although iptables is the newer and more powerful implementation, Red Hat seems to favor the usage of ipchains.
If you know something about firewalls, and have already configured your system so that the default input rule is DENY, you can skip this section. But you must make sure that you ALLOW SSH traffic (port 22). Otherwise, you should run the following commmands:
ipchains -A input -s 0.0.0.0/0.0.0.0 -d 0.0.0.0/0.0.0.0 5801:5801 -p 6 -j DENY -l
ipchains -A input -s 0.0.0.0/0.0.0.0 -d 0.0.0.0/0.0.0.0 5901:5901 -p 6 -j DENY -l
ipchains -A input -s 0.0.0.0/0.0.0.0 -d 0.0.0.0/0.0.0.0 6001:6001 -p 6 -j DENY -l
If your server is a gateway to an internal LAN, and you want to allow hosts from the internal LAN access to VNC without needing to use SSH, you can add the flag -i ethX (where ethX is the network interface on any external, untrusted network).
It might be easier (and more secure) to block all ports from 5800 to 6010. Then you can start as many VNC (and X) sessions as you wish, without worrying about reconfiguration:
ipchains -A input -s 0.0.0.0/0.0.0.0 -d 0.0.0.0/0.0.0.0 5800:6010 -p 6 -j DENY -l
(Note: when I configure firewalling rules and set up a rule for a TCP connection like above, for symmetry I usually also set up a similar rule for UDP traffic. You can accomplish this my running the ipchains commands again, using -p 17 instead of -p 6.)
The flag -l says to log data to syslog, so you can look at /var/log/messages (or similar) to see if it works. Test by using a VNC client (like vncviewer) to try to connect. You should see log messages like those in Listing 1.
Listing 1: ipchains' Log Messages in /var/log/messages Showing Blocked Connections to Port 5901
Now only VNC clients that are running locally are able to connect to the VNC server.
Remember that unless you do something about it, these rules will be put back into place on reboot. Some systems (like Red Hat 7.X) let you save ipchains configurations by running /etc/init.d/ipchains save. Otherwise, see the man page for ipchains-save.
If you use iptables, the rules you want are
iptables -A INPUT -p tcp --sport 5801 -j DROP
iptables -A FORWARD -p tcp --sport 5801 -j DROP
iptables -A INPUT -p tcp --sport 5901 -j DROP
iptables -A FORWARD -p tcp --sport 5901 -j DROP
iptables -A INPUT -p tcp --sport 6001 -j DROP
iptables -A FORWARD -p tcp --sport 6001 -j DROP
See netfilter.filewatcher.org for more information.
Trending Topics
| You Need A Budget | Feb 10, 2012 |
| The Linux powered LAN Gaming House | Feb 08, 2012 |
| Creating a vDSO: the Colonel's Other Chicken | Feb 06, 2012 |
| Your CMS Is Not Your Web Site | Feb 01, 2012 |
| Casper, the Friendly (and Persistent) Ghost | Jan 31, 2012 |
| Razor-qt 0.4 - Qt based Desktop Environment | Jan 30, 2012 |
- Fun with ethtool
- Linux-Based X Terminals with XDMCP
- 100% disappointed with the decision to go all digital.
- Parallel Programming with NVIDIA CUDA
- Readers' Choice Awards 2011
- You Need A Budget
- Validate an E-Mail Address with PHP, the Right Way
- The Linux powered LAN Gaming House
- The Linux RAID-1, 4, 5 Code
- RSS Feeds
- Gnome3 is such a POS. No one
7 hours 50 min ago - Gnome 3 is the biggest POS
8 hours 1 min ago - I didn't knew this thing by
14 hours 5 min ago - Author's reply
17 hours 30 min ago - Link to modlys
18 hours 36 min ago - I use YNAB because of the
18 hours 48 min ago - Search
23 hours 51 min ago - Question
1 day 14 min ago - for the record
1 day 17 min ago - That's disappointing. Thanks
1 day 2 hours ago






Comments
Doesn't works allways
I tried to do a conection tunneling vnc between two machines with Linux and it doesn't work. Both PC's are behind ADSL routers. The remote router as the port 22 redirected to port 22 of the remote PC. My router doesn't have any port redirected. Both routers have the firewall off.
Both PC's have the firewall off and both are clean of restrictions in iptables or ipchains.
Connection is always refused.
But, I can start an SSH session on the remote with -X and -C and run there the vncserver and the vncviewer so SSH transports to me the viewer.
Re: VNC, Securely: Part 2
Why do the iptables above use --sport? Shouldn't they be protecting against connections to the relevant --dport from the outside? I was also wondering what the FORWARD rules protect against.
I'm not an iptables expert by any stretch, but presuming that the host running the vncserver is IP 192.168.1.187, I was expecting something more like this:
iptables -A INPUT -p tcp -s 192.168.1.187 --dport 5801 -j ACCEPT
iptables -A INPUT -p tcp --dport 5801 -j DROP
iptables -A INPUT -p tcp -s 192.168.1.187 --dport 5901 -j ACCEPT
iptables -A INPUT -p tcp --dport 5901 -j DROP
iptables -A INPUT -p tcp -s 192.168.1.187 --dport 6001 -j ACCEPT
iptables -A INPUT -p tcp --dport 6001 -j DROP
The specific IP address could also be replaced by the vncserver's hostname as long as the hostname maps to the actual ethernet IP and not 127.0.0.1. You need the specific IP because ssh forwarded tunnel appears to make all the incoming packets look like they're coming from that IP, not localhost.
Hope this helps.
Re: VNC, Securely: Part 2
This article deals with security by SSH. I have found however that the biggest security risk of VNC is that a new connection will result in the old connection being dumped (ie., people can walk straight in onto your desktop.)
This patch to the VNC source, 3.3.3r1 and r2, modify this behaviour: an existing connection will be given priority over an incoming one. This of course still means you should log off your VNC desktop when you're not using it, thus defeating the first article, but I'm not up for too much source hacking ;).
Personally I use VNC to share XDM desktops (you connect to VNC, then login) and log them out after use. This means that over an untrusted LAN I can still have reliable access to my desktop. To do this, add an Xvnc line with appropriate resolution and colour depth to your Xservers file. (/usr/dt/config on Solaris, /etc/X11/xdm on my Linux box - not RH 7.1.)
Save this to a file, and use patch to apply this context diff and rebuild your source tree for the modification.
Re: VNC, Securely: Part 2
Should it be colour depth?
Re: VNC, Securely: Part 2
Technically, I do mean color depth. The idea was that the quality of the picture is less. With lower bit depth, you can actually resolve less information, but that isn't the proper technical way to use the word "resolve" in this context.
--Jeremy Impson