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

404 if Host header include port number 443 #959

Closed
yegle opened this issue Jun 22, 2020 · 8 comments · Fixed by #1126 or #1175
Closed

404 if Host header include port number 443 #959

yegle opened this issue Jun 22, 2020 · 8 comments · Fixed by #1126 or #1175
Assignees
Labels
bug Something isn't working

Comments

@yegle
Copy link
Contributor

yegle commented Jun 22, 2020

What happened?

If Host header includes the standard 443 port number, Pomerium will return 404.

$ curl -I -H 'Host: foo.example.com:443' https://foo.example.com
HTTP/2 404 
date: Mon, 22 Jun 2020 07:23:02 GMT
server: envoy

$ curl -I -H 'Host: foo.example.com' https://foo.example.com 
HTTP/2 302 
content-length: 5
content-type: text/plain
location: LOGIN_URL
date: Mon, 22 Jun 2020 07:23:52 GMT
server: envoy

What did you expect to happen?

Should handle the request correctly.

How'd it happen?

  1. Ran x
  2. Clicked y
  3. Saw error z

What's your environment like?

  • Pomerium version (retrieve with pomerium --version or /ping endpoint):
    pomerium/v0.9.0 (+github.com/pomerium/pomerium; 84dde09; go1.14.4)
  • Server Operating System/Architecture/Cloud:
    Docker

What's your config.yaml?

N/A

What did you see in the logs?

12:23AM INF http-request authority=foo.example.com:443 duration=0.126206 forwarded-for= method=HEAD path=/ referer= request-id=63ed7a23-69ba-48d0-990a-b3c079608df2 response-code=404 response-code-details=route_not_found service=envoy size=0 upstream-cluster= user-agent=curl/7.64.0
12:23AM INF http-request authority=foo.example.com duration=3.894968 forwarded-for= method=HEAD path=/ referer= request-id=aa62dd7c-6506-40c2-b6f6-43247ffb3849 response-code=302 response-code-details=ext_authz_denied service=envoy size=0 upstream-cluster= user-agent=curl/7.64.0

Additional context

Similar but probably unrelated bug #352

@yegle
Copy link
Contributor Author

yegle commented Jun 22, 2020

Workaround: Add the same policy but with port number appended to from:.

- from: https://foo.example.com
  to: ...
- from: https://foo.example.com:443
  to: ...

@yegle yegle changed the title 404 if Host header include port number 404 if Host header include port number 443 Jun 22, 2020
@cuonglm
Copy link
Contributor

cuonglm commented Jun 22, 2020

@yegle This is how envoy works. We can make envoy strip the port part from domain, by set strip_matching_host_port to true.

@yegle
Copy link
Contributor Author

yegle commented Jun 22, 2020

Yes found this https://www.envoyproxy.io/docs/envoy/latest/faq/debugging/why_is_my_route_not_found also suggest to set strip_matching_host_port to true.

I would assume it's as easy as adding a StripMatchingHostPort: true in the code below but it looks like Pomerium still uses 0.9.5 of Envoy and doesn't include this option.

here

tc, _ := ptypes.MarshalAny(&envoy_http_connection_manager.HttpConnectionManager{
CodecType: envoy_http_connection_manager.HttpConnectionManager_AUTO,
StatPrefix: "ingress",
RouteSpecifier: &envoy_http_connection_manager.HttpConnectionManager_RouteConfig{
RouteConfig: buildRouteConfiguration("main", virtualHosts),
},
HttpFilters: []*envoy_http_connection_manager.HttpFilter{
{
Name: "envoy.filters.http.ext_authz",
ConfigType: &envoy_http_connection_manager.HttpFilter_TypedConfig{
TypedConfig: extAuthZ,
},
},
{
Name: "envoy.filters.http.lua",
ConfigType: &envoy_http_connection_manager.HttpFilter_TypedConfig{
TypedConfig: extAuthzSetCookieLua,
},
},
{
Name: "envoy.filters.http.lua",
ConfigType: &envoy_http_connection_manager.HttpFilter_TypedConfig{
TypedConfig: cleanUpstreamLua,
},
},
{
Name: "envoy.filters.http.router",
},
},
AccessLog: buildAccessLogs(options),
CommonHttpProtocolOptions: &envoy_config_core_v3.HttpProtocolOptions{
IdleTimeout: ptypes.DurationProto(options.IdleTimeout),
MaxStreamDuration: maxStreamDuration,
},
RequestTimeout: ptypes.DurationProto(options.ReadTimeout),
Tracing: &envoy_http_connection_manager.HttpConnectionManager_Tracing{
RandomSampling: &envoy_type_v3.Percent{Value: options.TracingSampleRate * 100},
},
})

