Just a small comment regarding #1 - @TimoGoebel did some initial work on jwt as well in https://github.com/theforeman/foreman/pull/5596 as part of an effort to introduce GraphQL, so it would be a good idea to look into that as well and see that we don’t have duplicate effort/implementations.
Hey @tbrisker, thank you for bringing this to my attention. I don’t think it really conflicts here, au contraire, I think seeing an initial implementation might help the cause Either way, if you ask me, I’ll sign a JWT, containing hostname and port retrieved from compute resource, using foreman’s private key as this is readily available. The validation on proxy side is then to be done by its public key.
Meanwhile I’ve pushed a PR for websockify (including unit tests), so, we’re closing in on point 1:
Do you mean pushing an update to EPEL? This can be a bit issue since upstream hasn’t done an update for three years (0.8.0 is the latest, also in EPEL). The code is a quite change for patch carried in EPEL (new deps), let’s see. The best thing is to ask upstream to do a release, then ask CentOS packagers to do the same. But remember, the EPEL policy is no major changes, only bugfixes Let’s figure it out, we can always carry new version in our repos.
Allright, another year, another update
So, the PR for getting JWT token in Websockify has been merged.
This is a big step forward as we’ll now able to move to the next steps:
- Running this on the Smart-Proxy
- Expose this console-proxying capability
- Share the right secrets --> I think this is our new problem-child; so input would be very welcome here, let me explain:
- Still would need to proxy the websocket to the correct smart-proxy, I’m thinking “https://foreman-server/console-proxy//” which can be configured in the webserver to proxy this to a different backend
The JWT implementation for Websockify is enhanced in order to support JWE as well, in “layman terms” this means that we encrypt the content of the JWT using the public key of the receiver and Sign it using the Private key of the sender.
I think it would be valuable for us to implement the feature using JWE instead of simple JWS; however, the big question here is: how would I share the public keys of each end?
- I think it’s easy to create an API extension point for the “Console-Proxy” feature, which can return the public key, but would it be wise?
- Even more, would it be wise to also enhance this API and allow passing a public key from the sender (being The Foreman Server) to the proxy?
- What would be the trigger to send this?
- Or do I enhance the foreman API to send a public key on a proxy’s request?
Do we already have an infrastructure for passing public keys? Or, how would you guys do this?
Can you explain why? Everytime I can use symetric cryptography instead of asymetric, I go for it. It’s more simple.
I might not understand the whole picture at the moment, but can’t we simply deploy (public) key(s) using our installer? This is something that does not change. For symetric that would be just a string which we can generate randomly and store in answers file and deploy where necessary.
Hi! Thanks for your response! Actually JWE allows for the usage of symetric keys as well; as you state it would greatly simplify the deployment.
- Would it be okay that this is passed as an (foreman-proxy) installation argument? e.g. console-symetric-key?
- Or would we trust the Foreman API for passing the console symetric key (as, by my assumption, this has TLS by default and can be deemed secure?)
- Or would we trust the Proxy API instead? (also, this seems to be secure and only allows the foreman to access this; would make it possible to use different symmetric keys for different smart-proxies
I would vote for the last case? Unless my assumptions on using TLS are greatly exaggerated?
Would also be fairly easy to implement
At this moment I’d avoid building this support into the smart-proxy. Currently Foreman talks directly to compute resources and is the only one guaranteed to have a routable connection to them. Proxies may not and have no knowledge of compute resources at all (whether this is correct or not is another question). Other than that the clients are also not guaranteed to have connection to smart proxies. That means you’ll always need a console proxy on the Foreman server itself. In a schema:
client.example.com <-> foreman.example.com <-> compute.example.com
In the future this may add indirection via a smart proxy (which IMHO does make sense) but you’ll still have a proxy on
This will simplify your design.
Currently the Foreman user launches the websockify daemon with certs. This means the Foreman user needs permissions I’d like to get rid of. Could we run the websockify daemon (unencrypted) on localhost and use the webserver (Apache/Nginx) as a reverse proxy? We would need to think about the development setup, but a setting to override the host/port is probably sufficient.
Will this work in a load balanced setup?
If every server runs it on localhost and the webserver also proxies to localhost I don’t see why it wouldn’t. As long as the load balancer keeps the TCP session to one backend. It also means the webservers need to use a shared certificate to encrypt the data to send to the client so any backend can validate it.