django allowed_hosts error for www domain and ip address - python

django 1.6
I've got my webserver to redirect www requests to the non-www equivalent. i.e. www.domain.com goes to domain.com
i've got django setup to email me any errors
i'm getting a bunch of errors that look like:
[Django] ERROR: Invalid HTTP_HOST header: 'www.domain.com'.You may
need to add u'www.domain.com' to ALLOWED_HOSTS
or
[Django] ERROR:
Invalid HTTP_HOST header: '< ip address >'.You may need to add u'< ip
address >' to ALLOWED_HOSTS
but the content of the emails is simply:
No stack trace available
Request repr() unavailable.
I know the redirect is working because if i attempt to visit www.domain.com i get redirected to domain.com
I'd like to better inspect the request object to understand how the requests are getting to django. the only requests that should be getting forwarded to django should be the ones going to domain.com.
Does anyone know how i might go about this?
or even better if someone knows what is going on here that would be great.
As requested here is the nginx conf:
server {
listen <ip address>:80;
server_name "";
return 444;
}
server{
listen <ip address>:80;
server_name www.domain.com;
return 301 $scheme://domain.com$request_uri;
}
#HTTPS server
server{
listen <ip address>:80;
listen <ip address>:443 ssl;
server_name domain.com;
location / {
uwsgi_pass unix:<path to socket file>;
include /etc/nginx/uwsgi_params;
}
if ($ssl_protocol = ""){
return 301 https://$host$request_uri;
}
}

The ALLOWED_HOSTS setting in django inspects the Host header in your HTTP request, which is generated by the browser when it sends the request.
In your Nginx config you are (presumably) using a URL rewrite not an HTTP redirect.
If that is the case, then the redirect is essentially internal to the server. The original Hosts header in the request sent by your browser will still have its original value.
The correct config for Nginx would be something like:
server {
listen 80;
server_name www.domain.com;
return 301 http://domain.com$request_uri;
}
server {
listen 80;
server_name domain.com;
...django server config...
}
This will cause an HTTP 301 redirect to be returned to your browser, and the browser will send a new request with the correct Host header.

Related

unable to access .env files while running with uwsgi

