Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

feat: Add serving applications on subdomains and port-based proxying#3753

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 ourterms of service andprivacy statement. We’ll occasionally send you account related emails.

Already on GitHub?Sign in to your account

Merged
deansheather merged 29 commits intomainfromstevenmasley/unnamed-apps
Sep 13, 2022

Conversation

Emyrk
Copy link
Member

@EmyrkEmyrk commentedAug 30, 2022
edited
Loading

What this does

This PR adds the ability to serve applications at/ on subdomains. It also allows accessing ports inside a workspace with an anonymous application.

Examples:

Conversation Wanted

I hit a wall working on this, and want some discussion before I proceed.

Token Scoping + Security

We need to scope thesession_token used for application authentication. It should only have access to application endpoints, and nothing else. This is so a malicious application cannot make authenticated requests on a user's behalf.

We can do this with RBAC token scopes as defined in the RFC, or by making a new token type like we did for agent authentication. The new token can live incoder_application_token.

If the application is using the path based routing, then thesession_token of the primary auth can still be used. We need to either have a security setting to always host applications on another subdomain, or somehow reject api calls from these paths (??).

Applications on another domain

Eventually we want to serve applications on another domain for security reasons. To do this, we need to implement a way to insert a cookie on that subdomain, like we did with devurls in V1. I suggest we do this as a follow up PR.

Applications on subpath

We should be checking if authenticated requests come from an app via theOrigin header. If it is, we should not allow that Origin to make authenticated requests.


At present

At present we do not allow sharing these application URLs to other users. So all of the security considerations can be follow ups.


Future Work

  • Support serving apps on other domains
  • Scoped tokens to just application authentication
  • Security check on the things above, might need some setting toggles to disallow certain things.

bpmct reacted with thumbs up emoji
@bpmct
Copy link
Member

I'll defer to@sreya and@kylecarbs on the token scoping. From a product POV, supporting the following as a first iteration seems solid:

coder.mydomain.com# host*.coder.mydomain.com# subdomains for apps

We can open another issue "Run Coder apps on a separate domain" as some users may eventually want

coder.mydomain.com*.different-coder-apps-domain.com

(We have a few Coder Classic customers who do this today for security reasons)

Emyrk and ntimo reacted with thumbs up emoji

@Emyrk
Copy link
MemberAuthor

(We have a few Coder Classic customers who do this today for security reasons)

Yes, it's more secure to run from another domain. I think we will want to implement some sort of toggle on the BE to block the same domain in the future.

Awesome on first iteration though 👍. For now, I think I'll just throw a cookie on both.domain anddomain to handle this. We will need to tighten security in future.

@EmyrkEmyrk marked this pull request as ready for reviewAugust 30, 2022 14:03
@bpmct
Copy link
Member

For named applications, will this PR make therelative_path property for coder_app function as expected? (e.g. links from to apps from the web UI will go to the subdomain)

@Emyrk
Copy link
MemberAuthor

Emyrk commentedAug 30, 2022
edited
Loading

For named applications, will this PR make therelative_path property for coder_app function as expected? (e.g. links from to apps from the web UI will go to the subdomain)

It will not. The deployment still needs to setup their certs with wildcards to support this feature. Sorelative_path still requires some deployment side config. We need to figure out how to go about displaying this 🤔

The subdomain url will work, but the FE still has the path based link

bpmct reacted with thumbs up emoji

kylecarbs
kylecarbs previously requested changesAug 31, 2022
@kylecarbs
Copy link
Member

@Emyrk since oursession_token is HTTPOnly, is there any way to steal the cookie even with a malicious application? I'm thinking no, but I'm not sure.

@f0ssel
Copy link
Contributor

@Emyrk since oursession_token is HTTPOnly, is there any way to steal the cookie even with a malicious application? I'm thinking no, but I'm not sure.

We also strip the session token header on the proxy as well, correct?

@Emyrk
Copy link
MemberAuthor

@Emyrk since oursession_token is HTTPOnly, is there any way to steal the cookie even with a malicious application? I'm thinking no, but I'm not sure.

We strip the cookie in the proxy app:

for_,cookieHeader:=rangecookieHeaders {
r.Header.Add("Cookie",httpapi.StripCoderCookies(cookieHeader))
}

