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

reverseproxy: return validation error if upstream address has port range size of more than 1 #3695

Merged
merged 2 commits into from
Sep 17, 2020

Conversation

mohammed90
Copy link
Member

Currently the Provision-er of the reverse proxy handler accepts upstream network address with range size more than 1. This means the following Caddyfile is accepted and validates successfully:

localhost
reverse_proxy localhost:2000-2020

This is despite the comment on the Dial field of the Upstream struct saying only a single socket is accepted:

// The [network address](/docs/conventions#network-addresses)
// to dial to connect to the upstream. Must represent precisely
// one socket (i.e. no port ranges). A valid network address
// either has a host and port or is a unix socket address.
//
// Placeholders may be used to make the upstream dynamic, but be
// aware of the health check implications of this: a single
// upstream that represents numerous (perhaps arbitrary) backends
// can be considered down if one or enough of the arbitrary
// backends is down. Also be aware of open proxy vulnerabilities.
Dial string `json:"dial,omitempty"`

The code doesn't validate that until request time, when the method fillDialInfo is called:

if numPorts := addr.PortRangeSize(); numPorts != 1 {
return DialInfo{}, fmt.Errorf("upstream %s: dial address must represent precisely one socket: %s represents %d",
u.Dial, dial, numPorts)
}

This PR adds validation of the port range size of an upstream address to the Provision step. We can sugar the Caddyfile upstream to accept port range and convert it to the JSON array for the entire specified range.

@mohammed90 mohammed90 requested a review from mholt August 31, 2020 23:05
@mohammed90 mohammed90 added under review 🧐 Review is pending before merging bug 🐞 Something isn't working labels Sep 1, 2020
@francislavoie
Copy link
Member

francislavoie commented Sep 1, 2020

Hmm, yeah I think we should continue to support that, not reject it. It was a thing in Caddy v1 and was intended to work in v2.

@mohammed90
Copy link
Member Author

mohammed90 commented Sep 1, 2020

It didn't work before. It would've just failed at runtime rather than during validation.

@francislavoie
Copy link
Member

Understood - but we should actually fix it instead of rejecting it 🙂

@mohammed90
Copy link
Member Author

Hmm okay, how should we handle them? Should we expand them into the upstream slice? This makes it simpler for the selection policy to work.

The other approach is to treat network addresses whose port range size is greater than 1 as a single unit, but the selection policy might need to be applied recursively or at random.

@francislavoie
Copy link
Member

🤔 I think the Caddyfile adapter can expand it out. Probably the easiest way to deal with it.

@mohammed90
Copy link
Member Author

Oh so you're saying the JSON should reject upstream network addresses whose port range size is greater than 1, but the Caddyfile should accept it, right? I understood your earlier comment to apply to both JSON and Caddyfile.

@francislavoie
Copy link
Member

Either that, or we expand it out early at provisioning time so it's supported everywhere?

Copy link
Member

@mholt mholt left a comment

Choose a reason for hiding this comment

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

The tricky thing about expanding them out into multiple upstreams is the user might expect all of them to act as one upstream, because they were configured together. This has implications with regards to load balancing and health checks.

So to keep things simple, for now I disallowed port ranges. I remember initially thinking that expanding them out would be no problem (and thus didn't put in this check here), but when I got around to HC and LB it got complicated so I changed my mind.

Anyway, this is a good change I think. Thanks!

modules/caddyhttp/reverseproxy/reverseproxy.go Outdated Show resolved Hide resolved
@mohammed90 mohammed90 changed the title reverse_proxy: ensure upstream address has port range of only 1 reverse_proxy: return validation error if upstream address has port range size of more than 1 Sep 1, 2020
@mohammed90 mohammed90 changed the title reverse_proxy: return validation error if upstream address has port range size of more than 1 reverseproxy: return validation error if upstream address has port range size of more than 1 Sep 1, 2020
@mholt mholt removed bug 🐞 Something isn't working under review 🧐 Review is pending before merging labels Sep 17, 2020
Copy link
Member

@mholt mholt left a comment

Choose a reason for hiding this comment

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

Excellent, look good! Thank you as always, Mohammed!

@mholt mholt merged commit d55d50b into master Sep 17, 2020
@mholt mholt deleted the validate-upstream-range branch September 17, 2020 01:48
@mholt mholt added this to the v2.2.0 milestone Sep 17, 2020
mholt added a commit that referenced this pull request Oct 7, 2020
mholt added a commit that referenced this pull request Oct 13, 2020
* reverseproxy: Fix dial placeholders, SRV, active health checks

Supercedes #3776
Partially reverts or updates #3756, #3693, and #3695

* reverseproxy: add integration tests

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

Successfully merging this pull request may close these issues.

3 participants