I'm using smtplib to send simple emails for booking in a flask application I'm using google mail and have an app password as well as allowed less secure applications. I have the booking system running on my personal computer, but as soon as I port it over to the VPS it stops working, for an unknown reason other than the username and password are not accepted, but they are definitely correct, and it will run by itself but wont when run in wsgi and nginx.
Nginx config
server {
listen 80;
server_name example.com;
# return 301 https://$server_name$request_uri;
location / {
uwsgi_pass unix:/path/too/chatbot.sock;
include uwsgi_params;
}
}
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name example.com;`
ssl_certificate /path/too/keys.pem;
ssl_certificate_key /path/too//primarykey.pem;
ssl_trusted_certificate /path/too//keys.pem;
ssl_session_timeout 1d;
ssl_session_cache shared:MozSSL:10m; # about 40000 sessions
# curl https://ssl-config.mozilla.org/ffdhe2048.txt > /path/to/dhparam
#ssl_dhparam /path/to/dhparam;
# intermediate configuration
ssl_protocols TLSv1.2;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384;
ssl_prefer_server_ciphers on;
# HSTS (ngx_http_headers_module is required) (63072000 seconds)
add_header Strict-Transport-Security "max-age=63072000" always;
# replace with the IP address of your resolver
resolver 8.8.8.8;
location / {
include uwsgi_params;
uwsgi_pass unix:/path/too/chatbot.sock;
}
}
UWSGI.ini file
[uwsgi]
module=wsgi:app
master = true
processes = 5
enable-threads = true
socket = chatbot.sock
chmod.socket = 666
vacuum = true
die-on-term = true
.env
DIALOGFLOW_PROJECT_ID=projectid
GOOGLE_APPLICATION_CREDENTIALS=Ajsonfile.json
RESTFUL_CREDENTIALS=restful_credentials.json
MAIL_USERNAME=example#gmail.com
MAIL_PASSWORD=apasswordforemailaddress
My current thinking is that wsgi or nginx are unable too find the file due to some sort of permissions issue but I've chown'ed all the related files, I'm getting the same issue with my google api key now too.
all the information is stored in a .env file which has the correct group access, along with all the other files running on the site already.
I don't know what would be helpful to post here other than I'm using nginx and wsgi to expose a flask application, some items are stored in a .env file that doesn't seem to be read.
To get them to load while running in WSGI you need to use dot-env package
from dotenv import load_dotenv, find_dotenv
load_dotenv(find_dotenv())
[uwsgi]
base = /var/www/html/poopbuddy-api
chdir = %(base)
app = app
I don't know exactly what chdir does but I think it at least sets the default location to the root directory of the app. From there, load_dotenv() works.

nginx configuration: IP address showing instead of domain name

I put my website on a DigitalOcean Droplet and it worked. I called the IP address and it showed me the address, then I forwarded the domain to the website IP and it connected it.
The issue at the beginning was that when I was accessing the website with my domain the access bar was showing my domain and when the page loaded it showed the IP address instead of the domain.
it seemed that the issue was in my nginx configuration, as I wrote just my IP address there.
```
server {
listen 80;
server_name 178.128.42.100;
location = /favicon.ico { access_log off; log_not_found off; }
location /static/ {
root /home/patrik_website/patrik_web/form/;
}
location / {
include proxy_params;
proxy_pass http://unix:/run/gunicorn.sock;
}
}
```
I updated the file changing the server_name variable to:
server_name patrikmuniak.com www.patrikmuniak.com;
the lists in settings.py-ALLOWED_HOSTS=['*']
and after the update to the nginx website configuration, this it's been restarted with:
sudo systemctl restart nginx
the output is that when I use any browser and type the IP or the domain, now it shows me the page with 'Welcome to nginx!'.
The DNS records are:
and for forwarding I used the masking option.
if you need more info please let me know.
P.S. the OS is Ubuntu 19.04
You should add your domain name to server name section:
server {
listen 178.128.42.100:80;
server_name domain_name.com www.domain_name.com;
And correct your dns records. You have to point # to your ip: 178.128.42.100.

Flask redirect appends get%20/%20HTTP/1.1)uri on production server. Working fine locally

I am trying to redirect all get requests to abc.example.com and send them to example.com. The following works on local:
#app.route('/', methods=['GET'])
def message_get():
return redirect('https://example.com')
But on production server, it fails. Instead of getting redirected, the url looks like this:
abc.example.comget%20/%20HTTP/1.1)uri
I observed that if I put in the whole url like this
https://abc.example.com
it redirects properly. but abc.example.com or http://abc.example.com fails.
I have a flask app with gunicorn app server. Nginx is used as reverse proxy. Unable to determine which of them is causing the problem. Guessing something to do with my nginx configuration. But any pointers will help. thanks.
Nginx configuration:
server {
listen 80 default_server;
listen [::]:80 default_server;
server_name abc.example.com;
return 301 https://$server_name$request)uri; }
server{
# SSL configuration
server_name abc.example.com;
listen 443 ssl http2 default_server;
listen [::]:443 ssl http2 default_server;
include snippets/ssl-abc.example.com.conf;
include snippets/ssl-params.conf;
location / {
include proxy_params;
proxy_pass http://unix:/home/user1/apps/myapp/myapp.sock;
}
location ~ /.well-known {
allow all;
}
}
You have a typo in your first server section; it should be:
return 301 https://$server_name$request_uri;

Django on a url other than localhost [duplicate]

This question already has answers here:
How to specify which eth interface Django test server should listen on?
(3 answers)
Closed 7 years ago.
I have a server aerv.nl.
it has django (a python framework) but when i run the django server it says:
server started at: http://127.0.0.1:8000/ how can i let the server run on: http://www.aerv.nl/~filip/ ? (a real url)
You'll have to configure your http server and Django. For example if you're using apache you'll need to go through this:
https://docs.djangoproject.com/en/1.9/howto/deployment/wsgi/modwsgi/
What you're doing here is setting up your server to handle the http requests through your django app.
You will need to understand how DNS works, then use redirecting and then some proper server (like nginx or apache with e.g. gunicorn), not django development server, which shouldn't be used on production. There is no way you could do what you ask for just with ./manage runserver. All you can do is to change IP address and port to something different by e.g.: ./manage.py runserver 192.168.0.12:9999 so for example other computers in your network might access your site on this specific IP and port.
Example
You are owner of domain example.com, you have server where you want to server your site with IP address e.g. 5.130.2.19.
You need go to your domain provider and add an A record which connects these together: example.com -> 5.130.2.19.
Then on your server you set up webserver, e.g. nginx and let it run with e.g. this config for your particular server/site:
server {
listen 80;
server_name example.com;
client_max_body_size 4G;
location /static/ {
autoindex on;
alias /var/www/example/django/static/;
}
location /media/ {
autoindex on;
alias /var/www/example/django/media/;
}
location / {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_redirect off;
if (!-f $request_filename) {
proxy_pass http://upstream_server;
break;
}
}
upstream upstream_server {
server unix:/var/www/example/gunicorn.sock fail_timeout=10s;
}
then you would need to run gunicorn with something like
gunicorn example.wsgi:application --bind=unix:/var/www/example/gunicorn.sock
That should be all, but it's of course very brief. Just substitute example.com for your URL. It is up to you if this going to be specific record in nginx config (think about this as an entry point) or if it is going to be one of route specified in your django project.
How does it work?
User put example.com into an address bar, your computer then ask global DNS servers: To what IP address example.com points to?, DNS reply: It's 5.130.2.19. User's browser then sends HTTP request on that IP, where nginx get this request and looks inside its config if there is example.com handler. It find that it is there and that he should look for files in unix:/var/www/example/gunicorn.sock. He looks there and see working gunicorn, which basically parse python django project to something what nginx can present as your website.

Socket connection through nginx

i have a production server which has a nginx server to handle connection to several services. In other machine which is only visible through a VPN from the production server, I have a development server which is used to test some networks application.
I want to reach services provided for the development machine from internet, so I need to forward the incomming traffic to the development server
1.- Client request using socket connection to a.domain.com (Port 7081)
2.- nginx must forward this, I have the following code for that
Note: a.domain.com has a VPN interface at 10.8.0.1
server {
listen 7081;
server_name a.domain.com;
location / {
proxy_pass http://10.8.0.210:7081;
proxy_set_header X-Real-IP $remote_addr;
}
}
3.- In the development server (10.8.0.210) I have a service listining in port 7081.
The socket connection from client returned the following
<html>
<head><title>400 Bad Request</title></head>
<body bgcolor="white">
<center><h1>400 Bad Request</h1></center>
<hr><center>nginx/0.6.35</center>
</body>
</html>
4.- nginx server at a.domain.com logged the following
XXX.XXX.XX.XX - - [11/Feb/2011:08:58:10 -0300] "-" 400 173 "-" "-"
Any ideas
thank you
Bad request -- means, that it is not http request.
Nginx can proxy only http/smtp/pop3/imap protocols.
If you want to proxy anything else, you must use for example DNAT in iptables

Categories