I just tried to use the HttpOverrides middleware and went through a lot more pain than I had expected:
The application is hosted on a server in an Azure VNET (10.10.1.5). I'm using an Azure Application Gateway in front of it which sits in a separate subnet of the same VNET (10.10.3.4). I'd consider this a pretty common setup.
Being naive, I followed the samples and tried this - to my surprise, it didn't work:
Again, no success. Now I've finally seen the warning log messages from before. That's why I've also added RequireHeaderSymmetry (I want the IP in as many cases as possible):
But again, no success. After looking at the source, I've seen that there's a KnownProxies property. This didn't pop up in IntelliSense of the object initializer because it doesn't have a public setter.
var forwardedOptions = new ForwardedHeadersOptions
{
RequireHeaderSymmetry = false,
ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto,
};
forwardedOptions.KnownProxies.Clear();
app.UseForwardedHeaders(forwardedOptions);
However, still no success. After digging further into the source code, I've seen that the middleware has some LogLevel=Debug outputs which I haven't seen because my minimum Log Level was "Information". This gave me an "Unknown proxy" message. No I realized that there's also a KnownNetworks property - not sure why I missed this before.
After clearing this as well, I ended up with the following configuration which finally worked:
var forwardedOptions = new ForwardedHeadersOptions
{
RequireHeaderSymmetry = false,
ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto,
};
forwardedOptions.KnownNetworks.Clear();
forwardedOptions.KnownProxies.Clear();
app.UseForwardedHeaders(forwardedOptions);
Of course, in hindsight I could have figured this out faster, but still I think that there are quite a few issues with the current default settings:
The original IP is REALLY important.: IMO it's better to set a value, even if the headers don't match. Just ignoring the IP and keeping the proxy IP leaves one completely blind. So I don't think, RequireHeaderSymmetry should be true by default. What's the benefit with this?
KnownProxies/KnownNetworks could be made more discoverable by making it public set to use it in the object initializer.
"Unknown proxy" is a pretty interesting message. My app is running in an internal network so every occurence of this is at least "informational".
Very few people run a proxy on 127.0.0.1 or ::1. Limiting the middleware to localhost is very weird. Also, it's not documented that these are added by default. Why isn't this opt-in? If this should be a security measure to prevent unintended access, why not block the request completely? What's the point in just ignoring the value?
The code I ended up with is far from simple/reusable. We have multiple applications which need this setup. Would have been nicer if this was covered by the defaults.
Related: https://github.com/aspnet/BasicMiddleware/issues/190 in that we need to doc this whole experience to avoid these issue. Also considering changing some defaults to not hit the failure cases as commonly.
I just tried to use the HttpOverrides middleware and went through a lot more pain than I had expected:
The application is hosted on a server in an Azure VNET (10.10.1.5). I'm using an Azure Application Gateway in front of it which sits in a separate subnet of the same VNET (10.10.3.4). I'd consider this a pretty common setup.
Being naive, I followed the samples and tried this - to my surprise, it didn't work:
After some digging, I finally found that Azure Application Gateway doesn't set the X-Forwarded-Host header. Next attempt:
Again, no success. Now I've finally seen the warning log messages from before. That's why I've also added RequireHeaderSymmetry (I want the IP in as many cases as possible):
But again, no success. After looking at the source, I've seen that there's a KnownProxies property. This didn't pop up in IntelliSense of the object initializer because it doesn't have a public setter.
However, still no success. After digging further into the source code, I've seen that the middleware has some LogLevel=Debug outputs which I haven't seen because my minimum Log Level was "Information". This gave me an "Unknown proxy" message. No I realized that there's also a
KnownNetworks
property - not sure why I missed this before. After clearing this as well, I ended up with the following configuration which finally worked:Of course, in hindsight I could have figured this out faster, but still I think that there are quite a few issues with the current default settings:
RequireHeaderSymmetry
should be true by default. What's the benefit with this?Your thoughts?