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

Add method to get client's claimed IP #904

Open
bdarnell opened this issue Sep 22, 2013 · 6 comments · May be fixed by #2975
Open

Add method to get client's claimed IP #904

bdarnell opened this issue Sep 22, 2013 · 6 comments · May be fixed by #2975

Comments

@bdarnell
Copy link
Member

The HTTPRequest.remote_ip field is intended to contain a trustworthy equivalent of the TCP-level remote address, so it accepts only a single X-Forwarded-For hop, and only when configured to do so. For some purposes (e.g. geolocation), it is useful to take whatever IP address the client claims to be using even through a chain of untrusted proxies. There should be some method to return the first public IP address from X-Forwarded-For.

moijes12 added a commit to moijes12/tornado that referenced this issue May 10, 2014
…equest

As per ticket description of ticket tornadoweb#904, a method to return the first
public IP address from X-Forwarded-For should be implemented. This
update contains the below changes:

1. In tornado/httpserver.py
HTTPRequest.get_claimed_ip() is implemented which simply returns
remote_ip

2. In tornado/test/httpserver_test.py
The test for verifying ip_headers already existed in XHeaders. I simply
modified the internal class Handler to retrieve the output of
get_claimed_ip from the request messge and write it to the dictionary.
The same tests that were written for verifying ip_headers have been
re-used except that they now check that remote ip equals claimed_ip
@PatTheMav
Copy link

I agree that remote_ip should return the "true" remote IP (which should be localhost in most proxied setups) and there should be a getter (e.g. the suggested get_claimed_ip() to get the actual client IP.

That said, there is another (maybe not so uncommon) example when using Cloudflare - these guys expose the client IP address via the CF-Connecting-IP header - there is a KB article explaining how to setup Nginx to use that header from trusted proxies only to determine the real_ip.

This allows Nginx to work and populate logs with actual client IPs and for logging/analytics purposes it would be great if I could tell Tornado which header to use for the "real ip" to appear in logs and for other purposes.

@ploxiln
Copy link
Contributor

ploxiln commented May 30, 2017

This issue description is a bit out of date. According to http://www.tornadoweb.org/en/stable/httpserver.html#http-server

By default, when parsing the X-Forwarded-For header, Tornado will select the last (i.e., the closest) address on the list of hosts as the remote host IP address. To select the next server in the chain, a list of trusted downstream hosts may be passed as the trusted_downstream argument. These hosts will be skipped when parsing the X-Forwarded-For header.

That's very similar to what nginx can do (you just can't customize the header to look at, it's just X-Forwarded-For or X-Real-IP).

@PatTheMav
Copy link

PatTheMav commented May 30, 2017

*sigh* yeah looks like I had a severe case of brain-lag - FWIW setting xheaders to true seems to be enough. Nginx doesn't add itself to the X-Forwarded-For header (dunno if that's due to the real_ip module) so not even the trusted_upstreams setting is needed.

Also: Cloudflare supports its own header as well as X-Forwarded-For..

@bdarnell
Copy link
Member Author

bdarnell commented Jun 3, 2017

The issue description is still valid. The xheaders and trusted_downstream options let you find the IP via which the request entered your network. The X-Forwarded-For header may contain additional untrusted information from external proxies; this issue proposes to expose the source address claimed by that untrusted proxy chain for use cases where a malicious client or proxy is not a concern. (For example, the untrusted source IP may be useful for geotargeting purposes, since honest proxies that use this field will get you closer to the user's true location, while the harm caused by a lying proxy is limited)

@answerquest
Copy link

I'm initiating my server using this: tornado.web.Application([..routes..], **settings) . But all the xheader examples are tornado.httpserver.HTTPServer(). How can I set xheaders=True in a tornado.web.Application() initiation?

@PatTheMav
Copy link

You can pass it e.g. using kwargs on the listen method:

        application = cls(options)
        application.listen(options.port, xheaders=True)

@betatim betatim linked a pull request Jan 11, 2021 that will close this issue
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants