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

fix app access regression when the app is on a leaf cluster #47778

Merged

Conversation

capnspacehook
Copy link
Contributor

@capnspacehook capnspacehook commented Oct 22, 2024

Fixes #46951.

changelog: fix app access regression to apps on leaf clusters

Copy link
Contributor

@avatus avatus left a comment

Choose a reason for hiding this comment

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

Logic seems fine to be. it'd be nice to change this from some nested if and just into two variables like
const fqdnMatch and const isLeafApp or whatever you think makes most sense. then we can just do if !this && !that, return error

might read a little nicer. but in general this is good!

@capnspacehook capnspacehook marked this pull request as ready for review October 24, 2024 01:26
@github-actions github-actions bot requested review from kiosion and ryanclark October 24, 2024 01:26
Copy link

This pull request is automatically being deployed by Amplify Hosting (learn more).

Access this pull request here: https://pr-47778.d3pp5qlev8mo18.amplifyapp.com

@capnspacehook
Copy link
Contributor Author

Thanks @avatus, moved the logic into it's own function to put the logic and comments in one place. Did some more testing and found that this PR fixes an access denied error popping up when attempting to access an app from a leaf cluster, but another issue prevents accessing the leaf app. I get a warning: Request failed: state cookie is not set. app/auth.go:166. I confirmed this issue started after my 2 commits that added and revised these app FQDN checks, the regression seems to have been created between #45024 and #45512. Do you mind confirming this for me?

@avatus
Copy link
Contributor

avatus commented Oct 25, 2024

The fqdn returned from a leaf resource gets updated in a weird way (which might be incorrect and perhaps is what we should really look at and fix). It becomes something like appname-rootcluster. Which then causes the frontend to forward to the wrong app

This is why you see Request failed: state cookie is not set, because the original requested app during the auth exchange is different, so the cookie isn't set on the correct domain.

I believe we need to update our forwarding URL to use publicAddr of the resolved app instead of the FQDN. I tested locally and works, but didn't consider the implications of the change. Please take a look when you get a chance @capnspacehook .

Here was my diff to get it working (copy and then pbpaste | git apply)

