I have come to know that x forwarded for gives the ip address o the client who actually sent the request(getremoteaddress() returns the ip address of the machine that sent the reques to the server which can be a proxy). Anyway my question is where is the x forwarded for included in the request. How to extract the client address from it?
I would recommend reading the fine Wikipedia article first:
http://en.wikipedia.org/wiki/X-Forwarded-For
The method for extracting the information from the headers will depend on your platform (which you haven't provided in your question).
Please be aware that X-Forwarded-For headers can be spoofed, and that the machine sending the request may simply pretend to be a proxy and put a fake IP address into the X-Forwarded-For header.
You should only trust X-Forwarded-For headers from your own proxies, not remote ones.
Related
I was assign a task by my direct manager to make sure that all the websites in the company will have "X-Forwarded-For" HTTP Header set, in order to receive the original IP of the users for our Web Application Firewall logs.
I am not a developers, but I need to make sure our developers do that, and they seem to not understand what needs to be in the value of the header.
Because looking at some examples, it seemed that some people put specific IP like this:
X-Forwarded-For: <client>, <proxy1>, <proxy2>
which doesn't make any sense to me, because how can u type the IP in the value when it is completely random for each one?
Basically, I need that our logs will contain the real IP from each computer which surf behind a proxy or a load balancer.
Would like for some help : )
Thanks!
If you have one reverse proxy (or load balancer) between the client and the application server, then the proxy should add the header:
X-Forwarded-For: <client>
before forwarding the request on to the application server. The application server receives the request from the proxy IP but can deduce the client's IP from the value of the header.
If you have two reverse proxies (or load balancers) between the client and the application server, the first proxy (the one nearest the client) acts the same as above.
The second proxy receives the request from proxy1's IP and also receives the X-Forwarded-For header from proxy1. It then appends the IP address from where the request was receives (proxy1) and passes the updated header to the application server as:
X-Forwarded-For: <client>, <proxy1>
Each proxy or load balancer is responsible for creating the header if it does not already exist, and appending the IP address of the from where the request was received (i.e. the previous step in the chain).
Only the first IP address is necessary to identify the client, the remaining IP addresses are necessary to ensure that the header has not been faked.
We are using mulesoft proxy api as proxy for another api. We need to know the X-Forwarded-For of the originating requestor.
If you are creating the proxy with API Manager you could add a Header Injection policy to it to add the header. You could use as the value the expression #[attributes.remoteAddress] so it takes the IP of the client of the IP.
If the proxy is deployed to CloudHub it might be receiving the IP of CloudHub load balancer and the load balancer may be already adding the X-Forwarded-For header.
I have a few questions about cloudflare service before I use it.
Are there any difference on http request header between a web server use cf-connecting-ip,x-forwarded-for etc and a web don't use these kinds of thing?
Can/How client knows that a web server uses cf-connecting-ip, x-forwarded-for etc?
These request headers are specific to webproxies, and appended after the request was received by Cloudflare, when it's relaying to your origin. The user cannot see it, unless your webserver for some reason sends it back.
x-forwarded-for: https://en.wikipedia.org/wiki/X-Forwarded-For
Used by proxy servers to tell the origin any HTTP servers involved in relaying the request between the user and the origin. you may see 1 or multiple sets of IP addresses in this header.
cf-connecting-ip:
Relays the IP of the user connecting to Cloudflare to the origin webserver
From: https://support.cloudflare.com/hc/en-us/articles/200170986-How-does-Cloudflare-handle-HTTP-Request-headers-
CF-Connecting-IP Provides the client (visitor) IP address (connecting
to Cloudflare) to the origin web server. cf-connecting-ip contains a
special Cloudflare IP 2a06:98c0:3600:0:0:0:0:103 when the request
originates from a Cloudflare Workers subrequest instead of the
visitor's true IP.
Example:
CF-Connecting-IP: 203.0.113.1
X-Forwarded-For Maintains proxy server and original visitor IP
addresses. If there was no existing X-Forwarded-For header in the
request sent to Cloudflare, X-Forwarded-For has an identical value to
the CF-Connecting-IP header:
Example:
X-Forwarded-For: 203.0.113.1 If an X-Forwarded-For header was already
present in the request to Cloudflare, Cloudflare appends the IP
address of the HTTP proxy to the header:
Example:
X-Forwarded-For: 203.0.113.1,198.51.100.101,198.51.100.102 In the
examples above, 203.0.113.1 is the original visitor IP address and
198.51.100.101 and 198.51.100.102 are proxy server IP addresses provided to Cloudflare via the X-Forwarded-For header.
So for advice, review your application and see if it depends on the IP of the user, if so you will need to modify your web-server configuration to relay the correct IP.
To restore original visitor IP addresses at your origin web server,
Cloudflare recommends your logs or applications look at
CF-Connecting-IP or True-Client-IP instead of X-Forwarded-For since
CF-Connecting-IP and True-Client-IP have a consistent format
containing only one IP.
I've been experimenting with Apache mod_proxy and mod_remoteip in order to confirm my understanding of the handling of X-Forwarded-For headers, particularly around how internal IP Addresses (e.g. 10.x.x.x or 192.168.x.x ranges) are being handled.
It seems like mod_proxy doesn't always add the internal IP addresses to the X-Forwarded-For header, but I've been unable to find any documentation explaining the expected behavior for this.
As far as I can tell, when the request initiates from an internal IP address, then mod_proxy will add internal IP addresses to the X-Forwarded-For header, but when the initial request comes from a public IP, mod_proxy does not seem to add any internal IP addresses to the X-Forwarded-For.
The Question
My question is: What are the rules that govern whether or not mod_proxy will append the calling IP address to the X-Forwarded-For header.
The documentation on mod_proxy says:
When acting in a reverse-proxy mode (using the ProxyPass directive, for example), mod_proxy_http adds several request headers in order to pass information to the origin server. These headers are:
X-Forwarded-For -
The IP address of the client.
X-Forwarded-Host -
The original host requested by the client in the Host HTTP request header.
X-Forwarded-Server -
The hostname of the proxy server.
Be careful when using these headers on the origin server, since they will contain more than one (comma-separated) value if the original request already contained one of these headers. For example, you can use %{X-Forwarded-For}i in the log format string of the origin server to log the original clients IP address, but you may get more than one address if the request passes through several proxies.
I read this as saying that the client IP address will always be appended to the X-Forwarded-For header, but that's not the behavior I'm observing.
The rest of this question is the tests I've conducted and the behavior I've observed.
The Setup
I've setup two servers both running Apache with mod_proxy installed. I'll refer to these as One and Two.
One has the (internal) IP address 10.0.7.1
Two has the (internal) IP address 10.0.7.2
One has the following ProxyPass directive so that requests to sub-paths of /proxyToTwo are sent to the equivalent sub-path under /proxyToOne on Two
<Location "/proxyToTwo">
ProxyPass http://10.0.7.2/proxyToOne
</Location>
Two has the following ProxyPass directive so that requests to sub-paths of /proxyToOne are sent back to One but without the /proxyToOne prefix
<Location "/proxyToOne">
ProxyPass http://10.0.7.1
</Location>
The effect of this is that when I issue requests to http://One/proxyToTwo/foo it's proxied as follows
One receives the request, issues the following request to Two http://10.0.7.2/proxyToOne/foo
Two receives the request, issues the following request back to One http://10.0.7.1/foo
One receives a request for /foo and actually serves the resource
So every request is bounced from one to two and back to one before being responded two.
Calling with an Internal IP
Using the above setup, I call One from Two using it's internal IP address:
curl http://10.0.7.1/proxyToTwo/foo
The X-Forwarded-For and X-Forwarded-Host headers received when One eventually gets the request for the /foo resource is what I expect below:
X-Forwarded-For: 10.0.7.2, 10.0.7.1
X-Forwarded-Host: 10.0.7.1, 10.0.7.2
This is what I expect, that the request was proxied first through One then Two, and the requesting IP addresses are first the initial request from Two (curl) then the request from One (mod_proxy) and the final request (not in the header because it's the client IP of the connection being from Two (mod_proxy)
Calling with external IP
The unexpected behavior is that mod_proxy seems to behave differently when called from public IP. So Instead of calling One from Two, I call One from my local machine using the public address
curl http://35.162.28.102/proxyToTwo/foo
The X-Forwarded-Host is still what I expect:
X-Forwarded-Host: 35.162.28.102, 10.0.7.2
That is, the request was first proxied through One (using it's external address) then through Two.
But the X-Forwarded-For header is showing only my (external) IP address:
X-Forwarded-For: 35.163.25.76
This suggests to me that the initial execution of mod_proxy is adding the X-Forwarded-For header with the client IP address. But then the subsequent proxying by Two doesn't append the address of One.
I think this behavior is probably more useful than blindly appending the internal IP addresses to the header, but I can't find it documented anywhere so would like to ensure I fully understand it.
Answering this so it's available in-case others make a similar mistake.
In short: mod_proxy always appends the client IP to the X-Forwarded-For header (or adds an X-Forwarded-For header if there is no existing header).
But, other Apache modules can manipulate the X-Forwarded-For header prior to mod_proxy processing it. Mod_proxy will append the client IP to what it sees as the X-Forwarded-For header, which can be the output of other Apache modules.
In my tests, the other module affecting the result was mod_remoteip. The reason for the difference in resulting behavior was that I was using the RemoteIpTrustedProxy directive to specify my trusted proxies and this will allow trusting of private IPs as the first connection but will not process private IPs in the X-Forwarded-For header.
As a result for the External IP case there was the following handling:
My Machine (35.163.25.76) connects to One with no X-Forwarded-For
One sends this request to Two with my IP in X-Forwarded-For header (X-Forwarded-For: 35.163.25.76)
Two receives this request, mod_remoteip processes the X-Forwarded-For header, because One is trusted, the client IP effectively is 35.163.25.76 and there is effectively no X-Forward-For header passed on to mod_proxy
Two sends this request to One with my IP in X-Forwarded-For header (X-Forwarded-For: 35.163.25.76)
This is what presents as "not appending the private IP" but is actually processing the X-Forward-For header and producing an identical one.
The Private ID case behaves differently because mod_remoteip isn't accepting the private IP address in the X-Forward for. So it's handled by:
Two (10.0.7.2) connects to One with no X-Forwarded-For
One sends this request to Two with Two's IP in X-Forwarded-For header (X-Forwarded-For: 10.0.7.2)
Two receives this request, mod_remoteip processes the X-Forwarded-For header but does not trust the value so leaves it as is. So the client IP remains One's IP (10.0.7.1) and the X-Forward-For header passed on to mod_proxy is unmodified
Two sends this request to One appending the client IP (One's) to X-Forwarded-For header resulting in X-Forwarded-For: 10.0.7.2, 10.0.7.1
I verified this by actually sending in some X-Forwarded-For headers from trusted hosts. E.g.
curl http://10.0.7.1/proxyToTwo/foo --header "X-Forwarded-For: TrustedHost1, TrustedHost2"
This results in the final X-Forward-For header containing only TrustedHost1 indicating that the header really is being processed by mod_remoteip and re-issued by mod_proxy.
There's probably an answer already on stackoverflow that I'm missing, sorry in advance for that, I just can't find it.
I have a small TCP server running on my localhost that, for security reasons, will not support CORS.
My question is, if CORS is for cross-domain protection, why is it being requested when I have a page on http://localhost/ request a connection to http://localhost:xxxx
I know I can turn off the security in my browser, but Im trying to understand why localhost to localhost connections are being treated as cross-origin.
XMLHttpRequest cannot load http://localhost:8000/. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:63342' is therefore not allowed access. The response had HTTP status code 500.
Because localhost (port 80) is a different host than localhost:8000.
See RFC 6454, Section 5:
If the two origins are scheme/host/port triples, the two origins
are the same if, and only if, they have identical schemes, hosts,
and ports.
Same-origin Policy
The same-origin policy permits scripts running in a browser to only make requests to pages on the same domain. This means that requests must have the same URI scheme, hostname, and port number. This post on the Mozilla Developer Network clearly defines the definition of an origin and when requests result in failure. If you send a request from http://www.example.com/, the following types of requests result in failure.
https://www.example.com/ – Different protocol (or URI scheme).
http://www.example.com:8080/myUrl – Different port (since HTTP requests run on port 80 by default).
http://www.myotherexample.com/ – Different domain.
http://example.com/ – Treated as a different domain as it requires the exact match (Notice there is no www.).
For more information refer to this link