xpra icon
Bug tracker and wiki

Opened 4 years ago

Last modified 4 months ago

#675 new enhancement

Extend Xpra proxy for terminal server deployments

Reported by: sschnitzer Owned by: sschnitzer
Priority: minor Milestone: future
Component: server Version: trunk
Keywords: Cc:

Description

In order to use Xpra as a terminal server a couple of features are missing:
a) Spawning a dedicated xpra session for each user (currently you even have to do this in advance, since you don't know when which user will connect)
b) Watch for crashed Xpra processes and respawn them
c) Provide a mechanism to allow a user to reset all his remote processes (e.g., if Xpra and X11 are still running but don't work correctly anymore)
d) Consider updates to xpra.auth (deleted or added users) by killing processes or spawning new ones.

It would be great if this functionality could be integrated into Xpra.
Some thoughts on how this could be implemented:
The xpra.auth file contains the list of valid users (no ip addresses or ports, though). The proxy process maintains a list of all running xpra instances. If a users connects it either spawns a new xpra process or reuses the existing. The proxy could forward the network traffic to the child xpra using UNIX pipes (replacing tcp sockets for local host communication). Additionally, the proxy should react on some custom signal that tells to reread xpra.conf. Moreover, a client side command line option could be added that causes the server to terminate all of the users processes (after authorization of course).

Change History (10)

comment:1 Changed 4 years ago by Antoine Martin

Milestone: 1.0
Owner: changed from Antoine Martin to sschnitzer
Priority: majorminor

Spawning a dedicated xpra session for each user


That would be pretty easy to do I think.

Watch for crashed Xpra processes and respawn them


How often does this really happen?

Provide a mechanism to allow a user to reset all his remote processes


I don't understand what that means.

Consider updates to xpra.auth


I assume that by xpra.auth you mean the file used by the file auth mechanism?
If so, it already reloads the file whenever it is modified.

If a users connects it either spawns a new xpra process or reuses the existing


So this would effectively limit to one session per user.

should react on some custom signal that tells to reread xpra.conf


What for? That would very hard to do right.

a client side command line option could be added that causes the server to terminate all of the users


Running xpra stop against the master proxy process stops it (including all proxy instances).
We could easily add an xpra control :MASTERPROXYDISPLAY stop control command to call this stop_all_proxies function.
As you may already know, individual proxy instances can be stopped with xpra stop, so I guess this can also be scripted.

comment:2 in reply to:  1 Changed 4 years ago by sschnitzer

Replying to totaam:

Spawning a dedicated xpra session for each user


That would be pretty easy to do I think.

Watch for crashed Xpra processes and respawn them


How often does this really happen?

Rarely, I hope. However, if it happens, there should be a way for users to recover without admin intervention.


Provide a mechanism to allow a user to reset all his remote processes


I don't understand what that means.