There is something you can do though with a malicious app. You can send authenticated requests to coderd. This is an issue I put in the description. We should not allow sharing apps until we close that

Copy link
Collaborator

@BrunoQuaresmaBrunoQuaresma left a comment

Choose a reason for hiding this comment

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

LGTM

@BrunoQuaresma
Copy link
Collaborator

@deansheather right now, I'm doing this in the FE:

# Subdomain`${port}--${agentName}--${workspaceName}--${username}.dev.coder.com`# Subpath`https://dev.coder.com/@${username}/${workspaceName}/apps/${port}`

Is that right?

@deansheather
Copy link
Member

Yes@BrunoQuaresma, but the subpath should be/@$username/$workspace.$agent/apps/$port. The port is also interchangeable with an application name in both cases

BrunoQuaresma reacted with thumbs up emoji

Comment on lines 262 to 291
// ParseSubdomainAppURL parses an application from the subdomain of r's Host
// header. If the subdomain is not a valid application URL hostname, returns a
// non-nil error.
//
// Subdomains should be in the form:
//
//{PORT/APP_NAME}--{AGENT_NAME}--{WORKSPACE_NAME}--{USERNAME}
//(eg. http://8080--main--dev--dean.hi.c8s.io)
func ParseSubdomainAppURL(hostname string) (ApplicationURL, error) {
subdomain, rest, err := SplitSubdomain(hostname)
if err != nil {
return ApplicationURL{}, xerrors.Errorf("split host domain %q: %w", hostname, err)
}

matches := appURL.FindAllStringSubmatch(subdomain, -1)
if len(matches) == 0 {
return ApplicationURL{}, xerrors.Errorf("invalid application url format: %q", subdomain)
}
matchGroup := matches[0]

appName, port := AppNameOrPort(matchGroup[appURL.SubexpIndex("AppName")])
return ApplicationURL{
AppName: appName,
Port: port,
AgentName: matchGroup[appURL.SubexpIndex("AgentName")],
WorkspaceName: matchGroup[appURL.SubexpIndex("WorkspaceName")],
Username: matchGroup[appURL.SubexpIndex("Username")],
BaseHostname: rest,
}, nil
}
Copy link
Member

Choose a reason for hiding this comment

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

Ithinkhttpapi might be a better spot for this too, but it's a bit weird, so chef's choice on this one. Regardless, I think it'd be better to remove this from being exposed and use an_internal.go test for it.

Copy link
Member

Choose a reason for hiding this comment

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

how do you do the internal test thing? I've never seen that before

Copy link
Member

Choose a reason for hiding this comment

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

Moved to httpapi

// We only support setting this cookie on the access URL subdomains. This is
// to ensure we don't accidentally leak the auth cookie to subdomains on
// another hostname.
appCookie.Domain = "." + api.AccessURL.Hostname()
Copy link
Member

Choose a reason for hiding this comment

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

This is interesting... I didn't know we could apply to subdomains without requiring an authentication redirect, this is awesome.

Copy link
Member

Choose a reason for hiding this comment

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

We probably won't be doing this soon as we'll be implementing proper devurl auth similarly to v1

Copy link
MemberAuthor

Choose a reason for hiding this comment

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

@kylecarbs this is a stop gap. It will not work on apps hosted on another domain.

Also currently using the same full auth token. We should used scoped auth tokens.

kylecarbs reacted with thumbs up emoji
Copy link
Member

@kylecarbskylecarbs left a comment

Choose a reason for hiding this comment

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

