VNC over SSH and SOCKS

Do you have a question? Post it now! No Registration Necessary.  Now with pictures!

Threaded View
    I am trying to establish a VNC connection from my local box to a remote
one over SSH, so far without success. Here is my setup:

    My local box, A, is the one where I will launch the VNC client,
vncviewer. The remote machine, B, is already running a VNC server,
listening on port 5901.

    A is behind a firewall. A is granted access to the external world by means
of a socks server. I have no control over this.

    B is behind another firewall F. F is a Linux box running
iptables, with a set of rules such that connections arriving at ports 5901
and 22 on the external network interface of F are transparently forwarded
to B, in the internal network. F is doing IP masquerading for B (among
other Linux boxes, which are not relevant to the issue I am bringing up

    I can establish SSH connections from A to B without any problems,
provided that I run the ssh command in socksified form. The connections
are opened to the external network interface of F; i.e. running

    runsocks ssh FIP

(where FIP is the IP address of F's external network interface) from
A gives me a shell on B, as expected (the SSH infrastructure is already
correctly set up on both ends so that no password is required).

    Likewise, from A I can establish successful connections to the VNC server
in B as follows:

    runsocks vncviewer FIP:1

    Now how can I establish VNC connections from A to B over SSH?

    I have read some documents on the subject, and it seems to be the case
that one has to do some SSH port forwarding on the machine where the VNC
client is to be launched. In my case, on A I would have to do the

    ssh -L 5901:localhost:5901 FIP

This doesn't work, as expected, for we need to go via the socks server in
order to have access to the exterior world, where B is. I therefore
socksified it:

    runsocks ssh -L 5901:localhost:5901 FIP

This returns the following error message:

    listen: Bad file descriptor
    channel_setup_fwd_listener: cannot listen to port: 5901
    Could not request local forwarding.

while at the same time giving me a shell in B.

    I am sure that I misunderstanding something in the basic SSH setup for,
when invoking the ssh command above with -v, I get the following:

    debug1: Connections to local port 5901 forwarded to remote address
    listen: Bad file descriptor
    channel_setup_fwd_listener: cannot listen to port: 5901
    Could not request local forwarding.

    This I do not understand, for I want to forward connections to port 5901
on the local host (A) to the remote address - not A again. I would have
thought it would make more sense to do

    runsocks ssh -L 5901:FIP:5901 FIP

With this I get

    debug1: Connections to local port 5901 forwarded to remote address

which sounds more like it. However, the Bad file descriptor stuff is still
there :-(

    I have tried to substitute -R for -L, and although in this case there is
no Bad... error, the debugging message

    debug1: Connections to remote port 5901...

are far less reassuring. And, anyway, under no circumstances have I been
able to get the command

    vncserver localhost:1

invoked on A (socksified or not) to succeed.

    I think I have some fundamental misunderstanding about the way SSH does
its job. I would appreciate it if anyone can throw some light into the
situation I have described here.

Re: VNC over SSH and SOCKS

(Mea culpa:  I may be entirely wrong.)

SKH wrote:
Quoted text here. Click to load it
Something like this, if I understood correctly:
.---.  .----------.                  .---.   .---.
| A |--| socks fw |--// internet //--| F |---| B |
`---'  `----------'                  `---'   `---'

F:22 and F:5901 both forward to B

 >    runsocks ssh -L 5901:localhost:5901 FIP

This should be saying "Open an SSH connection to FIP:22, and listen on
A:5901, and connect that to localhost:5901 on FIP."  Of course, since
FIP is redirecting you to B, that should all be fine.

Quoted text here. Click to load it

First guess:  Is there a vncserver already running on A:5901?

Second guess:  Is VNC on B set to allow loopback connections?

Quoted text here. Click to load it

This depends on how well F and B talk to each other.  Since you're
SSH'ing to B (via FIP), it's B that interprets "FIP:5901".  When you VNC
to "FIP:5901" from B, are able you to see your own desktop?  (It's an
unpleasant recursive experience.)


Re: VNC over SSH and SOCKS

On Thu, 05 Feb 2004 00:36:37 +0000, Jim Davis wrote:

Quoted text here. Click to load it

    Thanks for bothering to reply, even if you are.

Quoted text here. Click to load it

Quoted text here. Click to load it

    Nope. I don't think that is the problem anyway, for the error message I
report seems to happen no matter what port numbers I use. For instance,
something like

    runsocks ssh -L 8821:localhost:8732 FIP

produces the same result. There is no one listening on ports 8821 or 8732
on any of the boxes involved here.

Quoted text here. Click to load it

    That I hadn't. However, it makes no difference :-(
Quoted text here. Click to load it

    They do so very well, for all I know. For all other purposes, as long as
it works one can't tell that F is there.

Quoted text here. Click to load it

    That I can't do, because B is behind the firewall F, and doesn't have
access to FIP, F's external network interface.

Re: VNC over SSH and SOCKS

    OK, I got it working all right. Here's a summary, in case anybody is
interested not to make the same mistakes I made.

    First, my SSH software has been built with socks support, which I did not
know and, much to my embarrassment, never bother to test. Thus (using the
notation of my original posting) if in A I invoke

    ssh B

then I get a shell in B, just as I do with

    runsocks ssh B

    Now as far as port forwarding is concerned, runsocks seems to interfere
destructively with SSH. Indeed

    runsocks ssh -L x:localhost:y FIP

seems to fail all the time, in the same way, no matter what port numbers x
and y I use. However, invoking

    ssh -L x:localhost:y FIP

does the right thing, at least when x and y are port numbers used in VNC -
in my case, both x and y are 5901.

    Second, after invoking

    ssh -L 5901:localhost:5901 FIP

I was of course getting a shell on B, as expected. I just did not know
that the port forwarding remains active as long as the shell is up. If one
exits the shell immediately, the VNC connection will never succeed.

    Anyway, once all of the above is understood and done properly,

    vncviewer localhost:1

on A does indeed establish a successful connection to the VNC server on A.
Much to my delight, the performance of this SSH connection seems to be
much snappier than the direct one by means of

    vncviewer FIP:1

At the very least, the mouse pointer moves much more smoothly.


Re: VNC over SSH and SOCKS

Quoted text here. Click to load it

There are two possible causes for this.

The first is that some "ssh" binaries are setuid root (because they need
to bind() to low-numbered ports and need to read the host private key
for some authentication methods).  runsocks uses LD_PRELOAD to intercept
the function calls for connect() and friends, and for safety reasons
setuid binaries do not honour LD_PRELOAD.

The second possibility is the socks config itself.  Assuming an NEC-style
config, if you have something like this in your libsocks5.conf:
#proxy  cmd   dest-host    dest-port    [userlist [proxylist]]
socks5  -     -            -            -

Then the "cmd" of "-" is a wildcard that means "send all operations
*INCLUDING* the bind() to the socks server".

Attempting to establish a port forward with this configuration will
attempt to create a listening socket on your socks server which may
not permit it.

If this is the can you can change "cmd" to "c" to socksify only the
connect() calls and not bind(), which will probably work.

Darren Tucker (dtucker at
GPG key 8FF4FA69 / D9A3 86E9 7EEE AF4B B2D4  37C9 C982 80C7 8FF4 FA69
    Good judgement comes with experience. Unfortunately, the experience
usually comes from bad judgement.

Site Timeline