-
Notifications
You must be signed in to change notification settings - Fork 1.7k
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
gunicorn 19.0: empty remote addr on unix domain socket? #797
Comments
@jeroenp ping :) |
If not use X-Fowarded-For to check client real IP, how to log client real IP? I think the description of the %(h)s is a little ambiguous. my access_log_format: '''%(h)s %(l)s %(u)s %(t)s "%(r)s" %(s)s %(b)s "%(f)s" "%(a)s" "%({x-forwarded-for}i)s"''' example output: |
Sounds fine
|
Then on logs, We may have two IPs. |
I took that to mean that we'd add a log substitution variable, and people
|
May be %({x-forwarded-for}i)s -> %(x)s ? |
h is already used for the REMOTE_ADDR which now follows the rfc. Anyway I am not sure we need to add anything. You can already log any header in the request if you want. If you add |
I'm inclined to think that clearing the REMOTE_ADDR field is frivolous and breaks a lot of applications. I don't see any specification for non-TCP connections. My interpretation is that for unix domain sockets you'd still want to pretend that it has a complete set of CGI headers: Everyone trusts that there is a REMOTE_ADDR. An application can only guess that any other unspecified field (XFF, a list no less, or X-REAL-IP) is set. Django uses REMOTE_ADDR for testing for "Internal IPs" (https://docs.djangoproject.com/en/dev/ref/settings/#internal-ips). Most of my applications trust that the REMOTE_ADDR header is set in some way; Leaving the field empty effectively blocks 19.0 usage for me: I have to chose between auditing/editing various pieces of code (maybe not my own) to use XFF or switch from unix domain sockets to TCP/IP. |
frivolous? No not really. It just happen that django is built from the start to handle tcp connections only. Anyway the original problem described in #633 is that the proxy address was not found due to the way we set the remote address handling the FORWARDED headers. Also that we didn't respect the spec. And to be honest it would be easier if django would comply with the spec and use the HTTP headers to offer the feature you link. (Maybe opening a ticket there?) Now, in fact without this change, the application can still discover the remote_address by using the http headers. we could let the forward header pass the raw remote host differently and revert the change in #633. Any feedback is welcome. |
Perhaps wise to start moving away from X-Forwarded-For nomenclature in down stream usages as there is now an RFC for a proper replacement. |
From the looks of the Django source it would be feasible to have a middleware that patched REMOTE_ADDR for you in this situation. No editing of 3rd party code required. Sticking to the WSGI spec seems fine to me. |
@GrahamDumpleton You mean introduces a |
cc @davisp @tilgovi @sirkonst @kennethreitz @matrixise @berkerpeksag @fafhrd91 @asvetlov any feedback is welcome ;) |
I have no ideas on this question :/ sorry, Doesn't really help us, sorry if we are using unix socket, as explained in #633 we remove REMOTE_PORT, we have to make the same thing with REMOTE_ADDR. |
Django include I don't think we should be doing anything differently. If you're deploying with a UNIX socket you should be using this middleware because you have a trusted proxy and it should be setting the X-Forwarded-For header (or something else of your choosing). It's a common enough need that we could consider a flag in gunicorn as an enhancement proposal, but it's also something handled by most frameworks. Django has the middleware, above. Pyramid has |
@tilgovi i am also thinking the current behaviour is the good one. If everyone is OK I will close this ticket and release the 19.1. |
I think we need to keep REMOTE_ADDR to "" and Django has to use a middleware for this behaviour. |
@tilgovi Just an FYI, as best as I can tell |
It seems to to me it's the role of the wsgi server, not the application, to account for the situation of being behind a reverse proxy. The application should just be able to use REMOTE_ADDR directly, regardless of how exactly it's being deployed, and not need to implement logic to handle this case. The 2004 cgi spec says it identifies "the client for the immediate request to the server". Could we interpret server to mean "machine" (or even website) instead of actual "socket"? |
We need to take a decision on this. To summarise the context, the remote address is right now empty by default when using the unix socket. For the good reason that no tcp address is given, Now most of the time, the application want to fetch the remote address of the client. With the new behaviour it's only possible by parsing the
Hopefully we can solve that issue this week. Let me know. |
(coming here via the web-sig discussion). Seems like there are two related issues. For logs that gunicorn itself writes, some mechanism to select the 'real' client address would be useful for server admins. For apps they may need some way to determine the 'real' address too - and if gunicorn has determined that passing it on may be useful. I'm not sure it makes sense to require that all servers have a way to determine the 'real' client address though, so it seems like either a gunicorn extension or we'd have to make it optional.. and optional features are often problematic in terms of interop. |
Still not sure what to do about this one. What are the current proposals? Maybe we can chat soon in real time on IRC
|
See also discussion at: Without a reliable way of dealing with X-Fowarded and Forwarded headers which can be configured to say what front end clients you trust to pass the information and so be able to set REMOTE_ADDR properly, you are pretty much screwed. |
After reading the discussion at python-web-sig/wsgi-ng#11 I think my feeling is that the current behavior is not incorrect or bad. There is clear prior art for frameworks and middleware tolerating a On the other hand, we have a |
My reasoning is that if a user knows enough to set the |
I will do the change proposal from @tilgovi asap. |
It appeared that we also removed the code handling the X-Forwarded-Header so I am postponing to the next release. Also see my comment in python-web-sig/wsgi-ng#11 . |
Hi,
I've just upgraded gunicorn 18.0 to 19.0. Now REMOTE_ADDR is an empty string, where before it listed the remote ip ("real ip").
Is that an intentional change?
My setup snippets:
gunicorn:
reverse proxy, nginx (1.4.1):
My Django says that request.META['REMOTE_ADDR'] == ""
The text was updated successfully, but these errors were encountered: