Django won't get https header - django

Intro
I am building a web app using the latest Django version along with python3.7. The app is dockerized and I plan to deploy with docker-compose. Inside the container, I use nginx to proxy traffic to the application and not expose it directly. Also, I use apache in server level to proxy traffic to various other containers hosted on the same machine.
In the Django application, I use oauth2 to authenticate to Fitbit Web API and the issue I am facing is that the django-social-auth is passing the hostname automatically as a redirect_uri which now, after a lot of configuration with all those proxies, works perfectly in HTTP but when I use HTTPS although the app responds normally the redirect_uri is still http which obviously is not allowed by fitbit and very risky.
Although it is very hard for me to locate in which level the problem occurs I have tried various things but nothing seems to work out.
What I have tried
First
I tried to make my container listen to https request which seemed the most appropriate solution to me but ended getting 502 errors from the Apache.
I tried to find a solution on this by adding some configuration to the virtual host file like
#Solution 1
SSLProxyEngine on
SSLProxyVerify none
SSLProxyCheckPeerCN off
SSLProxyCheckPeerName off
SSLProxyCheckPeerExpire off
ProxyPass / https://localhost:83/ Keepalive=On #Solution 2 (keep alive)
ProxyPassReverse / https://localhost:83
But at last, I found out that it was not an apache issue but that the nginx inside the container was not responding although the traffic was routed to 443 port using HTTPS
Second
I tried to route traffic from the apache https to containerd nginx HTTP ( which does not make so much sense to me ) which makes the application respond normally but and results the redirect_uri error I mentioned above
As you can see I more or less confused and any kind of hint or help could be very useful
Update 1
The nginx configuration as requested in the comments
server {
listen 80;
listen 443 default_server ssl;
server_name localhost;
charset utf-8;
location /static {
alias /app/static/;
}
location /upload {
alias /app/media/;
}
location / {
proxy_pass http://web:8000;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}

I was able to fix the issue by adding the following configuration on the settings.py. I also added a control conditional in order to be able to run the container in development.
# Was already present before the issue resolved but is also needed
USE_X_FORWARDED_HOST = True
# The actual solution
if eval(os.environ.get('DEPLOY', default=False)):
SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https')
SECURE_SSL_REDIRECT = True
SESSION_COOKIE_SECURE = True
CSRF_COOKIE_SECURE = True

Related

403 Forbidden, Nginx config

I just started using Django and I try to deploy my project on the digital ocean server using Nginx. I am trying to set up SSL and domain (and they look good through the SSL checker and Google Dig DNS), however I get the 403 error in the browser once I try to access the webpage:
403 Forbidden
nginx/1.14.0 (Ubuntu)
I have been trying different things with Nginx config but it does not seem to help, here is what I have now:
http {
...
server {
listen 443;
ssl on;
ssl_certificate /etc/ssl/server_merged_key.crt;
ssl_certificate_key /etc/ssl/other_key.key;
root /var/www/html;
server_name domain.net www.domain.net ;
location / {
root /var/www/html;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto https;
proxy_set_header Host $http_host;
proxy_redirect off;
}
...
}
The Django project is located on the home of the server with no directory (just two folders /mysite1/mysite/). The server starts fine.
I do not see any GET request on the server side once I see the 403 error on the page. I do see the 400 error You're accessing the development server over HTTPS, but it only supports HTTP., if I try to access through http://IP-IN-NUMBER:8000.
Also, the settings.py looks like this, if this relevant to the issue:
DEBUG = False
ALLOWED_HOSTS = ['IP-IN-NUMBERS','localhost', '127.0.0.1','HTTP_X_FORWARDED_PROTO', 'https','domain.net'
,'www.domain.net']
SESSION_COOKIE_SECURE = True
CSRF_COOKIE_SECURE = True
SECURE_SSL_REDIRECT = True
How do I correctly set up Nginx for Django? Thank you so much for help!
Okay, so I figured it out with additional help, I will put answer in case it will be helpful for others. Basically I just needed to put my Django files in the root of /var/www/html, so they could be together with the index file. This way Nginx allows to access this directory and not throw 403 error.

Nginx static files 404 with django swagger rest api

I have Django rest API application and swagger for that is working fine locally. I am trying to configure it using containers and deploy it on ECS.
Now when I build and run the container the application works fine (I mean the swagger UI is appearing). When I attach the application load balancer to it, on the browser it is giving me 404 files not found for js and CSS files.
Here is the console output from the web browser.
Here is my Nginx config file
# nginx.default
add_header X-Content-Type-Options nosniff;
include /etc/nginx/mime.types;
add_header X-XSS-Protection "1; mode=block";
server {
listen 8020;
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
location / {
proxy_pass http://127.0.0.1:8010;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
location /static {
root /home/app/codebase;
}
}
THe path of static folder inside docker container is /home/app/codebase/static/
Also added the following lines in the Django Settings.py file.
STATIC_URL = '/static/'
STATIC_ROOT = os.path.join(BASE_DIR, 'static/')
Not sure what am I missing. Any leads will be appreciated.
I have looked into these questions. The problem is something similar but not sure what I'm missing.
Posting the solution in case anyone still facing the same kind of issue.
I provisioned all the resources using IaC (Cloud Formation) so while provisioning Load Balancer I created the one target group but at that time the ECS services were not created, so I created a dummy target group that drops the traffic and was not routing the traffic to any service.
And in ALB's path-based routing, the last route (which the traffic uses when the request does not find any route) was directing traffic to a dummy target group.
As soon as I changed the target group everything works like a charm.
Working Fine
Pro Tip:
Always use any of the target groups from your application in the last ALB rule.

nginx connection refused after config

I was setting up nginx on my aws ubuntu instance. At first every time went well, but after I config nginx and try to connect django, I can't even see the welcome page from either public ip nor the localhost(which was able to access from both sides). The nginx status command shows nginx is running.
Here's my nginx config:
/nginx/sites-available/mysite.com
server{
charset utf-8;
listen 80;
server_name my_aws_ip;
location /static{
alias my_django_static_path;
}
location / {
proxy_set_header Host $host;
proxy_pass http://unix:tmp/mysite.socket;
}
}
And I made a link to /nginx/sites-enabled/
It appears that every time I restarted nginx, I will be able to see the welcome page. However, after that, nginx refuses connections.
I didn't change anything in nginx.conf. Do I need to?
server_name should be your domain name, IP address should be specified as part of the listen directive
proxy_pass http://unix:tmp/mysite.socket;
Not sure where you are hoping this will end up, but you need to decide if you are sending it via http or to a socket. Not both. Having said that if it's for django then it's not proxy_pass you want at all
I'm guessing you mean:
uwsgi_pass unix:/tmp/mysite.socket;
You'll also need to include these somewhere in your config

Nginx redirection magic

I have a third-party that's forwarding traffic over to me on a subdomain - let's call it subdomain.thirdparty.com
I would like to forward this traffic over to www.mysite.com/subdomain - this is where the app lives. The links in the app require the /subdomain part in the URL.
BUT I would like to maintain the third-party URL in the browser, something like subdomain.thirdparty.com or subdomain.thirdparty.com/subdomain
I'm hosted on AWS so I have Route 53 available to me, and have the following Nginx setup:
server{
server_name *.mysite.com;
listen 80;
location /subdomain/{
proxy_set_header SCRIPT_NAME /subdomain;
proxy_set_header Host $host;
proxy_pass http://127.0.0.1:9014;
}
}
I've tinkered around with Nginx settings but just can't seem to figure it out. Any guidance would be greatly appreciated.

How to proxy proxy domain name to internal app server URL in Nginx?

I have an internal app server (Django+gunicorn) running behind an Nginx reverse proxy on a private port (listening on port 5000, for example.)
There are several Django apps installed in the app server, mapped to separate base paths. Example:
/app1
/app2
Where /app1 serves up content for domain1.com and /app2 serves content for domain2.com.
I'd like to silently reverse proxy incoming requests for specific hostnames to the related backend app, while preserving the path forwarded to the internal app server:
http://domain1.com/foo --> /app1/foo
http://domain1.com/bar/bletch --> /app1/bar/bletch
http://domain2.com/alpha/bravo --> /app2/alpha/bravo
I suppose you could say I'm trying to set up a simple 'virtual hosting' configuration but I want to use a shared back-end app server instance.
Key point: I don't want the visitor's browser to see the redirected URL structure. So when the client browser hits http://domain1.com/foo, the correct content is served up but the browser doesn't see a redirect.
I've done some basic work with Nginx (still learning) and I'm looking for example Nginx configurations demonstrating secure and efficient ways to accomplish this goal.
Based on this answer here's a configuration that seems to work as desired.
For app1 running on http://localhost:8000/app1_path :
upstream app1 {
server 127.0.0.1:8000 fail_timeout=0;
}
server {
listen 80;
server_name example.com
access_log /var/log/nginx/example.com.access.log;
error_log /var/log/nginx/example.com.error.log;
location / {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
rewrite ^(.*)$ /app1_path$1 break;
proxy_pass http://app1;
}
}
So, one could repeat this pattern as many times as desired for each hostname->app/path pair.