django: nginx: HTTP_HOST does not show port number - django

I have the following code running in production
The Nginx config is as follows:
# first we declare our upstream server, which is our Gunicorn application
upstream hello_server {
# docker will automatically resolve this to the correct address
# because we use the same name as the service: "djangoapp"
server webapp:8888;
}
# now we declare our main server
server {
listen 8558;
server_name localhost;
location / {
# everything is passed to Gunicorn
proxy_pass http://hello_server;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host;
proxy_redirect off;
}
}
Nginx server has port forwarding: 8555:8558
And the gunicorn command running is
gunicorn --bind :8888 basic_django.wsgi:application
Now in my browser i open this url:
http://127.0.0.1:8555/login_register_password/user_login_via_otp_form_email
Now my code in one of my views is
prev_url = request.META['HTTP_REFERER']
# EG: prev_url = http://127.0.0.1:8555/login_register_password/user_login_via_otp_form_email
# we want to get the url from namespace . We use reverse. But this give relative url not the full url with domain
login_form_email_url_reverse = reverse("login_register_password_namespace:user_login_via_otp_form_email")
# EG: login_form_email_url_reverse = "/login_register_password/user_login_via_otp_form_email"
# to get the full url we have to use do the below
login_form_email_url_reverse_full = request.build_absolute_uri(login_form_email_url_reverse)
# EG: login_form_email_url_reverse_full = "http://127.0.0.1/login_register_password/user_login_via_otp_form_email"
I am execpting prev_url and login_form_email_url_reverse_full to be same but it differs
prev_url domain is http://127.0.0.1:8555 whereas login_form_email_url_reverse_full domain is http://127.0.0.1
why this is happening.
This does not happen in development server. using runserver
"HTTP_HOST": "127.0.0.1:8555",
"HTTP_REFERER": "http://127.0.0.1:8555/login_register_password/user_login_via_otp_form_email",
Where as with nginx server: HTTP_HOST changes i.e now without port number
"HTTP_HOST": "127.0.0.1",
"HTTP_REFERER": "http://127.0.0.1:8555/login_register_password/user_login_via_otp_form_email",

I solved the problem by changing
proxy_set_header Host $host;
To
proxy_set_header Host $http_host;
in the server {} of local.conf of nginx
Got the answer from https://serverfault.com/a/916736/565479

Related

Setting up reverse proxy Nginx + Gunicorn/Django REST - 404 Not Found

I have a setup with Nginx as web server and Gunicorn as application server serving a Django REST API.
Nginx is listening at port 80 and gunicorn at port 8000 (I launch gunicorn using this command):
gunicorn --bind 0.0.0.0:8000 cdm_api.wsgi -t 200 --workers=3
and when I launch the petition to port 8000, I am able to access to the API running for instance:
curl -d "username=<user>&password=<pass>" -X POST http://127.0.0.1:8000/api/concept
However, when I try to make the petition though Nginx acting as reverse proxy, I get 404 Not Found Error:
curl -d "username=<user>&password=<pass>" -X POST http://127.0.0.1:80/api/concept
Here is my nginx conf file:
server {
listen 80;
listen [::]:80;
server_name 127.0.0.1;
location /api/ {
proxy_pass http://127.0.0.1:8000/api/;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Real-IP $remote_addr;
proxy_connect_timeout 360s;
proxy_read_timeout 360s;
}
location / {
root /usr/share/nginx/html;
index index.html index.htm;
}
}
Let me know if more information is needed. Thanks in advance!
So
gunicorn will create a sock file and you will have to map your proxy_pass with the sock file created, for now you are mapping to your localhost:8000 for this you will have to run the django runserver command so that nginx can find a server running on port 8000.
something like -
location / {
include proxy_params;
#proxy_pass http://unix:/home/abc/backend/social.sock;
proxy_pass http://unix:/home/abc/backend/backend.sock;
}
gunicorn make it possible to serve django at production, you don't have to command runserver everytime. Make sure gunicorn restarts everytime when server reboots.

How to to forbid access my site from ip address+port using nginx?

