use 'X-Forwarded-For' instead of '$remote_ip' in pluggin 'rate-limiting' - nginx

We have many layers before Kong server.
How can we use the plugin rate-limiting to limit requests by every enduser's client IP?
I want the plugin rate-limiting to read the header X-Forwarded-For to get the users real IP. But I think it is using $remote_ip by rate-limiting.
Any suggestions?

Related

Cloud foundry / XSA how to make http only service

We are working on SAP XS Advanced that is based on Cloud foundry and we got into a funny situation, we need an app to be HTTP only (I know it's not secure...but our situation requires it to be HTTP).
Does anyone know how to disable default deployment to HTTPS?
You can have your application check if the connection came in over HTTP or HTTPS and if it's the latter, you can redirect the user to HTTP. Normally, you'd do the opposite, but it should work this way too.
On Cloud Foundry, you can check if the connection is HTTP or HTTPS by examining the X-Forwarded-Proto header. That will tell you either http or https. Alternatively, you could look at X-Forwarded-Port which would tell you 80 or 443.
How you do this and how you issue the redirect depends entirely on the application, language and frameworks you're using. Some may handle this automatically, some may require manual configuration or code changes.
Hope that helps!

Azure IP throttle with web.config while using Cloudflare

I want to deny users access to my site if they have made X requests in Y milliseconds. According to Microsoft I can use dynamic ip security in the web config.
This is how my config, that I use for testing the ip throttle, looks:
<security>
<dynamicIpSecurity>
<denyByRequestRate enabled="true" maxRequests="2" requestIntervalInMilliseconds="10000"></denyByRequestRate>
</dynamicIpSecurity>
</security>
Now to my problem: Since I'm using Cloudflare I won't see the real IP of my visitors. According to Cloudflare, they provide the real IP in a couple of headers. Although, it does not seem that Azure looks at these headers when checking if the IP should be denied.
My question is: Is there some way I can still use the web config way of denying requests by IP or do I need to use a code solution instead?
I think that I found the answer to my own question. I'll post my findings here for people that might have the same problem.
According to this there is an attribute called "enableProxyMode" which
Enables IIS not only to block requests from a client IP that is seen
by IIS, but also to block requests from IP addresses that are received
in the x-forwarded-for HTTP header.
Since Cloudflare puts the real IP of the visitor in the X-Forwarded-For HTTP header it works perfectly.

Get real client IP in OpenShift?

I tried an application, and I used a way to ban those who send more than 5 empty requests to the server, but the problem then, is that everybody got blocked, and this is because everybody was seen as a ONE UNIQUE IP.
In the code, I used the way to get the X-Real-IP but it doesent work on OpenShift, so how to do that then?
Here is how I get the IP:
x_real_ip = self.request.headers.get("X-Real-IP")
remote_ip = self.request.remote_ip if not x_real_ip else x_real_ip
Update: I get '127.3.165.129', None) when doing print(self.request.remote_ip, x_real_ip)
You want to look for the "x-forwarded-for" header to get the visitors ip address. What you are seeing is the ip address of the reverse proxy that users go through before ending up at your application/gear.
You can refer to this article in the Developer Center for more information about how requests are routed on OpenShift: https://developers.openshift.com/en/managing-port-binding-routing.html

Nginx - Allow requests from IP range with no header set

I'm trying to use nginx behind a Compute Engine http load balancer. I would like to allow Health Check requests to come through a port unauthorized and all other requests to be authorized with basic auth.
The Health Check requests come from IP block: 130.211.0.0/22. If I see requests coming from this IP block with no X-forwarded-for header, then it is a health check from the load balancer.
I'm confused on how to set this up with nginx.
Have you tried using Nginx header modules? Googling around I found these:
HttpHeadersMoreModule
Headers
There's also a similar question here.
Alternative. In the past I worked with a software (RT), which had thought of this possibility in the software itself, providing a subdirectory for unauthorized access (/noauth/). Maybe your software might have the same, and you could configure GCE health check to point to something like /noauth/mycheck.html.
Please remember that headers can be easily forged, so an attacker who knows your vulnerability could access your server without auth.