I basically meant "killall -u $userid". I had already issues with programs like dbus that survived the shutdown (or crash, don't remember) of xpra and went into a nonfunctional state. So if I tried to start a new dbus process with a new xpra server, the dbus failed due to the still running (nonfunctional) dbus. Only way out: kill the old dbus.


Consider updates to xpra.auth


I assume that by xpra.auth you mean the file used by the file auth mechanism?
If so, it already reloads the file whenever it is modified.

Thats right. I didn't know about the automatic reload. Additionally, I guess that existing xpra sessions are not killed if the entry is removed from the xpra.auth file, right?


If a users connects it either spawns a new xpra process or reuses the existing


So this would effectively limit to one session per user.

Correct. This limit would only apply to "terminal server mode". If needed, another client option to choose between sessions could be added (not sure if the globally unique display number is the best way, here).

should react on some custom signal that tells to reread xpra.conf


What for? That would very hard to do right.

What I had in mind is that the xpra process is running as a service which you can start, stop, or reload. The "reload" should obviously not just do "start" + "stop" since this would kill all xpra processes. To my opinion, the automatic reload of xpra.auth is quite uncommon for a service. Typically, changes to /etc/ are reflected only after the service is reloaded. Thats were I was thinking a custom signal would be nice to trigger a reload of xpra.auth.


a client side command line option could be added that causes the server to terminate all of the users


Running xpra stop against the master proxy process stops it (including all proxy instances).
We could easily add an xpra control :MASTERPROXYDISPLAY stop control command to call this stop_all_proxies function.
As you may already know, individual proxy instances can be stopped with xpra stop, so I guess this can also be scripted.

Thats right, it can easily be scripted on the server side. But how can I trigger "xpra stop" from the client side?

comment:3 Changed 4 years ago by Antoine Martin

Thats right. I didn't know about the automatic reload. Additionally, I guess that existing xpra sessions are not killed if the entry is removed from the xpra.auth file, right?


No, the file is purely for authentication.

To my opinion, the automatic reload of xpra.auth is quite uncommon for a service


I think you misunderstand what this file is for: this is just a password + session lookup file.
In the same way that changes to your /etc/passwd immediately affect any subsequent login attempts.

Typically, changes to /etc/ are reflected only after the service is reloaded


This is not necessarily meant to be an /etc/ file. As per above, your statement is not true of login and many other utilities (tcp wrappers, etc).

But how can I trigger "xpra stop" from the client side?


It really depends on where the real session lives... Regular sessions can be stopped remotely with "xpra stop" over ssh or even tcp.

I think that you are making the assumption that the proxy and instances are on the same system, but that is not necessarily the case, by design. The proxy can point to instances anywhere.
The xpra client actually has the ability to shutdown the server session already (in the same way that the "xpra stop" command works), it is just not exposed in the tray menu.

Last edited 4 years ago by Antoine Martin (previous) (diff)

comment:4 in reply to:  3 Changed 4 years ago by sschnitzer

Replying to totaam:

Thats right. I didn't know about the automatic reload. Additionally, I guess that existing xpra sessions are not killed if the entry is removed from the xpra.auth file, right?


No, the file is purely for authentication.

To my opinion, the automatic reload of xpra.auth is quite uncommon for a service


I think you misunderstand what this file is for: this is just a password + session lookup file.
In the same way that changes to your /etc/passwd immediately affect any subsequent login attempts.


I think I misunderstood "reloads the file whenever it is modified". You just meant that the file is read whenever the proxy needs to authenticate someone.


Typically, changes to /etc/ are reflected only after the service is reloaded


This is not necessarily meant to be an /etc/ file. As per above, your statement is not true of login and many other utilities (tcp wrappers, etc).


Thats right. The difference is that these utilities are not running as service. The login reads /etc/passwd each time you login, there is no daemon/service running for this task. For cases where you have a service, it typically reads the /etc/ files at startup and reloads them only on request. For example the SSH server behaves like that, but the SSH client (which is no service) loads the /etc files just if you run it.
Thinking of /etc/passwd, deleting a user there of course does not kill the users processes. However, deleting users is not supposed to be done by deleting a line in /etc/passwd but by using something like "deluser" which will ensure that no process of that user is running (since this would be an inconsistent state I guess).

But how can I trigger "xpra stop" from the client side?


It really depends on where the real session lives... Regular sessions can be stopped remotely with "xpra stop" over ssh or even tcp.

I think that you are making the assumption that the proxy and instances are on the same system, but that is not necessarily the case, by design. The proxy can point to instances anywhere.
The xpra client actually has the ability to shutdown the server session already (in the same way that the "xpra stop" command works), it is just not exposed in the tray menu.


Didn't know that, thanks for the hint.
Does this also work through the proxy (i.e. not killing the proxy but the xpra server process behind)?
Yes, I assume that proxy and server run on the same system.
This setup requires

  • To start many xpra servers in advance (one for each user, even if only few of them actually log in)
  • To use one tcp port per user, which can hardly be guaranteed to work always since some other application could claim the assigned tcp port by chance or maliciously in a period where it is unclaimed. As an attacker I would login as myself and then try to spawn an xpra service that binds to a tcp port which is mapped (in xpra.auth) to an admin. Next time the admin connects, it is redirected to a xpra server running with my userid and executing what I want. Currently I don't see a way to prevent this as long as the xpra server processes are not spawned by the xpra proxy.

So for both points I see good reasons to integrate them into the xpra proxy.
A way to coexist with the existing functionality: Instead of something like "tcp:127.0.0.1:11001" in xpra.conf there could be the special option "auto_spawn_by_proxy" which then just spawns new xpra servers on localhost.
But I admit that for a terminal server scenario loadbalancing could be also an interesting feature. But I think for loadbalancing it is still desireable to run a proxy on each server system. Opening huge ranges of ports >1024 in the servers firewalls' is no great idea, I guess.

comment:5 Changed 4 years ago by Antoine Martin

I think I misunderstood "reloads the file whenever it is modified". You just meant that the file is read whenever the proxy needs to authenticate someone.


Right, my bad, that's because I let irrelevant implementations details slip into the discussion: we cache the contents of the file, so it gets "reloaded" when needed. Which is conceptually the same as looking things up when needed, just optimized a bit.

Does this also work through the proxy (i.e. not killing the proxy but the xpra server process behind)?


Yes: the proxy is only used for establishing the connection, after that it only forwards data back and forth between client and server. (well, it does modify some packets for hardware assisted encoding, and it may also use different packet encoders and/or compression algorithms for each side of the connection, but it isn't directly part of the conversation between client and server)

Instead of something like "tcp:127.0.0.1:11001" in xpra.conf there could be the special option "auto_spawn_by_proxy" which then just spawns new xpra servers on localhost


Sure, some syntax could be found. For local servers, something like this maybe:

:auto

I think it could be done by extending the file auth class quite easily.

The only potential hurdles are permission and paths related: when we spawn sessions and when we check for existing ones, we may not be running as the same user account, which can easily break things.

But I admit that for a terminal server scenario loadbalancing could be also an interesting feature


If the code isn't made too ugly, the auto-spawn feature can easily be changed into something that spawns remote servers or uses some kind of directory / service to locate sessions / servers.

comment:6 Changed 23 months ago by Antoine Martin

Milestone: 1.01.1

Milestone renamed

comment:7 Changed 21 months ago by Antoine Martin

Milestone: 1.12.0

Milestone renamed

comment:8 Changed 20 months ago by Antoine Martin

See also #1319 which may provide a big part of what you are asking already.

comment:9 Changed 16 months ago by Antoine Martin

Milestone: 2.0future

AFAIK, #1319 makes most of this moot.

comment:10 Changed 4 months ago by Antoine Martin

  • for a "dedicated xpra session for each user", see #408
  • starting sessions via the proxy is already supported via #1319, adding remote start would be harder (start how? via ssh?)

The whole "watch for dead sessions", "reset all his remote processes" and "Consider updates to xpra.auth (deleted or added users) by killing processes or spawning new ones" would drastically change the way the authentication modules are used. #1728 also makes this harder.
This could be used to implement load balancing (#1486).

Note: See TracTickets for help on using tickets.