@deansheather are we going to use [relative_path}(https://registry.terraform.io/providers/coder/coder/latest/docs/resources/app#relative_path) to determine the client-side routing?

It seems like we'll need to add a server-side option for the wildcard path so we can redirect users on the frontend properly, or we could assume a wildcard above the root, but we'd just have to document that.

@deansheather
Copy link
Member

It seems like we'll need to add a server-side option for the wildcard path so we can redirect users on the frontend properly, or we could assume a wildcard above the root, but we'd just have to document that.

@kylecarbs this PR only does wildcards underneath the site--access-url (i.e.dev.coder.com =>app--agent--ws--user.dev.coder.com), and not if the access URL is an IP address as that's obviously not supported.

In a future PR when we implement proper devurl auth (with their own tokens, similar to v1) we will be able to support separate domains, and it'll be configurable through a separate--devurl-domain flag or something.

This PR is the MVP for hostname based routing

kylecarbs reacted with thumbs up emoji

Copy link
Collaborator

@sreyasreya left a comment

Choose a reason for hiding this comment

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

Seems reasonable overall

Comment on lines 891 to 894
devurlCookie := api.applicationCookie(cookie)
if devurlCookie != nil {
http.SetCookie(rw, devurlCookie)
}
Copy link
Collaborator

Choose a reason for hiding this comment

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

api.setAuthCookie

Copy link
Member

@bpmctbpmct left a comment
edited
Loading

Choose a reason for hiding this comment

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

The frontend uses an environment variable which decides whether links in the dashboard should go to a wildcard or path (if the admin didn't set up wildcard DNS, for example).

CODER_ENABLE_WILDCARD_APPS:"",

What do you think about having this also impact the functionality (e.g. whether the app is routed) versus it being purely a cosmetic/dashboard variable?

If it's the latter, perhaps we should rename the var in#3812. I suggested the name, but originally assumed it'd be used across both.

@deansheatherdeansheather changed the titlefeat: Add serving applications at/ on subdomainsfeat: Add serving applications on subdomains and port-based proxyingSep 12, 2022
@deansheather
Copy link
Member

@bpmct the env var can be temporary until we do the changes I said in my above comment. I'll add a check for the env var

@deansheather
Copy link
Member

Actually@bpmct that's a build time env var, not a proper one. I'm just going to merge this as is and we can figure out what we want to do about it when we solve the devurl auth problem

Copy link
Member

@kylecarbskylecarbs left a comment

Choose a reason for hiding this comment

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

My comment mentioningrelative_path indicates that in its current form, there's no way to access a wildcard application from the frontend. We should respect that value, and direct a user to the subdomain if it's specified (maybe it's calledwildcard instead, so we don't break current behavior).

We also need to specify whether the wildcard is enabled or not, and have that information surfaced to the frontend so the "Open Port" button open in a subsequent PR functions.

}).String()
}

t.Run("NoAuthShould401", func(t *testing.T) {
Copy link
Member

Choose a reason for hiding this comment

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

Could we redirect to/login with aredirect query parameter back to the subdomain URL instead? Seems like this would be a questionable UX.

Copy link
Member

Choose a reason for hiding this comment

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

I've made it redirect to login but it's impossible to redirect back to the subdomain because we can't determine whether the accessed scheme was HTTP or HTTPS. If users are using a reverse proxy in front of coder (which they likely will) then coder will think it's receiving HTTP traffic when the actual scheme is HTTPS.

kylecarbs reacted with thumbs up emoji
@deansheather
Copy link
Member

@kylecarbs Bruno is working on this in a separate frontend PR. He will be reading that value to figure out whether to link to wildcard or path-based route.

BrunoQuaresma reacted with thumbs up emoji

@BrunoQuaresma
Copy link
Collaborator

@kylecarbs here is the related PR#3812

@deansheatherdeansheather merged commit9ab437d intomainSep 13, 2022
@deansheatherdeansheather deleted the stevenmasley/unnamed-apps branchSeptember 13, 2022 17:31
Sign up for freeto join this conversation on GitHub. Already have an account?Sign in to comment
Reviewers

@sreyasreyasreya approved these changes

@kylecarbskylecarbskylecarbs approved these changes

@deansheatherdeansheatherdeansheather left review comments

@bpmctbpmctbpmct left review comments

@BrunoQuaresmaBrunoQuaresmaBrunoQuaresma approved these changes

@f0sself0sselAwaiting requested review from f0ssel

@mafredrimafredriAwaiting requested review from mafredri

Assignees

@deansheatherdeansheather

Labels
None yet
Projects
None yet
Milestone
No milestone
Development

Successfully merging this pull request may close these issues.

7 participants
@Emyrk@bpmct@kylecarbs@f0ssel@deansheather@BrunoQuaresma@sreya

[8]ページ先頭

©2009-2025 Movatter.jp