Open Me!
diff --git a/web/packages/teleport/src/AppLauncher/AppLauncher.tsx b/web/packages/teleport/src/AppLauncher/AppLauncher.tsx
index 58420124e0..1c61b70d71 100644
--- a/web/packages/teleport/src/AppLauncher/AppLauncher.tsx
+++ b/web/packages/teleport/src/AppLauncher/AppLauncher.tsx
@@ -122,7 +122,6 @@ export function AppLauncher() {
       const stateToken = queryParams.get('state');
       if (!stateToken) {
         initiateNewAuthExchange({
-          fqdn,
           port,
           path,
           params,
@@ -138,7 +137,10 @@ export function AppLauncher() {
       const session = await service.createAppSession(params);
 
       // Set all the fields expected by server to validate request.
-      const url = getXTeleportAuthUrl({ fqdn, port });
+      const url = getXTeleportAuthUrl({
+        publicAddr: resolvedApp.publicAddress,
+        port,
+      });
       url.searchParams.set('state', stateToken);
       url.searchParams.set('subject', session.subjectCookieValue);
       if (requiredApps.length > 1) {
@@ -217,9 +219,15 @@ function prepareFqdn(fqdn: string) {
   }
 }
 
-function getXTeleportAuthUrl({ fqdn, port }: { fqdn: string; port: string }) {
+function getXTeleportAuthUrl({
+  port,
+  publicAddr,
+}: {
+  port: string;
+  publicAddr: string;
+}) {
   try {
-    return new URL(`https://${fqdn}${port}/x-teleport-auth`);
+    return new URL(`https://${publicAddr}${port}/x-teleport-auth`);
   } catch (err) {
     throwFailedToParseUrlError(err);
   }
@@ -235,13 +243,11 @@ function getXTeleportAuthUrl({ fqdn, port }: { fqdn: string; port: string }) {
 //      bookmarked URL), in which the server will redirect the user
 //      to this launcher.
 function initiateNewAuthExchange({
-  fqdn,
   port,
   params,
   path,
   requiredApps,
 }: {
-  fqdn: string;
   port: string;
   // params will only be defined if the user clicked our "launch"
   // app button from the web UI.
@@ -255,7 +261,7 @@ function initiateNewAuthExchange({
   path: string;
   requiredApps: string[];
 }) {
-  const url = getXTeleportAuthUrl({ fqdn, port });
+  const url = getXTeleportAuthUrl({ publicAddr: params.publicAddr, port });
 
   if (path) {
     url.searchParams.set('path', path);

Thanks!

@capnspacehook capnspacehook force-pushed the capnspacehook/trusted-cluster-app-access-regression branch from 2fb2ca4 to 98494cd Compare October 28, 2024 22:38
@capnspacehook capnspacehook force-pushed the capnspacehook/trusted-cluster-app-access-regression branch 2 times, most recently from a67cf46 to 8629517 Compare October 28, 2024 22:57
Copy link
Contributor

@nklaassen nklaassen left a comment

Choose a reason for hiding this comment

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

In the PR description I see what bug this is supposed to fix, but can you please explain how this is meant to fix it?

web/packages/teleport/src/AppLauncher/AppLauncher.tsx Outdated Show resolved Hide resolved
@zmb3
Copy link
Collaborator

zmb3 commented Nov 1, 2024

Does this (Michael's patch) also fix #10671?

@capnspacehook capnspacehook force-pushed the capnspacehook/trusted-cluster-app-access-regression branch from 8629517 to d0d79b7 Compare November 1, 2024 14:35
@capnspacehook
Copy link
Contributor Author

@zmb3 I'm not sure, will test and report back but I'm not optimistic it fixes that. @kimlisa can I get a review please?

@avatus
Copy link
Contributor

avatus commented Nov 1, 2024

Does this (Michael's patch) also fix #10671?

@zmb3 no, it won't fix that unfortunately. However, fixing the issue of same name on root/leaf would probably also fix same name on leaf1/leaf2.

Comment on lines 621 to 624
host := hostname
if req.requiresAppRedirect {
host = req.publicAddr
}
Copy link
Collaborator

Choose a reason for hiding this comment

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

Suggested change
host := hostname
if req.requiresAppRedirect {
host = req.publicAddr
}
if req.requiresAppRedirect {
hostname = req.publicAddr
}

If you update the existing hostname variable instead of making a new variable with a similar name, there's less chance of us mistakenly using the wrong one later on in this function and breaking something.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thinking about this more I agree with how it's done now a bit more; if the variable is set to the public addr calling it hostname isn't very accurate anymore

Copy link
Collaborator

Choose a reason for hiding this comment

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

Then change the input paramater to something like addr.

Having two variables in scope with a similar name, where one works and the other doesn't is a recipe for failure.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Fair enough, done

Copy link
Collaborator

Choose a reason for hiding this comment

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

I was hoping you would rename the function parameter, which was not done.

I don't want two variables in scope where one works and one doesn't. Let's make a single variable (which we overwrite if necessary), so there's no potential for confusion. As written, we still have addr and hostname in scope.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ah I see, I misunderstood. That makes sense, I renamed the hostname parameter to addr. This should make this function less confusing

Copy link
Contributor

@nklaassen nklaassen left a comment

Choose a reason for hiding this comment

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

i also tested this yesterday and it works well

@capnspacehook capnspacehook requested a review from zmb3 November 1, 2024 20:11
Copy link
Collaborator

@zmb3 zmb3 left a comment

Choose a reason for hiding this comment

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

Thanks capn!

@capnspacehook capnspacehook added this pull request to the merge queue Nov 1, 2024
@github-merge-queue github-merge-queue bot removed this pull request from the merge queue due to failed status checks Nov 1, 2024
@capnspacehook capnspacehook added this pull request to the merge queue Nov 1, 2024
Merged via the queue into master with commit 8d0bcc1 Nov 2, 2024
40 checks passed
@capnspacehook capnspacehook deleted the capnspacehook/trusted-cluster-app-access-regression branch November 2, 2024 00:02
capnspacehook added a commit that referenced this pull request Nov 2, 2024
* only redirect to the public addr of an app when an app redirect is required

* rename local variable from 'host' to 'addr'

* rename param
github-merge-queue bot pushed a commit that referenced this pull request Nov 2, 2024
…48334)

* only redirect to the public addr of an app when an app redirect is required

* rename local variable from 'host' to 'addr'

* rename param
@ravicious
Copy link
Member

Could we backport this to v16? According to #46951, it's broken on >= 16.4.0.

avatus pushed a commit that referenced this pull request Nov 15, 2024
* only redirect to the public addr of an app when an app redirect is required

* rename local variable from 'host' to 'addr'

* rename param
@avatus
Copy link
Contributor

avatus commented Nov 15, 2024

@ravicious @capnspacehook #49056 backported it to v16 here

github-merge-queue bot pushed a commit that referenced this pull request Nov 15, 2024
…49056)

* only redirect to the public addr of an app when an app redirect is required

* rename local variable from 'host' to 'addr'

* rename param

Co-authored-by: Andrew LeFevre <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Web application access with browser fails from root cluster with trusted clusters in Teleport >=16.4.0
5 participants