Skip to content

Conversation

erezrokah
Copy link
Contributor

@erezrokah erezrokah commented Jan 10, 2024

Same as #4246 ported for v3

Since this is intended for v3 which is a major bump I used the existing option to opt out, and made HTTP2 the default both for TLS and non TLS connections.

Fixes #4241

To test:

docker build . -t registry:v3-h2c
docker run -e REGISTRY_HTTP_H2C_ENABLED='true' -p 5000:5000 registry:v3-h2c

Then on a separate shell:

curl -i --http2-prior-knowledge http://localhost:5000 
HTTP/2 200 
cache-control: no-cache
content-length: 0
date: Fri, 05 Jan 2024 15:40:04 GMT

curl -i http://localhost:5000
HTTP/1.1 200 OK
Cache-Control: no-cache
Date: Fri, 05 Jan 2024 15:40:31 GMT
Content-Length: 0

@erezrokah erezrokah changed the title feat: Add HTTP2 for unencrypted HTTP feat: Add HTTP2 for unencrypted HTTP (opt-out config) Jan 10, 2024
@milosgajdos
Copy link
Member

Ok so this breaks storage tests, but the validation succeeds which makes me think the v2 dependency tracking is trashy as it always has been 🫠

@erezrokah
Copy link
Contributor Author

Thanks I'll take a look at the failing tests

@milosgajdos
Copy link
Member

I've re-run the failed job and it seems we're good now, but I'm now wondering if there is some race condition lurking somewhere in the tests 🤨

Copy link
Collaborator

@corhere corhere left a comment

Choose a reason for hiding this comment

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

Why? Just because you can, doesn't mean you should. Client support for h2c is limited. If anyone wants to expose a registry over h2c, they can stick a reverse proxy in front. I don't see a compelling reason to natively support h2c in distribution.

@erezrokah
Copy link
Contributor Author

Why? Just because you can, doesn't mean you should. Client support for h2c is limited. If anyone wants to expose a registry over h2c, they can stick a reverse proxy in front. I don't see a compelling reason to natively support h2c in distribution.

Thanks for the feedback @corhere, I should have linked the issue in this PR too. See the use case in #4241

Not sure how one would put a reverse proxy when using a managed service or any kind of hosted load balancer.
I was also following the suggestion in #4246 (comment)

If it makes sense I can put this via an opt-in configuration too as in #4246

@corhere
Copy link
Collaborator

corhere commented Jan 10, 2024

Fair, that's a legitimate use case. I'll have to think about whether it makes more sense as opt-in or opt-out

@milosgajdos
Copy link
Member

Personally, I'd keep it opt-in for now, instead of enforcing it on users in v3 release.

If there is a stronger demand for this we can make it a default in the next release and change it to opt-out.

@milosgajdos milosgajdos requested a review from corhere January 11, 2024 09:48
@erezrokah erezrokah changed the title feat: Add HTTP2 for unencrypted HTTP (opt-out config) feat: Add HTTP2 for unencrypted HTTP (opt-in config) Jan 11, 2024
@erezrokah
Copy link
Contributor Author

Personally, I'd keep it opt-in for now, instead of enforcing it on users in v3 release.

Done in 8eb4f48

@erezrokah erezrokah changed the title feat: Add HTTP2 for unencrypted HTTP (opt-in config) feat: Add HTTP2 for unencrypted HTTP (v3) Jan 11, 2024
@erezrokah
Copy link
Contributor Author

I've re-run the failed job and it seems we're good now, but I'm now wondering if there is some race condition lurking somewhere in the tests 🤨

Fixed the storage tests in #4251

Copy link
Member

@milosgajdos milosgajdos left a comment

Choose a reason for hiding this comment

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

LGTM, PTAL @corhere

@Jamstah
Copy link
Collaborator

Jamstah commented Jan 15, 2024

Do you know of clients that support this?

Would enabling it by default break any scenarios you can think of?

As we are doing a major release, turning feature like this on by default makes sense to me as long as its safe and useable.

@erezrokah
Copy link
Contributor Author

Do you know of clients that support this?

I tested it in the Docker Go SDK and it works. Haven't tried about other clients. Having it work in the Go SDK means that the engine/daemon supports it right?

@corhere
Copy link
Collaborator

corhere commented Jan 15, 2024

@Jamstah The "client" in the author's case is the GCP Cloud Run application gateway.