I have a django app with gunicorn running on port 2333.In nginx.conf I set
server {
listen 80;
server_name mydomain.com;
location / {
proxy_cache my_cache;
proxy_set_header REMOTE-HOST $remote_addr;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Host $http_host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http://127.0.0.1:2333;
expires 30d;
}
now I can view my django app on address http://ipaddress:2333 and mydomain.com
but I don't want users to view my site by http://ipaddress:2333 .How to allow nginx only use mydomain.com to access my site.
I have tried to use "server default".It not worked.
server {
listen 2333 default;
server_name _;
return 500;
}
Nginx has nothing to do with that. Your Gunicorn (Django) app is listening on port 2333. Therefore, you can bypass nginx by connecting to http://$SERVER:2333. It will work even if you stop nginx.
What you need to do is tell gunicorn to listen only on the localhost, e.g. with --bind=127.0.0.1:2333. Then port 2333 will be accepting connections only from the local network interface.

Rewriting URL in an nginx Docker container wrongly uses internal port

I have a Django application that runs in a Docker environment; one container for gunicorn and one for nginx. My application's nginx server listens on port 9081, which is internal to the system (it's not exposed to the outside world). Another nginx container (which routes traffic) sits on port 80 and sends traffic to my site as necessary (based on the hostname a request receives).
Here's my application's nginx setup, stripped down to the basics:
upstream project {
server gun_project:8001; # gunicorn container
}
server {
listen 9081;
server_name mytool.myhost.com;
set_real_ip_from 172.17.0.0/16;
real_ip_header X-Forwarded-For;
real_ip_recursive on;
location / {
proxy_pass http://project;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $remote_addr;
}
}
Here's the router nginx setup, again stripped down:
upstream project {
server ngx_project:9081; # nginx container
}
server {
listen 80;
server_name mytool.myhost.com;
return 302 https://$host$request_uri;
}
server {
listen 443 ssl;
server_name mytool.myhost.com;
# SSL Info
ssl_certificate /etc/nginx/ssl/mycert.cer;
ssl_certificate_key /etc/nginx/ssl/mycert.key;
location / {
proxy_pass http://project;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $remote_addr;
}
}
I want to redirect a URL on this site from one location to another (the URL has permanently changed). I'm doing so via a rewrite in the location block of my application's nginx configuration (the first nginx block above):
location / {
rewrite "^/oldpath/$" /newpath/ permanent;
proxy_pass http://project;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $remote_addr;
}
When I do this, and I attempt to load the old URL (mytool.myhost.com/oldpath/) in a web browser, I'm redirected to mytool.myhost.com:9081/newpath/ which fails because it doesn't exist (that port isn't exposed externally).
Is there something basic I'm missing? I don't want that internal port to be a part of the redirect.
Here's how I ended up doing it:
I added a dedicated location in the nginx configuration for the site, and performed the redirect there:
# Redirect the previous URL to the newer one
location = /old-path/ {
return 302 https://$host/new-path/;
}

Run simultaneously UWSGI and ASGI with Django

I'm currently running a Django (2.0.2) server with uWSGI having 10 workers
I'm trying to implement a real time chat and I took a look at Channel.
The documentation mentions that the server needs to be run with Daphne, and Daphne needs an asynchronous version of UWSGI named ASGI.
I manged to install and setup ASGI and then run the server with daphne but with only one worker (a limitation of ASGI as I understood) but the load it too high for the worker.
Is it possible to run the server with uWSGI with 10 workers to reply to HTTP/HTTPS requests and use ASGI/Daphne for WS/WSS (WebSocket) requests ?
Or maybe it's possible to run multiples instances of ASGI ?
It is possible to run WSGI alongside ASGI here is an example of a Nginx configuration:
server {
listen 80;
server_name {{ server_name }};
charset utf-8;
location /static {
alias {{ static_root }};
}
# this is the endpoint of the channels routing
location /ws/ {
proxy_pass http://localhost:8089; # daphne (ASGI) listening on port 8089
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
location / {
proxy_pass http://localhost:8088; # gunicorn (WSGI) listening on port 8088
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_connect_timeout 75s;
proxy_read_timeout 300s;
client_max_body_size 50m;
}
}
To use the /ws/ correctly, you will need to enter your URL like that:
ws://localhost/ws/your_path
Then nginx will be able to upgrade the connection.

Issue while configuring nginx in ec2 ubuntu server with Bitnami Configuration

I'm trying to cofigure nginx for reverse proxy in my ec2 server. My application starts with port 9000. So i added settings to nginx.conf file as below :
server {
listen 80;
location / {
proxy_pass http://localhost:9000;
}
}
After this i did 'service nginx start' and no response message, not even an error. I tried 'service nginx restart' and it is showing 'fail' message.
In my ec2 instance, i've port 80 listening to all requests.
Edit
I have bitnami configured on my instance, so it has apache as web server running. I don't want to disturb the current configuration. How could i do this with apache2 ?
For nginx, please try this bare-minimum configuration:
server {
listen 80;
location / {
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
# Fix the "It appears that your reverse proxy set up is broken" error.
proxy_pass http://127.0.0.1:9000;
proxy_read_timeout 90;
}
}
As my instance is pre-configured by bitnami, i used apache for reverse proxy. I added the following to the httpd.conf file and it worked like a charm.
<VirtualHost *:80>
Servername domainname.com
ProxyPass / http://localhost:9000/
ProxyPassReverse / http://localhost:9000/
</VirtualHost>
Thanks semm0 for the hints.