@yegle
Copy link
Contributor Author

yegle commented Jun 22, 2020

I was a bit confused. It looks like the commit envoyproxy/envoy@111684f is not part of any Envoy release yet. And the go control plane library is likely kept in sync with Envoy so it doesn't have StripMatchingHostPort. (Pomerium is already using the latest released version of envoy go control plane library).

I guess we'll have to use the workaround for now.

@cuonglm
Copy link
Contributor

cuonglm commented Jun 22, 2020

I was a bit confused. It looks like the commit envoyproxy/envoy@111684f is not part of any Envoy release yet. And the go control plane library is likely kept in sync with Envoy so it doesn't have StripMatchingHostPort. (Pomerium is already using the latest released version of envoy go control plane library).

I guess we'll have to use the workaround for now.

Yes, we will have to wait new envoy release.

@desimone desimone added bug Something isn't working blocked PR/ISSUE is blocked by third party labels Jun 22, 2020
@desimone desimone removed the blocked PR/ISSUE is blocked by third party label Jul 21, 2020
@cuonglm cuonglm self-assigned this Jul 21, 2020
cuonglm added a commit that referenced this issue Jul 22, 2020
With envoy 1.15.0 release, strip host port matching setting allows
incoming request with Host "example:443" will match again route with
domains match set to "example".

Not that this is not standard HTTP behavior, but it's more convenient
for users.

Fixes #959
cuonglm added a commit that referenced this issue Jul 22, 2020
* internal/controlplane: using envoy strip host port matching

With envoy 1.15.0 release, strip host port matching setting allows
incoming request with Host "example:443" will match again route with
domains match set to "example".

Not that this is not standard HTTP behavior, but it's more convenient
for users.

Fixes #959

* docs/docs: add note about enable envoy strip host port matching
@cuonglm cuonglm reopened this Jul 23, 2020
@cuonglm cuonglm closed this as completed Jul 23, 2020
@yegle
Copy link
Contributor Author

yegle commented Jul 30, 2020

This is not fully resolved. It looks like a request with header Host: example.com:443 will disable public unauthenticated access:

$ curl -I https://plex.example.com -H 'Host: plex.example.com:443'
HTTP/2 302 
content-length: 5
content-type: text/plain
location: https://pomerium.example.com/.pomerium/sign_in?XXXX
date: Thu, 30 Jul 2020 23:05:42 GMT
server: envoy

$ curl -I https://plex.example.com -H 'Host: plex.example.com'    
HTTP/2 401 
x-plex-protocol: 1.0
content-length: 193
content-type: text/html
cache-control: no-cache
date: Thu, 30 Jul 2020 23:05:51 GMT
x-envoy-upstream-service-time: 0
strict-transport-security: max-age=31536000; includeSubDomains; preload
x-frame-options: SAMEORIGIN
x-xss-protection: 1; mode=block
server: envoy

Policy config:

- from: https://plex.example.com
  to: https://plex:32400
  allow_public_unauthenticated_access: true
  allow_websockets: true

@desimone
Copy link
Contributor

\cc @cuonglm / @calebdoxsey

@desimone desimone reopened this Jul 31, 2020
@calebdoxsey
Copy link
Contributor

The route matching code in authorize needs to be updated.

cuonglm added a commit that referenced this issue Jul 31, 2020
After #1153, envoy can handle routes for `example.com` and `example.com:443`.
Authorize service should be updated to handle this case, too.

Fixes #959
cuonglm added a commit that referenced this issue Jul 31, 2020
After #1153, envoy can handle routes for `example.com` and `example.com:443`.
Authorize service should be updated to handle this case, too.

Fixes #959
cuonglm added a commit that referenced this issue Aug 1, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
4 participants