I don't think we should enable h2c support by default, ever. All mechanisms for client/server negotiation of h2c have been deprecated, so h2c is only useable by a client with prior knowledge that the server supports h2c. I think it's safe to say that no sane registry client should be making h2c requests to a distribution service over the internet, so h2c support in the distribution server is only useful in a deployment scenario such as the GCP Cloud Run one where an HTTP/2-compatible application gateway is terminating TLS without downgrading the reverse-proxied connection to HTTP/1.1. In practice, "prior knowledge" for the gateway takes the form of explicit configuration to forward requests to the backend as h2c, so an administrator would have to explicitly opt into using h2c in their environment regardless. Therefore enabling h2c support in distribution by default would only be a trivial convenience for administrators who know about h2c and want to use it in their environment, while being of no benefit to anyone else.

If h2c support is enabled, it might be possible to smuggle crafted HTTP/2 requests past an HTTP/1.1-only application gateway that the gateway would have otherwise blocked. Having h2c support enabled by default would therefore open everyone else up to HTTP request smuggling attacks they would not otherwise be impacted by. Furthermore, having Go's HTTP/2 server implementation enabled increases the attack surface for remotely-exploitable vulnerabilities. It would be an acceptable risk iff the distribution service could receive legitimate HTTP/2 requests. Only the administrator of the distribution service can judge for themselves whether the risk is acceptable for their environment. Therefore h2c disabled by default is the only correct choice, in my view.

Copy link
Collaborator

@corhere corhere left a comment

Choose a reason for hiding this comment

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

The new config flag also needs to be added to docs/content/about/configuration.md.

@Jamstah
Copy link
Collaborator

Jamstah commented Jan 15, 2024

Thanks for the explanation. Sounds like we're on the right track then, and can merge after adding to the docs.

@erezrokah erezrokah force-pushed the feat/allow_h2c_v3 branch 2 times, most recently from 358cf9a to 61b4e27 Compare January 16, 2024 13:04
@erezrokah
Copy link
Contributor Author

CI failure seems unrelated (fixed in #4256).

Added another commit for the docs in 61b4e27.

I updated the http2 part to clarify it's only used when tls is configured and also used the proper casing for HTTP where applicable.

Please let me know what you think

@milosgajdos
Copy link
Member

Now that #4256 has been merged, mind rebasing @erezrokah

@milosgajdos
Copy link
Member

Looks like we still need to remove

area/config:
- charts/registry/config/**/*

@erezrokah
Copy link
Contributor Author

Looks like we still need to remove

#4257

@erezrokah
Copy link
Contributor Author

@milosgajdos
Copy link
Member

Looks like labeler@v5 changed the structure of the config file significantly hence

It's hard not feel persistently depressed when debugging GHA issues....it really is

@erezrokah
Copy link
Contributor Author

It's hard not feel persistently depressed when debugging GHA issues....it really is

Hopefully #4258 fixes it

@milosgajdos
Copy link
Member

Can you squash @erezrokah

@github-actions github-actions bot added area/config Related to registry config dependencies Pull requests that update a dependency file area/docs labels Jan 17, 2024
@erezrokah
Copy link
Contributor Author

Can you squash @erezrokah

I rebased the PR. Do you want me to squash all commits into a single one or you'll do it once you merge the PR?

@corhere
Copy link
Collaborator

corhere commented Jan 17, 2024

Squash down to one commit before merge, please. Squash-merge is disabled on this repository.

@erezrokah erezrokah force-pushed the feat/allow_h2c_v3 branch 2 times, most recently from de76696 to 959a9f9 Compare January 17, 2024 20:58
Signed-off-by: erezrokah <erezrokah@users.noreply.github.com>
@erezrokah
Copy link
Contributor Author

Squash down to one commit before merge, please. Squash-merge is disabled on this repository.

Done, thanks

@milosgajdos milosgajdos merged commit 945eed7 into distribution:main Jan 18, 2024
@erezrokah erezrokah deleted the feat/allow_h2c_v3 branch January 18, 2024 14:35
@erezrokah
Copy link
Contributor Author

Thanks everyone for the thoughtful reviews 🚀

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area/config Related to registry config area/docs dependencies Pull requests that update a dependency file
Projects
None yet
Development

Successfully merging this pull request may close these issues.

feat: Support h2c protocol (HTTP2 over cleartext)
4 participants