0

When I ssh -X to a server, I will be assigned a $DISPLAY value, usually localhost:x.0 where x is the lowest number unused by all the users starting from 10. (e.g., if no other user uses $DISPLAY, then it is 10. If some user is already using 10, then it will be 11, etc)

Now my question is: is there a way to specify a number for x when doing ssh -X, like 100.

My purpose is to have a detached program keeping running on the server that always use localhost:100.0 as its display. Then even if I lost the X connection to the server, I can re-login and still establish a connection to localhost:100.0 without worrying about other users occupying the same port during my disconnection. Choose a number as big as 100 can avoid most of the possibilities that it get occupied, comparing to the default 10.

  • If you have an X application that can tolerate disconnecting from and reconnecting to its X server, then a better solution might be to have a way (other than the environment variable) to tell the app which server it should connect to. For example store the display name in a file and have the app check the file periodically. Or split the app into two parts, a core app which runs as a daemon and a UI frontend which connects to the core app. – Kenster Jul 3 '20 at 12:05
  • Thanks @Kenster. That application is actually jupyter lab, I have no much way to modify it. xserver is only needed when I use matplotlib to plot something. When get disconnected, the displayed figures will go away, but after reconnection I can replot. – Liu Sha Jul 3 '20 at 12:12
1

is there a way to specify a number for x when doing ssh -X, like 100.

No, because not only will the number need to be "assigned", ssh also needs to forward the X protocol on the corresponding local socket for that number. And there's no guarantee that "number" will be free when ssh connects. That's why ssh provides no option for this.

Then even if I lost the X connection to the server, I can re-login and still establish a connection to localhost:100.0

This is not going to work, because the server is the X server on your local machine (the one you ssh from), and the client programs are running on the remote machine. So all client programs would need to re-establish the connection (because there's state involved).

If you want a remote desktop you can reconnect to, consider using something like VNC.

  • Thanks. But the second part is not always correct. For an example, if a program (with environ $DISPLAY=localhost:10.0 set when launched) is monitoring a file change (this part does not need X display) and once found, call system(xeyes) to show an xwindow, the X display sockets only needs to be present when the call to system() is made. If before this call, I reestablished the connection with $DISPLAY=localhost:10.0, the window can still be displayed correctly. If at the point of the call, I am still disconnected, then the call just fails and the program can still continue to run. – Liu Sha Jul 3 '20 at 2:44
  • "And there's no guarantee that "number" will be free when ssh connects. That's why ssh provides no option for this." I wish ssh could let us assign this number and fail to connect if the specified number is occupied. But ssh just works as what you said – Liu Sha Jul 3 '20 at 4:13
  • You can always change the source code of ssh and add an option to set the display number, if you think that's the ideal solution for your problem. – dirkt Jul 3 '20 at 4:57
0

I found two methods:


The first one

  1. from local machine, ssh -X remote
  2. get the display port number echo $DISPLAY | awk -F'[:.]' '{print $2}', assume it is 10
  3. check whether port 6020 in remote is used: lsof -i TCP:6020, assume it is not
  4. forward the port 6020 to 6010: ssh -NTR 6020:localhost:6010 localhost optionally add -f (need to remember to kill this process when exit if -f is used, recommend trap "kill $!" EXIT
  5. set env: DISPLAY=${DISPLAY/:10/:20}
  6. update ~/.Xauthority to let display port localhost:20.0 get the same xauth magic key: xauth add $(xauth list :10 | sed 's/:10/:20/')

Alternatively

  1. ssh to remote without using -X: ssh remote
  2. in remote machine set DISPLAY=localhost:20.0
  3. in local machine, forward remote port 6020 to the local machine's xserver socket /tmp/.x11-unix/X0: ssh -NTR 6020:/tmp/.x11-unix/X0 remote, optionally add -f
  4. transfer the local machine's xauth key to the remote machine: in local xauth list :0, assume it is local-hostname:0 MIT-MAGIC-COOKIE-1 hash
  5. in remote machine: do xauth add remote-hostname:20 MIT-MAGIC-COOKIE-1 hash.

Comparing these two methods, the first one doesn't need to transfer the local machine's xauth key to the remote machine, which MAYBE more secure (could any expert tell what potential security issue can raise if I do so?). But it needs to occupy two ports: the one assigned by ssh -X and the one that you want to use.

-1

I know of no way to specify the DISPLAY.

On Linux (or at least on Ubuntu), displays are just sockets in /tmp/.X11-unix/. For example: /tmp/.X11-unix/X0 is display :0

So you could move any socket to any other path, and it would still work. (I'm not sure if this is true of ssh-forwarded X connections, but it may be.)

(BTW, ssh -Y may be more secure than ssh -X, but it has been a long time since I used either.)

In any case, if the socket closes (due to an SSH connection ending), any programs running on that socket may quit and exit.

If you want to run persistent X programs, look at running a VNC server, and connecting to it with a VNC client. You can tunnel the VNC connection securely with SSH. I do this regularly. I believe you can run a VNC server on a "virtual" display (meaning you will only be able to see that display if you connect with a VNC client), but I have never done this.

UPDATE

So X11 forwarding over SSH probably involves 3 elements:

  1. A TCP socket at some port
  2. The DISPLAY variable
  3. Some form of handling X-authority requirements

All three of these can be done manually. You can manually forward any port using -R. You can manually set DISPLAY. You can (probably?) manually adjust the X-authority settings somehow. Handling the X-authority is probably the trickiest, and I do not know how to do it, but I suspect it can be done.

If you do 1, 2 and 3, you should be able to forward X11 connections while using neither -X nor -Y.

I still suspect most X programs will exit when their connection to the server closes.

I still believe setting up a VNC server and client will give you better result.

  • What do you mean by "you could move any socket to any other path and it would still work"? I feel this may provide an alternative way to fit my purpose. The connection between /tmp/.X11-unix/X0 to :0 is hard coded, right? If some program opened /tmp/.X11-unix/X0 for write and I moved the file to /tmp/.X11-unix/X100, what will happen? – Liu Sha Jul 3 '20 at 2:51
  • there is no /tmp/.X11-unix/X10 for localhost:10.0. where does the socket reside – Liu Sha Jul 3 '20 at 3:03
  • 1
    in datacadamia.com/ssh/x11/display it says: localhost:10.0 just means TCP port 6010 – Liu Sha Jul 3 '20 at 3:13
  • I believe that already established connections will continue working if you move a Unix-domain socket. New connections will need to happen at the new path. I have also provided additional suggestions in the answer (see the update). – mpb Jul 3 '20 at 6:39

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.