Real life usage of the X-Forwarded-Host header?

I've found some interesting reading on the X-Forwarded-* headers, including the Reverse Proxy Request Headers section in the Apache documentation, as well as the Wikipedia article on X-Forwarded-For.
I understand that:
X-Forwarded-For gives the address of the client which connected to the proxy
X-Forwarded-Port gives the port the client connected to on the proxy (e.g. 80 or 443)
X-Forwarded-Proto gives the protocol the client used to connect to the proxy (http or https)
X-Forwarded-Host gives the content of the Host header the client sent to the proxy.
These all make sense.
However, I still can't figure out a real life use case of X-Forwarded-Host. I understand the need to repeat the connection on a different port or using a different scheme, but why would a proxy server ever change the Host header when repeating the request to the target server?
If you use a front-end service like Apigee as the front-end to your APIs, you will need something like X-FORWARDED-HOST to understand what hostname was used to connect to the API, because Apigee gets configured with whatever your backend DNS is, nginx and your app stack only see the Host header as your backend DNS name, not the hostname that was called in the first place.
This is the scenario I worked on today:
Users access certain application server using "https://neaturl.company.com" URL which is pointing to Reverse Proxy. Proxy then terminates SSL and redirects users' requests to the actual application server which has URL of "http://192.168.1.1:5555". The problem is - when application server needed to redirect user to other page on the same server using absolute path, it was using latter URL and users don't have access to this. Using X-Forwarded-Host (+ X-Forwarded-Proto and X-Forwarded-Port) allowed our proxy to tell application server which URL user used originally and thus server started to generate correct absolute path in its responses.
In this case there was no option to stop application server to generate absolute URLs nor configure it for "public url" manually.
I can tell you a real life issue, I had an issue using an IBM portal.
In my case the problem was that the IBM portal has a rest service which retrieves an url for a resource, something like:
{"url":"http://internal.host.name/path"}
What happened?
Simple, when you enter from intranet everything works fine because internalHostName exists but... when the user enter from internet then the proxy is not able to resolve the host name and the portal crashes.
The fix for the IBM portal was to read the X-FORWARDED-HOST header and then change the response to something like:
{"url":"http://internet.host.name/path"}
See that I put internet and not internal in the second response.
For the need for 'x-forwarded-host', I can think of a virtual hosting scenario where there are several internal hosts (internal network) and a reverse proxy sitting in between those hosts and the internet. If the requested host is part of the internal network, the requested host resolves to the reverse proxy IP and the web browser sends the request to the reverse proxy. This reverse proxy finds the appropriate internal host and forwards the request sent by the client to this host. In doing so, the reverse proxy changes the host field to match the internal host and sets the x-forward-host to the actual host requested by the client. More details on reverse proxy can be found in this wikipedia page http://en.wikipedia.org/wiki/Reverse_proxy.
Check this post for details on x-forwarded-for header and a simple demo python script that shows how a web-server can detect the use of a proxy server: x-forwarded-for explained
One example could be a proxy that blocks certain hosts and redirects them to an external block page. In fact, I’m almost certain my school filter does this…
(And the reason they might not just pass on the original Host as Host is because some servers [Nginx?] reject any traffic to the wrong Host.)
X-Forwarded-Host just saved my life. CDNs (or reverse proxy if you'd like to go down to "trees") determine which origin to use by Host header a user comes to them with. Thus, a CDN can't use the same Host header to contact the origin - otherwise, the CDN would go to itself in a loop rather than going to the origin. Thus, the CDN uses either IP address or some dummy FQDN as the Host header fetching content from the origin. Now, the origin may wish to know what was the Host header (aka website name) the content is asked for. In my case, one origin served 2 websites.
Another scenario, you license your app to a host URL then you want to load balance across n > 1 servers.

Resources