Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enhance configuration of Keycloak valid redirects list in the canned deployment #3503

Merged
merged 5 commits into from
Aug 4, 2023

Conversation

webbnh
Copy link
Member

@webbnh webbnh commented Jul 25, 2023

By default, the canned Pbench Server deployment configures all accesses -- Server, PostgreSQL, Elasticsearch, browser, and especially Keycloak -- with the assumption that all accesses to and fro will be on localhost. This works fine for functional test, but for development (at least for me...), the client/browser is not necessarily running on the host where the servers are running. This means that the Dashboard code is served from the Pbench Server using an IPv4 address instead of localhost...which means that, for the Keycloak login dance, the redirect back from the Keycloak Server to the Dashboard has to match a valid redirect pattern which references the Dashboard using the IPv4 address of the Pbench Server and not just localhost.

This PR addresses this by enhancing the load_keycloak.sh script to generate a full list of plausible redirects. Currently, the script installs two -- a development UI server and the containerized localhost -- to which this change adds anything which hostname's -I, -A, and -f options' outputs provides (that is, any way that the host knows of in terms of how it can be addressed...including the IPv4 address which I'm using.)

Unfortunately, this covers only the return from the Keycloak server...we also need to make sure that, when the Dashboard attempts to request authentication from the Keycloak server, it uses a suitable address (i.e., in my case, an IP address rather than localhost). This is determined by the server_url option in the openid section of the pbench_server.cfg file. So, this PR also modifies run-pbench-in-a-can to set that value according to a new environment variable, PB_HOST. (This replaces the machinations based on the previous, otherwise unused PB_HOST_IP environment variable, which don't seem to have any effect.)

And, with this newly-acquired acumen for generating lists of hostnames, I decided to enhance the TLS certificate generation along the lines of the Keycloak redirect: with this PR, the certificate will now cover accesses to the host using any name or IP address which the hostname -I and -A switches produce, along with localhost and 127.0.0.1. And, the script issues a warning if the requested PB_HOST value isn't in the list of certifiable hosts/addresses.

And, while I was tweaking the pbench-server.cfg creation code, I made run-pbench-in-a-can set values for the Keycloak realm and client, so that we are assured that they will match the setup later established by the load_keycloak.sh script.

(Also, the initial commit picks a bunch of lint.)

@webbnh webbnh added Server Code Infrastructure Containerization Of and relating to the process of setting up and maintaining container images labels Jul 25, 2023
@webbnh webbnh added this to the v0.73 milestone Jul 25, 2023
@webbnh webbnh self-assigned this Jul 25, 2023
@webbnh webbnh force-pushed the keycloak_redirects branch 3 times, most recently from 4bdeae6 to 9139636 Compare August 1, 2023 20:40
@webbnh
Copy link
Member Author

webbnh commented Aug 1, 2023

This PR is now ready for review.

@webbnh webbnh marked this pull request as ready for review August 1, 2023 21:13
@webbnh webbnh requested review from dbutenhof and ndokos August 1, 2023 21:13
dbutenhof
dbutenhof previously approved these changes Aug 1, 2023
Copy link
Member

@dbutenhof dbutenhof left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm worried whether you're going to break something with the IPv6; but while I think the redundant and often non-routable hostnames are a waste of time they also won't hurt. You should verify you're doing this on a system with an IPv6 address and that everything works; beyond that, yeah, fine, whatever.


KEYCLOAK_HOST_PORT=${KEYCLOAK_HOST_PORT:-"https://localhost:8090"}
KEYCLOAK_REDIRECT_URI=${KEYCLOAK_REDIRECT_URI:-"https://localhost:8443/*"}
KEYCLOAK_REDIRECT_HOSTS=${KEYCLOAK_REDIRECT_HOSTS:-"localhost $(hostname -I) $(hostname -A) $(hostname -f)"}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Dang: so "localhost 10.0.0.104 <IPv6> dbutenho-thinkpadp1gen4i.bos.csb dbutenho-thinkpadp1gen4i.bos.csb dbutenho-thinkpadp1gen4i.bos.csb" (that's my local router IPv4 since I'm not on VPN, and the csb FQDNs aren't routable, so the IPv6 is the only one I actually ought to avoid revealing on GitHub 😆 )

But, seriously, using hostname -f when you're using hostname -A seems pointless as the former is "the" FQDN while the latter is all FQDNs and therefore will always be a superset. (And, since I don't think any of our systems have separate FQDNs across NICs, probably still always a duplicate.)

Also, I'm not sure the redirect will take an undelimited IPv6 address, so your https://<IPv6>:8443 probably won't work and might generate an error in Keycloak. I suspect it'd need to be https://[<IPv6>]:8443 ... all of which makes this IP stuff a lot more complicated than it might seem at first.

I just think you're potentially asking for trouble here, and I'm not sure your result is really going to help anyone anyway since we're not using this in a real deployment anymore.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

using hostname -f when you're using hostname -A seems pointless as the former is "the" FQDN while the latter is all FQDNs and therefore will always be a superset.

I agree...but, I'm pretty sure that I one point I found myself in a situation where the output of -f was not in the list from -A, so I included it out of an abundance of caution. (I assume that I was inside a container at the time.... 🦐)

However, if your goal is to avoid duplication, I think you're out of luck -- I just got this:

# hostname -A
8e10ccf8e78e 8e10ccf8e78e 

🤣

since I don't think any of our systems have separate FQDNs across NICs, probably still always a duplicate.

intlab-002 has two NICs, but the second one doesn't seem to have a FQDN (i.e., the reverse-lookup on its IPv4 address fails), but hostname -A there reports a duplication of the n002 name (in addition to the intlab-002 name), too.

I just think you're potentially asking for trouble here, and I'm not sure your result is really going to help anyone anyway since we're not using this in a real deployment anymore.

I may indeed be asking for trouble, since I don't seem to have a system with IPv6 configured that I can test on. However, the result helps me -- running with the browser on my laptop and the canned server on my VM in the IntLab, the Keycloak redirect has to be something other than localhost. So, the question is, how to get that "something", and I was hoping that hostname could provide the answer...but there is no good way to choose among (or even recognize) what it offers. 🙁

I'm not sure the redirect will take an undelimited IPv6 address

I just tried a manual test...and it did! 🥴

"redirectUris": ["http://localhost:3000/*", "https://fd00::948d:1dff:fe6c:fefe:8443/*"]

So, I guess it just does a dumb-ish pattern match on the backside.

But, you're absolutely right, the IPv6 addresses should be wrapped in square-brackets. 😝

Copy link
Member Author

@webbnh webbnh Aug 2, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK, they are now wrapped. Assuming the tests pass, I don't suppose you'd be willing to try the script on your machine? (My machines don't speak IPv6 outside of containers, and my attempt to run jenkins/runlocal using jenkins/run built the RPM but then couldn't find it to build the container.... 🍤)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

However, if your goal is to avoid duplication, I think you're out of luck -- I just got this:

# hostname -A
8e10ccf8e78e 8e10ccf8e78e 

Wait; so where did it get a "hostname" like that? Even inside a container, I'm seeing host.containers.internal -- which is stupid, but arguably less stupid than yours. 🤔

rofl

since I don't think any of our systems have separate FQDNs across NICs, probably still always a duplicate.

intlab-002 has two NICs, but the second one doesn't seem to have a FQDN (i.e., the reverse-lookup on its IPv4 address fails), but hostname -A there reports a duplication of the n002 name (in addition to the intlab-002 name), too.

Interesting. I know the BOS lab used to have a high-speed internal subnet; and presumably the "second" proxy NIC would be on the internal net, which I don't think had DNS. RDU2 may well do something similar.

I just think you're potentially asking for trouble here, and I'm not sure your result is really going to help anyone anyway since we're not using this in a real deployment anymore.

I may indeed be asking for trouble, since I don't seem to have a system with IPv6 configured that I can test on. However, the result helps me -- running with the browser on my laptop and the canned server on my VM in the IntLab, the Keycloak redirect has to be something other than localhost. So, the question is, how to get that "something", and I was hoping that hostname could provide the answer...but there is no good way to choose among (or even recognize) what it offers. slightly_frowning_face

I really don't understand the logic of the CSB configuration. They have DHCP addresses, but apparently no DDNS names, and hostname generates only non-routable blather. Then again, VMs and containers generally aren't any better.

(Then again, on the staging VM, hostname -f gives "rhel9-pbenchstaging" while hostname -A gives the actual routable DDNS DHCP FQDN, so that's something.)

I'm not sure the redirect will take an undelimited IPv6 address

I just tried a manual test...and it did! woozy_face

"redirectUris": ["http://localhost:3000/*", "https://fd00::948d:1dff:fe6c:fefe:8443/*"]

So, I guess it just does a dumb-ish pattern match on the backside.

Leaving the obvious question of which form, if either, would match on a redirect.

But, you're absolutely right, the IPv6 addresses should be wrapped in square-brackets.

I pulled your branch and did a runlocal. I verified that the Keycloak has the (delimited) IPv6 address. (Actually, it's got both the link-local address and the routable address ... and while my first thought was that the link-local was silly as it's not routable off the local subnet, well, my laptop curiously enough is on its own local subnet...) Anyway, I can open a web page on either delimited IPv6 address copied from the redirects list, and the page loads and I can log in!

And, interestingly, while the CSB hostname isn't actually routable, I'd never had occasion to notice before that it actually works as a "localhost" alias on my laptop, so https://dbutenho-thinkpadp1gen4i.bos.csb:8443/dashboard/ loads (and logs in) just fine!

The upshot here is that every one of the redirect URLs you're programming on my laptop actually work to launch the dashboard and to log in: even the ridiculously silly ones. 😆

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Addendum: on a whim, I also tried the local dashboard dev-mode to exercise the http://localhost:3000 redirect, although there was no reason to think it wouldn't still work. It does... but, feeling in an IPv6-ish mood, I tried connecting to IPv6 localhost [::], and that's not mapped in your cert (or probably in the allowed redirects), so it didn't work. Hmm. But the link-local IPv6 (PBENCH_SERVER=https://\[fd10:22:16:1::10b9\]:8443 npm run dev) worked just fine.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

However, if your goal is to avoid duplication, I think you're out of luck -- I just got this:

# hostname -A
8e10ccf8e78e 8e10ccf8e78e 

Wait; so where did it get a "hostname" like that?

No clue...I'm just reporting what I'm seeing. 🙃

which is stupid, but arguably less stupid than yours. 🤔

😆

presumably the "second" proxy NIC would be on the internal net, which I don't think had DNS. RDU2 may well do something similar.

I expect that you're correct.

I really don't understand the logic of the CSB configuration. They have DHCP addresses, but apparently no DDNS names, and hostname generates only non-routable blather. Then again, VMs and containers generally aren't any better.

Yeah, and it's not just CSB. My home network has similarly awkward hostnames (which are not, generally, as far as I can tell, routable or even usable except in rare circumstances).

(Then again, on the staging VM, hostname -f gives "rhel9-pbenchstaging" while hostname -A gives the actual routable DDNS DHCP FQDN, so that's something.)

Hah! You found it!! That's a case of the return from -f not being in the list (of one...) returned by -A....

So, I guess it just does a dumb-ish pattern match on the backside.

Leaving the obvious question of which form, if either, would match on a redirect.

Well, the redirect is provided by the client (to wit, the Dashboard) and checked by the OIDC server and then invoked. So, if the provided value doesn't match the valid-redirect list, it doesn't really matter whether it is a valid URL format. 🙃 And, if it does match the list, but isn't a valid URL, then that's a problem for the client...so, I'm not sure that Keycloak has any motivation for enforcing anything other than fairly simple pattern matching.

I pulled your branch and did a runlocal. I verified that the Keycloak has the (delimited) IPv6 address. (Actually, it's got both the link-local address and the routable address ... and while my first thought was that the link-local was silly as it's not routable off the local subnet, well, my laptop curiously enough is on its own local subnet...) Anyway, I can open a web page on either delimited IPv6 address copied from the redirects list, and the page loads and I can log in!

Yay! 🎉 Thanks for checking that!!

And, interestingly, while the CSB hostname isn't actually routable, I'd never had occasion to notice before that it actually works as a "localhost" alias on my laptop, so https://dbutenho-thinkpadp1gen4i.bos.csb:8443/dashboard/ loads (and logs in) just fine!

I'm glad it's good for something.... 😉

The upshot here is that every one of the redirect URLs you're programming on my laptop actually work to launch the dashboard and to log in: even the ridiculously silly ones. 😆

Hurrah! (Thanks again for checking!!)

I also tried the local dashboard dev-mode to exercise the http://localhost:3000 redirect, although there was no reason to think it wouldn't still work. It does... but, feeling in an IPv6-ish mood, I tried connecting to IPv6 localhost [::], and that's not mapped in your cert (or probably in the allowed redirects), so it didn't work. Hmm. But the link-local IPv6 (PBENCH_SERVER=https://\[fd10:22:16:1::10b9\]:8443 npm run dev) worked just fine.

OK...if you're willing to test it again, I'll see if I can close that gap.... 🤔 But see my comment below.

Include 'alternate names' for all of the server's hostnames and IP addresses.
Ensure that the Keycloak realm and client in the Pbench Server configuration
file match the configuration of the canned Keycloak server, and make the value
of the Keycloak server in the Pbench Server config file be configurable.
dbutenhof
dbutenhof previously approved these changes Aug 2, 2023
Copy link
Member

@dbutenhof dbutenhof left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Experimentation has shown that this works, and while you omitted one obscure usable address (IPv6 localhost), every address in the redirect is (surprisingly in several case) usable. That's a solid "A", and I don't necessarily think we need any more; but if you want an "A+", it's just "one more thing" ... 😁


KEYCLOAK_HOST_PORT=${KEYCLOAK_HOST_PORT:-"https://localhost:8090"}
KEYCLOAK_REDIRECT_URI=${KEYCLOAK_REDIRECT_URI:-"https://localhost:8443/*"}
KEYCLOAK_REDIRECT_HOSTS=${KEYCLOAK_REDIRECT_HOSTS:-"localhost $(hostname -I) $(hostname -A) $(hostname -f)"}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

However, if your goal is to avoid duplication, I think you're out of luck -- I just got this:

# hostname -A
8e10ccf8e78e 8e10ccf8e78e 

Wait; so where did it get a "hostname" like that? Even inside a container, I'm seeing host.containers.internal -- which is stupid, but arguably less stupid than yours. 🤔

rofl

since I don't think any of our systems have separate FQDNs across NICs, probably still always a duplicate.

intlab-002 has two NICs, but the second one doesn't seem to have a FQDN (i.e., the reverse-lookup on its IPv4 address fails), but hostname -A there reports a duplication of the n002 name (in addition to the intlab-002 name), too.

Interesting. I know the BOS lab used to have a high-speed internal subnet; and presumably the "second" proxy NIC would be on the internal net, which I don't think had DNS. RDU2 may well do something similar.

I just think you're potentially asking for trouble here, and I'm not sure your result is really going to help anyone anyway since we're not using this in a real deployment anymore.

I may indeed be asking for trouble, since I don't seem to have a system with IPv6 configured that I can test on. However, the result helps me -- running with the browser on my laptop and the canned server on my VM in the IntLab, the Keycloak redirect has to be something other than localhost. So, the question is, how to get that "something", and I was hoping that hostname could provide the answer...but there is no good way to choose among (or even recognize) what it offers. slightly_frowning_face

I really don't understand the logic of the CSB configuration. They have DHCP addresses, but apparently no DDNS names, and hostname generates only non-routable blather. Then again, VMs and containers generally aren't any better.

(Then again, on the staging VM, hostname -f gives "rhel9-pbenchstaging" while hostname -A gives the actual routable DDNS DHCP FQDN, so that's something.)

I'm not sure the redirect will take an undelimited IPv6 address

I just tried a manual test...and it did! woozy_face

"redirectUris": ["http://localhost:3000/*", "https://fd00::948d:1dff:fe6c:fefe:8443/*"]

So, I guess it just does a dumb-ish pattern match on the backside.

Leaving the obvious question of which form, if either, would match on a redirect.

But, you're absolutely right, the IPv6 addresses should be wrapped in square-brackets.

I pulled your branch and did a runlocal. I verified that the Keycloak has the (delimited) IPv6 address. (Actually, it's got both the link-local address and the routable address ... and while my first thought was that the link-local was silly as it's not routable off the local subnet, well, my laptop curiously enough is on its own local subnet...) Anyway, I can open a web page on either delimited IPv6 address copied from the redirects list, and the page loads and I can log in!

And, interestingly, while the CSB hostname isn't actually routable, I'd never had occasion to notice before that it actually works as a "localhost" alias on my laptop, so https://dbutenho-thinkpadp1gen4i.bos.csb:8443/dashboard/ loads (and logs in) just fine!

The upshot here is that every one of the redirect URLs you're programming on my laptop actually work to launch the dashboard and to log in: even the ridiculously silly ones. 😆


KEYCLOAK_HOST_PORT=${KEYCLOAK_HOST_PORT:-"https://localhost:8090"}
KEYCLOAK_REDIRECT_URI=${KEYCLOAK_REDIRECT_URI:-"https://localhost:8443/*"}
KEYCLOAK_REDIRECT_HOSTS=${KEYCLOAK_REDIRECT_HOSTS:-"localhost $(hostname -I) $(hostname -A) $(hostname -f)"}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Addendum: on a whim, I also tried the local dashboard dev-mode to exercise the http://localhost:3000 redirect, although there was no reason to think it wouldn't still work. It does... but, feeling in an IPv6-ish mood, I tried connecting to IPv6 localhost [::], and that's not mapped in your cert (or probably in the allowed redirects), so it didn't work. Hmm. But the link-local IPv6 (PBENCH_SERVER=https://\[fd10:22:16:1::10b9\]:8443 npm run dev) worked just fine.

server/pbenchinacan/run-pbench-in-a-can Show resolved Hide resolved
Copy link
Member

@dbutenhof dbutenhof left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(When you wake up in the middle of the night and decide to be "productive" before trying to get back to sleep...)

I re-tested with https://[::1]:8443 and it works, both directly in-browser and as the express relay PBENCH_SERVER value. Cool. I guess this must be perfect.

@webbnh webbnh merged commit b2e56ac into distributed-system-analysis:main Aug 4, 2023
3 checks passed
@webbnh webbnh deleted the keycloak_redirects branch August 4, 2023 17:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Code Infrastructure Containerization Of and relating to the process of setting up and maintaining container images Server
Projects
Status: Done
Development

Successfully merging this pull request may close these issues.

2 participants