#33293 closed Uncategorized (invalid)
Wrong redirect behind reverse proxy
Reported by: | Rodolphe | Owned by: | nobody |
---|---|---|---|
Component: | contrib.admin | Version: | 3.0 |
Severity: | Normal | Keywords: | |
Cc: | Triage Stage: | Unreviewed | |
Has patch: | no | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description
I am running a small django app with django admin.
In fact, I only use django admin to edit a few models.
It works fine in local and behind a simple reverse proxy (without path change), but now I have this rewrite rule that changes the path: (it's a nginx ingress rewrite rule for Kubernetes)
path: /diagnosis-admin(/|$)(.*) => $2
Wich means, urls such as mydomain.com/diagnosis-admin redirect to localhost/ (mind the path change).
When I try to access the admin at mydomain.com/diagnosis-admin/admin, django tries to redirect to mydomain.com/admin/, which leads nowhere because it falls on the proxy:
Request URL: https://mydomain.com/diagnosis-admin/admin Request Method: GET Status Code: 301 Remote Address: 138.21.17.33:3128 Referrer Policy: strict-origin-when-cross-origin Response Headers content-length: 0 content-type: text/html; charset=utf-8 date: Tue, 19 Oct 2021 15:11:42 GMT location: /admin/ script_name: /diagnosis-admin strict-transport-security: max-age=15724800; includeSubDomains x-content-type-options: nosniff
as you can see, django sends a "location: /admin/" redirect in the response which causes the error
I had this problem with other applicative frameworks but could solve it since they can interpret the FORWARDED_HOST, FORWARDED_PORT and FORWARDED_PATH headers provided by the proxy.
Additionnal information:
I run django with "python manage.py runserver 0.0.0.0:8000" on a docker container (running through GKE)
Everything is pretty standard, I ran the basic django project scafolding, setup the database, auto migrated the models and that's about it. I can provide additionnal files if needed
Additionnal information:
requirements.txt
requirements.txt: asgiref==3.2.6 Django==3.0.4 psycopg2==2.8.4 pytz==2019.3 sqlparse==0.3.1
Dockerfile:
FROM python:3.6.10-alpine COPY requirements.txt ./ RUN apk add --no-cache --virtual .build-deps \ ca-certificates gcc postgresql-dev linux-headers musl-dev \ libffi-dev jpeg-dev zlib-dev \ && pip install -r requirements.txt ENV PYTHONUNBUFFERED 1 RUN pip install -r requirements.txt COPY . . EXPOSE 8000 ENTRYPOINT ["python", "manage.py"] CMD ["runserver", "0.0.0.0:8000"]
Change History (4)
follow-up: 2 comment:1 by , 3 years ago
Resolution: | → invalid |
---|---|
Status: | new → closed |
follow-up: 3 comment:2 by , 3 years ago
Replying to Mariusz Felisiak:
Thanks for this report, however it looks like a support question 🤔 and Trac is not a support channel. Have you tried to use USE_X_FORWARDED_HOST settings?
Please see TicketClosingReasons/UseSupportChannels for ways to get help with Django usage.
USE_X_FORWARDED_HOST doesn't work because it doesn't track the path change. It tried support channels but they fail me. As I see it, this is either a bug (django shouldn't do an absolute redirect), or a missing feature (django should support a way to work behind reverse proxy with path changes.)
comment:3 by , 3 years ago
USE_X_FORWARDED_HOST doesn't work because it doesn't track the path change. It tried support channels but they fail me. As I see it, this is either a bug (django shouldn't do an absolute redirect), or a missing feature (django should support a way to work behind reverse proxy with path changes.)
You should be able to add a custom middleware with expected logic.
It tried support channels but they fail me.
Please remember that folks on the support channels are volunteers who help others in their spare time, you cannot expect an immediate help.
comment:4 by , 3 years ago
Whilst this isn't a support channel, I'll add some possibly helpful information below as a courtesy, and because who knows who else might stumble across this in the future.
If your httpd (or whatever; could be a wsgi middleware etc) sets SCRIPT_NAME
and PATH_INFO
to the correct values, and (maybe; it's been a while) the setting FORCE_SCRIPT_NAME to the prefix, anything that goes through reverse
/resolve
in terms of generated URLs (for Location
redirects etc) should end up with the correct values.
e.g. return HttpResponseRedirect(reverse('admin:index', ...))
would be prefixed, but return HttpResponseRedirect('/admin/')
would not.
For transparent reverse-proxying of all URLs AFAIK you'd need further co-operation from either the WSGI publisher (e.g. See the waitress docs for their support) or the fronting httpd (e.g. see Apache's ProxyPassReverse)
Please note also this gentle reminder that you should not be using runserver in anything ostensibly like "production" - you should be using something designed for the purposes, such as gunicorn/uwsgi/mod_wsgi/waitress/bjoern/meinheld.
Thanks for this report, however it looks like a support question 🤔 and Trac is not a support channel. Have you tried to use USE_X_FORWARDED_HOST settings?
Please see TicketClosingReasons/UseSupportChannels for ways to get help with Django usage.