xpra icon
Bug tracker and wiki

Opened 10 months ago

Last modified 2 months ago

#2125 assigned enhancement

let a server register with a proxy

Reported by: brief Owned by: Antoine Martin
Priority: major Milestone: 4.0
Component: network Version: 2.4.x
Keywords: Cc: mjharkin@…

Description

If a server has the ability to register on a proxy, the proxy can become aware of servers where discovery via bonjour is not possible.

Furthermore, this allows hole punching in the servers firewall if the server is keeping the connection to the proxy alive. This allows to have client and server behind a NAT and only needs a proxy exposed.

Attachments (2)

command line options.patch (6.3 KB) - added by brief 8 months ago.
paket handler.patch (3.7 KB) - added by brief 8 months ago.

Download all attachments as: .zip

Change History (14)

comment:1 Changed 10 months ago by Antoine Martin

Milestone: 2.53.0
Owner: changed from Antoine Martin to brief

How would a client identify which server it wants to connect to?

The standard way of doing this at the moment is using sqlite auth (#1488), which you can already use today as long as the server is not behind NAT: the servers can add themselves to the sqlite auth database used by the proxy to locate sessions for its users.

To workaround the NAT problem, the servers would need to connect to the proxy instead of the other way around.
The connection would have to be authenticated and then kept alive until a client takes over.
This is quite similar to #1022.

comment:2 Changed 9 months ago by Antoine Martin

Component: corenetwork
Owner: changed from brief to Antoine Martin
Status: newassigned
Summary: let a server register at a proxylet a server register with a proxy

Add a new command line option so that servers can advertise themselves to remote proxy servers.
This would complement wiki/MulticastDNS and make it easier to deploy proxy servers.
Can also be used for easy NAT traversal: both server and client can be behind NAT.

Related tickets:

  • #1590 network tracker ticket
  • #675 extend xpra proxy for terminal server deployments

ie:

xpra start --start=xterm \
    --register=tcp://proxyusername:proxypassword@proxyip:proxyport/SESSIONID?\
    username=optionalclientloginusername&password=optionalclientloginpassword

Issues:

  • only allow registration on some tcp / ws / wss / ssh sockets?
  • support multiple proxies: register with all of them, or the first one, or random, or...
  • re-connect to the proxy if the connection drops, maybe add an option to give up and exit if none of the proxies are available for too long
  • keep connection to proxy alive - also similar to #1022: "client listen mode"
  • the proxy needs to keep track of those sessions in memory, return them before or after the ones from the client auth module?
  • the proxy servers could also listen for mdns broadcasts and expose those servers

comment:3 Changed 8 months ago by brief

I tried to do changes regarding this ticket, but I got stuck after implementing the command line options.

I suggest using one command line option for the server to register himself at a proxy and one command line option for the proxy to accept registrations.

The option for the server could be like yours above. Multiple --register options could be accepted, each with a list of servers. Connections are made to a random not failing entry in each list. Thus multiple proxies with failover configurations can be configured.

The option for the proxy should include the protocol to listen on.

Should there be a new table containing optionalclientloginusernames and passwords with groups matched to users group?

comment:4 Changed 8 months ago by Antoine Martin

I tried to do changes regarding this ticket, but I got stuck after implementing the command line options.

Where is your code?

The option for the proxy should include the protocol to listen on.

I think this should be done as per #1160, using chained authentication modules: the last module in the chain would do the registration.

Should there be a new table containing optionalclientloginusernames and passwords with groups matched to users group?

Not sure I understand, I don't think anything should be tied to unix user groups. The solution should be generic.

Changed 8 months ago by brief

Attachment: command line options.patch added

Changed 8 months ago by brief

Attachment: paket handler.patch added

comment:5 Changed 8 months ago by brief

I attached a patch regarding the command line options. The cmd options are not in the format you mentioned but in the old one.

I also attached a patch what I tried with a new paket handler, but I certainly sure this is not the right way to do it.

Regarding optionalclientloginusernames: I understood that a server willing to register at a proxy can provide credentials (optionalclientloginusernames, optionalclientloginpassword). I wanted to ask if a new table in db/... is needed (e.g. server_users) to store these combinations. Furthermore I thought about the idea, to be able to indicate groups at server_users to be able to present users a list of servers matching by group.

comment:6 Changed 8 months ago by Antoine Martin

Owner: changed from Antoine Martin to brief
Status: assignednew
  • there is no authentication on the "register" packets? You would be better off using a hello request option. (see how detach or info requests are handled)
  • if using a dedicated packet type, the "register" packet handler should live in the proxy code, not in server core module.
  • I don't understand why you're using mod_python here
  • the "answer" object is constructed weird and I don't see the code for add_user anywhere
  • the register string should be a regular xpra URI (ie for TCP: tcp://username:password@host:port/?extra_args), that way authentication will be handled automatically

comment:7 Changed 7 months ago by Antoine Martin

See also #2261

comment:9 Changed 6 months ago by Antoine Martin

Owner: changed from brief to Antoine Martin
Status: newassigned

Here's my plan - feel free to comment:

  • --proxy-sessions=auth,sys,mdns,register so the proxy can be told where to get the list of sessions from (and maybe those options can be combined?):
    • auth (default) would still use the auth module so we don't break any existing setups
    • sys same as what most auth modules currently do: similar to running xpra list using the same uid supplied by the auth module (usually the user that authenticated)
    • mdns without knowing if the server already has clients or not since we can't seem to get TXT record update notifications (see #2187)
    • register get the list of sessions from servers that register with the proxy
  • I would like to re-use all the socket code and authentication configuration options for the server registration (so servers can use ssl / ssh / whatever), but ideally without letting the servers have the same privileges as regular authenticated users (ie: no ability to connect to sessions or start new sessions, just registering) - not sure how to do that yet (comment:4 suggested using a new authentication module, but this would be too difficult to tie with other features: keepalive, etc), should this be configured at the socket level (as part of the --bind-XXXX option), or as part of the authentication module? (ie: access=full,register,info,... to specify what the authentication gives access to)
  • the sessions can be identified using their uuid, and maybe other attributes? the display string is not a good match as multiple servers running on different systems can use the same display number. uids are not usually portable either (not without things like ldap - which we can't require)
  • the server code will need a new option for telling it to register with the proxy, something like: --register=tcp://host:port/?options, it will need options like keepalive and re-connect, we should detect authentication failures and not retry too often in that case
  • the proxy can keep these connections open, proxy_auth can be taught about the special "registered" sessions and bypass connect_to

Notes:

  • do we want to think about load-balancing?
  • how do we select a session easily?
  • if more than one is available?

comment:10 Changed 6 months ago by Antoine Martin

Cc: mjharkin@… added

(CC was removed by mistake)

comment:11 Changed 2 months ago by Antoine Martin

Some useful socket functions have been moved:

  • r23736 refactoring: move code to socket_util
  • r23737 move socket_util to xpra.net
  • r23738 make add_listen_socket more re-usable
  • r23740 remove socket_types mapping, use callback argument instead
  • r23741 move accept_connection code to socket_util

comment:12 Changed 2 months ago by Antoine Martin

More network related updates that can help here:

  • r23742 + r23756: cosmetic
  • r23747 assume socket if path is given as display
  • r23748 control channel fix for python3 proxy instances
  • r23750 : #2408
  • r23754 warn if a unix domain socket goes MIA
  • r23759 cleanup now stops listening for socket events, fix r23740 (must return True to continue receiving socket events)
  • r23760 BUG introduced by r23759, cleanup IO event source only once
  • r23761 simplify named-pipe extra "pipe_handle" argument (make it a default arg)
  • r23762 : #2407
  • r23763 : proxy instance process message queue cleanup
  • r23768 refactor peek_connection to make it reusable
  • #1022 : client listen mode
  • r23769 constify
Last edited 2 months ago by Antoine Martin (previous) (diff)

comment:13 Changed 2 months ago by Antoine Martin

Milestone: 3.04.0

Too late for 3.0, will deal with this after #1160 so we can re-use the same bind-XXX syntax and have different capabilities on different ports.

Note: See TracTickets for help on using tickets.