Nginx download permissions error - Open() failed (13: Permission denied) - django

I have a webpage with Nginx + Uwsgi + Django where I have an external path called /download to manage the downloads in Django (the user credentials) and the internal path /download-nginx to actually download the files on the directory /var/wwww/download. For the sake of trials, I have tried to do this with my username as well as the default nginx user. With both of them I get a permission denied error on Nginx:
open() "/var/www/download/example.txt" failed (13: Permission denied)
I have read several other solutions on SO telling that the problem is that the provided user in nginx.conf does not have enough permissions. The thing is that they do have enough permissions:
$ sudo -u nginx stat /var
File: ‘/var’
Size: 4096 Blocks: 8 IO Block: 4096 directory
Device: 802h/2050d Inode: 50331745 Links: 21
Access: (0777/drwxrwxrwx) Uid: ( 996/ nginx) Gid: ( 0/ root)
Context: system_u:object_r:var_t:s0
Access: 2021-11-23 11:24:53.329927606 +0000
Modify: 2021-11-23 09:43:29.250244353 +0000
Change: 2021-11-23 11:21:37.151148760 +0000
Also, just in case I have done chmod 777 recursively on directory /var/wwww/download
My nginx.conf file is as follows:
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log;
pid /run/nginx.pid;
# Load dynamic modules. See /usr/share/doc/nginx/README.dynamic.
include /usr/share/nginx/modules/*.conf;
events {
worker_connections 1024;
}
http {
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 4096;
include /etc/nginx/mime.types;
default_type application/octet-stream;
client_max_body_size 128M;
proxy_max_temp_file_size 0;
proxy_buffering off;
server_names_hash_bucket_size 256;
# Load modular configuration files from the /etc/nginx/conf.d directory.
# See http://nginx.org/en/docs/ngx_core_module.html#include
# for more information.
include /etc/nginx/conf.d/*.conf;
upstream django {
server 127.0.0.1:8000;
}
server {
listen 80;
listen [::]:80;
server_name _;
root /usr/share/nginx/html;
# Load configuration files for the default server block.
include /etc/nginx/default.d/*.conf;
location /download-nginx {
internal;
alias /var/www/download;
sendfile on;
proxy_max_temp_file_size 0;
}
location / {
uwsgi_pass django;
proxy_read_timeout 300s;
proxy_connect_timeout 75s;
uwsgi_param Host $host;
uwsgi_param X-Real-IP $remote_addr;
uwsgi_param X-Forwarded-For $proxy_add_x_forwarded_for;
uwsgi_param X-Forwarded-Proto $http_x_forwarded_proto;
uwsgi_param QUERY_STRING $query_string;
uwsgi_param REQUEST_METHOD $request_method;
uwsgi_param CONTENT_TYPE $content_type;
uwsgi_param CONTENT_LENGTH $content_length;
uwsgi_param REQUEST_URI $request_uri;
uwsgi_param PATH_INFO $document_uri;
uwsgi_param DOCUMENT_ROOT $document_root;
uwsgi_param SERVER_PROTOCOL $server_protocol;
uwsgi_param HTTPS $https if_not_empty;
uwsgi_param REMOTE_ADDR $remote_addr;
uwsgi_param REMOTE_PORT $remote_port;
uwsgi_param SERVER_PORT $server_port;
uwsgi_param SERVER_NAME $server_name;
}
error_page 404 /404.html;
location = /404.html {
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
}
}
}
The download view on my Django webpage is as follows, (although the error I'm pretty sure that is not on this snippet):
def download(request):
# Auth code is ommitted #
response = HttpResponse()
path = "/var/www/download/example.txt"
name = "example.txt"
response['Content-Length'] = os.path.getsize(path)
response['X-Accel-Redirect'] = "/download-nginx/{0}".format(name)
del response['Content-Type']
del response['Content-Disposition']
del response['Accept-Ranges']
del response['Set-Cookie']
del response['Cache-Control']
del response['Expires']
return response
Therefore, my question is: what should I do in my Centos machine in order to be able to access the data on /var/www/download and provide it to the users as downloadable elements?

Problem solved: Nginx needs +x permission on each of the directories. This was solved with:
sudo chmod +x /var
sudo chmod +x /var/www
sudo chmod +x /var/www/download

Related

Django + Nginx + Uwsgi see Nginx default page then run on 80 port

I have Django app that runs on VPS using Nginx + Uwsgi.
The Symlink nginx config
# the upstream component nginx needs to connect to
upstream django {
server unix:///root/ubergf/client/uwsgi_nginx.sock; # for a file socket
# server 127.0.0.1:8001; # for a web port socket (we'll use this first)
}
# configuration of the server
server {
# the port your site will be served on
listen 80;
# the domain name it will serve for
server_name my-site.com; # substitute your machine's IP address or FQDN
charset utf-8;
# max upload size
client_max_body_size 75M; # adjust to taste
# Django media
location /media {
alias /root/ubergf/client/media; # your Django project's media files - amend as required
}
location /static {
alias /root/ubergf/client/staticfiles; # your Django project's static files - amend as required
}
# Finally, send all non-media requests to the Django server.
location / {
uwsgi_pass django;
include /root/ubergf/client/deployment/uwsgi_params; # the uwsgi_params file you installed
}
}
uwsgi_params
uwsgi_param QUERY_STRING $query_string;
uwsgi_param REQUEST_METHOD $request_method;
uwsgi_param CONTENT_TYPE $content_type;
uwsgi_param CONTENT_LENGTH $content_length;
uwsgi_param REQUEST_URI $request_uri;
uwsgi_param PATH_INFO $document_uri;
uwsgi_param DOCUMENT_ROOT $document_root;
uwsgi_param SERVER_PROTOCOL $server_protocol;
uwsgi_param REQUEST_SCHEME $scheme;
uwsgi_param HTTPS $https if_not_empty;
uwsgi_param REMOTE_ADDR $remote_addr;
uwsgi_param REMOTE_PORT $remote_port;
uwsgi_param SERVER_PORT $server_port;
uwsgi_param SERVER_NAME $server_name;
ubergfapi_uwsgi.ini
[uwsgi]
chdir = /root/ubergf/client
module = ubergfapi.wsgi
master = true
processes = 10
socket = /root/ubergf/client/uwsgi_nginx.sock
chmod-socket = 666
vacuum = true
env = DEBUG_MODE=False
When I run everything on port 8000 (change in Symlink nginx config) everything works fine (my_domain.com : 8000), but when I change it back to 80 - my_domain.com returns me Nginx default page.
EDITED:
Tried to add to location section following params and got the same result
proxy_pass http://your_server_ip:8000;
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;
I added
uwsgi_param Host $host;
uwsgi_param X-Real-IP $remote_addr;
uwsgi_param X-Forwarded-For $proxy_add_x_forwarded_for;
uwsgi_param X-Forwarded-Proto $http_x_forwarded_proto;
to location location and it worked

Deploying Django with uwsgi and nginx, uwsgi ok but nginx not working

I am trying to run my site, when i run
uwsgi --socket 0.0.0.0:8080 --protocol=http --chdir /opt/virtualenv/landivarpj/ --wsgi-file /opt/virtualenv/landivarpj/landivarpj/wsgi.py
i can access 192.xxx.xxx.xxx:8080 fine and my test text appears,
but if i try to go trought 192.xxx.xxx.xxx i only get an nginx welcome page,
and if i try to go in trought my domain www.xxxxxxxx.com, then it doesnt work at all.
in my project folder(opt/virtualenv/landivarpj) i have a uswgi_params file with
uwsgi_param QUERY_STRING $query_string;
uwsgi_param REQUEST_METHOD $request_method;
uwsgi_param CONTENT_TYPE $content_type;
uwsgi_param CONTENT_LENGTH $content_length;
uwsgi_param REQUEST_URI $request_uri;
uwsgi_param PATH_INFO $document_uri;
uwsgi_param DOCUMENT_ROOT $document_root;
uwsgi_param SERVER_PROTOCOL $server_protocol;
uwsgi_param REQUEST_SCHEME $scheme;
uwsgi_param HTTPS $https if_not_empty;
uwsgi_param REMOTE_ADDR $remote_addr;
uwsgi_param REMOTE_PORT $remote_port;
uwsgi_param SERVER_PORT $server_port;
uwsgi_param SERVER_NAME $server_name;
then in (opt/virtualenv/landivarpj/landivarpj) the wsgi.py is
import os
from django.core.wsgi import get_wsgi_application
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "landivarpj.settings")
application = get_wsgi_application()
in etc/nginx/sites-available is have drlandivar.conf
upstream django {
server 192.xxx.xxx.xxx:8080; # for a web port socket (we'll use this first)
}
server {
listen 80;
server_name drlandivar.com www.drlandivar.com;
charset utf-8;
client_max_body_size 75M; # adjust to taste
location /media {
alias /opt/virtualenv/landivarpj/media;
}
location /static {
alias /opt/virtualenv/landivarpj/static;
}
location / {
uwsgi_pass django;
include /opt/virtualenv/landivarpj/uwsgi_params;
}
}
the site-available and site-enable are linked
what have i done wrong why it work on 192.xxx.xxx.xxx:8080
but not trought the domain and nginx
***** new edit as recommended on nginx/availables-site/drlandivar.conf
upstream django {
server 192.254.145.207:8080;
}
server {
listen 80;
server_name drlandivar.com www.drlandivar.com;
charset utf-8;
client_max_body_size 75M; # adjust to taste
location /media {
alias /opt/virtualenv/landivarpj/media;
}
location /static {
alias /opt/virtualenv/landivarpj/static;
}
location / {
proxy_pass http://django;
}
}
it still give me same problem page only load trought 192.xxx.xxx.xxx:8080 not trought drlandivar.com
please help
You need to proxy_pass instead. The following configuration should do the trick.
upstream django {
server 192.254.145.207:8080;
}
server {
...
location / {
proxy_pass http://django;
}
}
Comparing yours to a working example of mine, one thing stands out. Try
...
location / {
include uwsgi_params;
proxy_pass http://django;
}
Adding --logto /var/log/uwsgi/uwsgi.log to your uwsgi invocation (after creating /var/log/uswgi and making it writeable to the uwsgi process) might shed some additional light.

Django SECRET_KEY called in os.environ but isn't an environment variable

I've been asked to look at a Django project where the developer has disappeared. I cannot work out how they've set the SECRET_KEY. In settings.py we have SECRET_KEY = os.environ['SECRET_KEY']
It is running on a Ubuntu 14.04.05 server. I understand the code above to mean the SECRET_KEY has been set as an environment setting so in terminal I type printenv to see the environment settings and SECRET_KEY isn't there.
How might it be being set?
EDIT
nginx.conf
user www-data;
worker_processes 1;
pid /run/nginx.pid;
events {
worker_connections 1024;
# multi_accept on;
}
http {
##
# Basic Settings
##
client_body_buffer_size 10K;
client_header_buffer_size 1k;
client_max_body_size 8m;
large_client_header_buffers 2 1k;
sendfile on;
tcp_nopush on;
tcp_nodelay on;
client_body_timeout 12;
client_header_timeout 12;
keepalive_timeout 15;
send_timeout 10;
types_hash_max_size 2048;
# server_tokens off;
# server_names_hash_bucket_size 64;
# server_name_in_redirect off;
include /etc/nginx/mime.types;
default_type application/octet-stream;
##
# Logging Settings
##
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
##
# Gzip Settings
##
gzip on;
gzip_disable "msie6";
# gzip_vary on;
gzip_proxied expired no-cache no-store private auth;
gzip_comp_level 2;
gzip_min_length 1000;
# gzip_buffers 16 8k;
# gzip_http_version 1.1;
gzip_types text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript;
##
# nginx-naxsi config
##
# Uncomment it if you installed nginx-naxsi
##
#include /etc/nginx/naxsi_core.rules;
##
# nginx-passenger config
##
# Uncomment it if you installed nginx-passenger
##
#passenger_root /usr;
#passenger_ruby /usr/bin/ruby;
##
# Virtual Host Configs
##
include /etc/nginx/conf.d/*.conf;
include /etc/nginx/sites-enabled/*;
}
uwsgi_params
uwsgi_param QUERY_STRING $query_string;
uwsgi_param REQUEST_METHOD $request_method;
uwsgi_param CONTENT_TYPE $content_type;
uwsgi_param CONTENT_LENGTH $content_length;
uwsgi_param REQUEST_URI $request_uri;
uwsgi_param PATH_INFO $document_uri;
uwsgi_param DOCUMENT_ROOT $document_root;
uwsgi_param SERVER_PROTOCOL $server_protocol;
uwsgi_param UWSGI_SCHEME $scheme;
uwsgi_param REMOTE_ADDR $remote_addr;
uwsgi_param REMOTE_PORT $remote_port;
uwsgi_param SERVER_PORT $server_port;
uwsgi_param SERVER_NAME $server_name;
There is a really simple hack I use: It worked for me, but am still testing different environments. This is how I did it. You set variables when activating your virtual environment.
Just open your bin/activate file that you source for activating the virtual environment and add something like this to the end of it:
If your virtual environment folder is, for example, "virtual", then you activate your virtual environment using this command:
source virtual/bin/activate
So, now you know where to locate your "activate" file, which is located in the virtual environment. Open it with a text editor and add the lines below at the end of the file. NOTE: replace the characters between the quotes with your secret key.
export APP_SECRET_KEY="OiJjajJjZXlraGcwMDBrMndtdWJ6NDFsNWt4"
export APP_DEBUG="1"
...
Now everytime you activate the environment (source virtenv/bin/activate), all configuration variables will be set and available.

Django Nginx uWSGI 502 Bad Gateway always

I have been following the http://uwsgi-docs.readthedocs.io/en/latest/tutorials/Django_and_nginx.html
and went up to the
http://uwsgi-docs.readthedocs.io/en/latest/tutorials/Django_and_nginx.html#running-the-django-application-with-uwsgi-and-nginx
and started the uwsgi --socket mysite.sock --module mysite.wsgi --chmod-socket=664 it is started but when i load my webpage on browser getting 502 Bad Gateway
Django version 1.10.2
error is
error] 25444#25444: *1 connect() failed (111: Connection refused)
while connecting to upstream, client: 127.0.0.1, server: mytest.com,
request: "GET / HTTP/1.1", upstream: "uwsgi://127.0.0.1:8001", host:
"127.0.0.1:8000"
What could be the issue ?
# configuration of the server
server {
# the port your site will be served on
listen 8000;
# the domain name it will serve for
server_name mytest.com; # substitute your machine's IP address or FQDN
charset utf-8;
# max upload size
client_max_body_size 175M; # adjust to taste
# Django media
location /media {
alias /home/karesh/tutorial/uwsgi-tutorial/mysite/media; # your Django project's media files - amend as required
}
location /static {
alias /home/karesh/tutorial/uwsgi-tutorial/mysite/static; # your Django project's static files - amend as required
}
# Finally, send all non-media requests to the Django server.
location / {
uwsgi_pass unix:/home/karesh/tutorial/uwsgi-tutorial/mysite/mysite.sock;
include /home/karesh/tutorial/uwsgi-tutorial/mysite/uwsgi_params; # the uwsgi_params file you installed
}
}
uwsgi_params file inside project directory
uwsgi_param QUERY_STRING $query_string;
uwsgi_param REQUEST_METHOD $request_method;
uwsgi_param CONTENT_TYPE $content_type;
uwsgi_param CONTENT_LENGTH $content_length;
uwsgi_param REQUEST_URI $request_uri;
uwsgi_param PATH_INFO $document_uri;
uwsgi_param DOCUMENT_ROOT $document_root;
uwsgi_param SERVER_PROTOCOL $server_protocol;
uwsgi_param REQUEST_SCHEME $scheme;
uwsgi_param HTTPS $https if_not_empty;
uwsgi_param REMOTE_ADDR $remote_addr;
uwsgi_param REMOTE_PORT $remote_port;
uwsgi_param SERVER_PORT $server_port;
uwsgi_param SERVER_NAME $server_name;
A few things, that could help you:
1) Add user, that runs uWSGI, to nginx group
2) On CentOS with enabled SE the best way to put socket is a directory under /run
3) Set socket permissions to <your_user>:nginx(in other words - set permission for socket for your user and for nginx group.
These steps normally helps me to figure out with permissions error.

how to nginx virtual servers + fcgi for django?

I would like to run several virtual hosts via nginx, each serving a different django app via fcgi. Is this possible? If so, does anyone have good resources on where/how to start? The nginx docs seem to be mostly examples, but none of the particular config I'm attempting...
There have been two pretty good blog posts lately about setting up nginx, but both are using nginx to serve static (or cached) content and apache + mod_wsgi to serve Django. I prefer this myself because mod_wsgi makes process management so much easier than fcgi (among other advantages).
Anyway, here are the posts:
The Django and Ubuntu Intrepid Almanac
django, nginx, memcached - the dynamic trio
EDIT: ok I dug out an old tar file with my nginx + django + virtual host config files from a year ago before I switched to apache + mod_wsgi. This was a development machine, so you'll want to adjust # of workers, connections, etc.
nginx.conf:
user nginx nginx;
worker_processes 2;
error_log /var/log/nginx/error_log info;
events {
worker_connections 1024;
use epoll;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
log_format main
'$remote_addr - $remote_user [$time_local] '
'"$request" $status $bytes_sent '
'"$http_referer" "$http_user_agent" '
'"$gzip_ratio"';
client_header_timeout 3m;
client_body_timeout 3m;
send_timeout 3m;
connection_pool_size 256;
client_header_buffer_size 1k;
large_client_header_buffers 4 2k;
request_pool_size 4k;
gzip on;
gzip_min_length 1100;
gzip_buffers 4 32k;
gzip_types text/plain text/html application/x-javascript text/xml text/css;
output_buffers 4 32k;
postpone_output 1460;
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 75 20;
ignore_invalid_headers on;
include vhosts.d/*.conf;
}
So, the main nginx.conf includes every file in the vhosts.d/ subdirectory. One of my files was for serving PHP on localhost (was probably running phpMyAdmin) like this:
vhosts.d/00_localhost:
server {
listen 127.0.0.1:80;
server_name localhost;
access_log /var/log/nginx/localhost.access_log main;
error_log /var/log/nginx/localhost.error_log info;
root /var/www/localhost/htdocs;
index index.php index.html index.htm;
location ~ .php$ {
fastcgi_pass 127.0.0.1:8888;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME /var/www/localhost/htdocs$fastcgi_script_name;
fastcgi_param QUERY_STRING $query_string;
fastcgi_param REQUEST_METHOD $request_method;
fastcgi_param CONTENT_TYPE $content_type;
fastcgi_param CONTENT_LENGTH $content_length;
}
}
And then a local Django development server like this:
50_django.local:
server {
listen 80;
server_name django.local;
access_log /var/log/nginx/django.access.log main;
error_log /var/log/nginx/django.error.log info;
root /var/www/django.local;
location ~* ^.+\.(mpg|avi|mp3|swf|zip|tgz|gz|rar|bz2|doc|xls|exe|ppt|txt|tar|mid|midi|wav|rtf|mpeg)$ {
access_log off;
break;
}
location ~* ^.+\.(jpg|jpeg|gif|png|ico|css|bmp|js)$ {
expires 30d;
break;
}
location / {
fastcgi_pass unix:/var/www/django.local/server.sock;
include fastcgi.conf;
}
location ^~ /admin/ {
fastcgi_pass unix:/var/www/django.local/server.sock;
include fastcgi.conf;
access_log off;
auth_basic "Welcome to admin";
}
}
Finally, each of the virtual servers included a fastcgi.conf for each location.
fastcgi.conf:
fastcgi_pass_header Authorization;
fastcgi_intercept_errors off;
fastcgi_param PATH_INFO $fastcgi_script_name;
fastcgi_param REQUEST_METHOD $request_method;
fastcgi_param QUERY_STRING $query_string;
fastcgi_param CONTENT_TYPE $content_type;
fastcgi_param CONTENT_LENGTH $content_length;
fastcgi_param SERVER_PORT $server_port;
fastcgi_param SERVER_PROTOCOL $server_protocol;
fastcgi_param SERVER_NAME $server_name;
fastcgi_param REQUEST_URI $request_uri;
fastcgi_param DOCUMENT_URI $document_uri;
fastcgi_param DOCUMENT_ROOT $document_root;
fastcgi_param SERVER_ADDR $server_addr;
fastcgi_param REMOTE_USER $remote_user;
fastcgi_param REMOTE_ADDR $remote_addr;
fastcgi_param REMOTE_PORT $remote_port;
fastcgi_param SERVER_SOFTWARE "nginx";
fastcgi_param GATEWAY_INTERFACE "CGI/1.1";
fastcgi_param UID_SET $uid_set;
fastcgi_param UID_GOT $uid_got;
I'm not sure all of the above were required, but that was another one of the reasons I switched to mod_wsgi... superior support and documentation :)
Since this question was asked someone created a pip installable django package that will generate an apache or nginx vhost file for you from your settings.py
pip install django-vhost
Check it out here: https://bitbucket.org/djangostars/django-vhost