aspnet / BasicMiddleware

[Archived] Basic middleware components for ASP.NET Core. Project moved to https://github.com/aspnet/AspNetCore
Apache License 2.0
169 stars 84 forks source link

::ffff:127.0.0.1 not recognized as trusted local proxy #341

Closed proog closed 6 years ago

proog commented 6 years ago

I'm trying to use the ForwardedHeaders middleware behind a reverse proxy. However, it seems that if my application is started with explicit wildcard urls, such as by specifying ASPNETCORE_URLS=http://+:5000, the X-Forwarded headers are ignored.

Steps to reproduce

Initialize an empty ASP.NET Core 2.1 project and add the ForwardedHeaders middleware and the troubleshooting code from the documentation.

Start the application without explicit urls or with the explicit url http://127.0.0.1:5000. Make a request with mock X-Forwarded-For and X-Forwarded-Proto headers. The response looks something like this:

Request Method: GET
Request Scheme: https
Request Path: /
Request Headers:
Host: 127.0.0.1:5000
X-Original-Proto: http
X-Original-For: 127.0.0.1:65345

Request RemoteIp: 12.34.56.78

Now start the application with a url of e.g. http://+:5000. The response now looks like this:

Request Method: GET
Request Scheme: http
Request Path: /
Request Headers:
Host: 127.0.0.1:5000
X-Forwarded-Proto: https
X-Forwarded-For: 12.34.56.78

Request RemoteIp: ::ffff:127.0.0.1

I'm stumped as to why this happens, and it seems to me like a bug. If this is indeed the intended behavior,

  1. is it documented anywhere?
  2. what is the recommended way to combine forwarded headers and wildcard urls?
Tratcher commented 6 years ago

? ForwardedHeaders has no knowledge of the server url settings. It looks like you're having an issue with KnownProxies instead. https://github.com/aspnet/BasicMiddleware/blob/baf5c7b3e245a9b0a15fb57b364bc110f89f5788/src/Microsoft.AspNetCore.HttpOverrides/ForwardedHeadersOptions.cs#L63

The wildcard binding binds to IPv6 so you get back an IPv6 remote IP. Note the remote IP is ::ffff:127.0.0.1, not 127.0.0.1. When you bind to http://127.0.0.1:5000 you're binding to IPv4. What happens if you bind tohttp://[::1]:5000`?

Possible workaround: Add ::ffff:127.0.0.1 to KnownProxies.

proog commented 6 years ago

Ah, it seems you're absolutely right. Thank you for the clarification.

I was unaware that wildcard bindings bind to IPv6. What is in my opinion fairly unintuitive is that binding to e.g. http://+:5000 allows clients to successfully connect using either [::1] or 127.0.0.1 (which ends up as ::ffff:127.0.0.1), but only the former will actually have the forwarded headers processed by ForwardedHeaders, while the other will fail silently (due to the default value of KnownProxies).

Tratcher commented 6 years ago

We may consider adding ::ffff:127.0.0.1 to KnownProxies. This is the first time I've seen it come up.

Which server and which OS are you using?

proog commented 6 years ago

I'm using Kestrel 2.1 on OSX 10.13.

SebastianC commented 6 years ago

I believe this was resolved with #358. passing unit test: https://github.com/aspnet/BasicMiddleware/blob/release/2.2/test/Microsoft.AspNetCore.HttpOverrides.Tests/ForwardedHeadersMiddlewareTest.cs#L827