25
votes

I try to configure uWsgi, Django ,Nginx with this document: http://uwsgi-docs.readthedocs.org/en/latest/tutorials/Django_and_nginx.html

Finish config the uwsgi.ini file, create a soft link at /etc/uwsgi/vassals.

Failed at the last step :Make uWSGI startup when the system boots.

When run this command:

sudo /usr/local/bin/uwsgi --emperor /etc/uwsgi/vassals --uid www-data --gid www-data

I got this error:

clock source: unix
detected number of CPU cores: 1
current working directory: /etc/uwsgi/vassals
detected binary path: /usr/local/bin/uwsgi
!!! no internal routing support, rebuild with pcre support !!!
your processes number limit is 3813
your memory page size is 4096 bytes
detected max file descriptor number: 1024
lock engine: pthread robust mutexes
thunder lock: disabled (you can enable it with --thunder-lock)
bind(): Permission denied [core/socket.c line 227]
Tue May 27 05:29:26 2014 - [emperor] curse the uwsgi instance uwsgi.ini (pid: 1391)
Tue May 27 05:29:29 2014 - [emperor] removed uwsgi instance uwsgi.ini

If I run this command without sudo, everything is OK.

I've add user "kk" into group "www-data", and here is the uwsgi.ini

[uwsgi]
chdir           = /home/kk/XXXXXXX
module          = wsgi
home            = /home/kk/XXXXXXX

master          = true
processes       = 10
socket          = /home/kk/XXXXXXX/mysite.sock
chmod-socket    = 666
vacuum          = true

I guess maybe I made mistake on file permission. Does anybody have good idea?Thank you.


Update:

The official document is correct, I follow the steps to deploy the project in another new VPS, no error occurred.

10
if the emperor runs as www-data all of its vassals will run as www-data. For this reason /home/kk/XXXXXX must be writable by www-data.roberto
@roberto kk is a member of group of www-data, the project folder's mod is 775. It's strange that I can run this command as kk but failed as root.Hunger
double check if there is already a socket file not owned by www-dataroberto
@roberto No, before I run the command, there's no socket file in project folder.Hunger
@Hunger I ran into the same error ? DO you have a solution for this?Mevin Babu

10 Answers

18
votes

I was having this problem. Running without setting the group and user ids solved the problem. I'll probably revisit this when I have more time to fix file permissions for the directory, but it works for the moment

/usr/local/bin/uwsgi --emperor /etc/uwsgi/vassals

EDIT I've had time to revisit this answer and I'd have to say that this is not good practice when running uwsgi in production.

The problem with the tutorial as written is that it assumes that www-data is a user and that the www-data user and group has access to all the files it needs on your server; in particular the socket file. Replace the appropriate arguments with your user and group and and you'll be good to go (and won't leave a gaping security hole on your server).

So, the correct command (if I was user ovangle in group ovangle would be):

/usr/local/bin/uwsgi --emperor /etc/uwsgi/vassals --uid ovangle --gid ovangle

It would be better to create a user which has the specific permissions it needs to run the server successfully, but that's left as an exercise for the reader.

17
votes

I don't know why the permissions don't work, but I ran into the same problem.

One quick way to fix this is to move the sockets to /tmp though! (Which is a fairly reasonable place to keep sockets anyway...)

so just update the uwsgi config with:

socket          = /tmp/mysite.sock

and the nginx-config with:

upstream django {
    server unix:///tmp/mysite.sock;
}

and it'll start working!

4
votes

You did the permissions backwards.

uwsgi is running as www-data.

Your socket is in kk's home directly which is presumably owned by the kk user and the kk group.

You made it so that kk can access everything that www-data owns, not so www-data can access what kk owns.

You want to add the www-data to kk's group. This way www-data can reach the socket in kk's home.

usermod www-data -aG kk

Confirm with groups www-data and you should get back www-data : www-data kk showing that www-data is now in kk's primary group.

Now, provided kk's home folder permissions have at least '6' for the group permission www-data can read and write to the socket as necessary. E.g. chmod 660 /home/kk/XXXXXXX/mysite.sock.

1
votes

This is how I got the socket to start securely. Are you running in a virtualenv? I got the same error message when I was sourced to the virtualenv with my app, since there's no sudo in the env. I had to deactivate the virtualenv then to install uwsgi globally. After installing uWSGI I needed to download the python3 plugin with sudo apt-get install uwsgi-plugin-python3, and add "plugins = python3" to my uWSGI ini file. After all of that I was able to start uWSGI with sudo/root eq. sudo uwsgi --ini mysite.ini.

As for security it's recommended to add these lines to the ini file:

uid = www-data
gid = www-data
chmod-socket = 644

# Plus here's the plugin I mentioned
plugins = python3

For these to be honored www-data has to own the parent directory where the mysite.sock file will be created, and the uwsgi command needs to be started with sudo. If either of those options are off then the socket gets created as the user who ran the uwsgi command.

0
votes

If you are okay using a web port socket (like the first part of the demo) instead of unix sockets.. you could change this..

# uwsgi.ini
socket = :8001

and this..

# mysite_nginx.conf
upstream django {
    # server unix:///home/teewuane/uwsgi-tutorial/mysite/mysite.sock; # for a file socket
    server 127.0.0.1:8001; # for a web port socket (we'll use this first)
}

and you will avoid the permission issues.

0
votes

The cause of the issue you asking about is that uwsgi is trying to create a unix socket file to interact with a webserver via fastCGI protocol in directory you configured /home/kk/XXXXXXX/ You should set write permissions for the user you run uwsgi from to the directory /home/kk/XXXXXXX/

0
votes

Ran into the exact same problem, after solving it by running with users and groups which have enough permission for the socket file, I realized this probably is a bug.

It's very confusing if you can actually run it in current user with uwsgi --emperor /etc/uwsgi/vassals --uid www-data --gid www-data while once sudo is added you get bind(): Permission denied error.

The only explanation for this would be when you run it without sudo, somehow --uid www-data --gid www-data part DOES NOT work and you're actually running it with current user which have enough permision; and once sudo is added, --uid www-data --gid www-data part magically works again, which ends up with www-data not having enough permision to bind the socket file.

0
votes

I also had this error. It turned that my folder had the wrong owner and group. Files inside were correct so I didn't catch it for a while.

0
votes

Kind of resurrecting an old question, but I ran into this problem.

I found the solution. I had previously run uwsgi to test something as root. Later on I tried running it as www-data. Eventually I figured out that the stats server makes a socket file in /tmp/name.stats.sock this was owned by root and therefore would crash uwsgi. I just removed that and it works now!

I hope this helps anyone stumbling around with this.

0
votes

My error was that I expected that if I add the site user (USER) to the uwsgi group, it'll be able to write to /run/uwsgi. But it turns out supplementary groups are ignored in this case. So I ended up having the socket at /run/nginx-PRJ/socket (socket = /run/nginx-PRJ/socket), adding nginx to the site user's group (GROUP), and chmod-socket = 660. This way nginx is automatically able to access the socket if SELinux is in effect:

# grep httpd_var_run_t /etc/selinux/targeted/contexts/files/file_contexts
/var/run/wsgi.* -s  system_u:object_r:httpd_var_run_t:s0
/var/run/mod_.* system_u:object_r:httpd_var_run_t:s0
/var/run/httpd.*    system_u:object_r:httpd_var_run_t:s0
/var/run/nginx.*    system_u:object_r:httpd_var_run_t:s0
/var/run/apache.*   system_u:object_r:httpd_var_run_t:s0
/var/run/php-fpm(/.*)?  system_u:object_r:httpd_var_run_t:s0
/var/run/lighttpd(/.*)? system_u:object_r:httpd_var_run_t:s0
/var/lib/php/session(/.*)?  system_u:object_r:httpd_var_run_t:s0
/var/lib/php/wsdlcache(/.*)?    system_u:object_r:httpd_var_run_t:s0
/var/run/dirsrv/admin-serv.*    system_u:object_r:httpd_var_run_t:s0
/var/opt/rh/rh-nginx18/run/nginx(/.*)?  system_u:object_r:httpd_var_run_t:s0
/var/www/openshift/broker/httpd/run(/.*)?   system_u:object_r:httpd_var_run_t:s0
/var/www/openshift/console/httpd/run(/.*)?  system_u:object_r:httpd_var_run_t:s0
/opt/dirsrv/var/run/dirsrv/dsgw/cookies(/.*)?   system_u:object_r:httpd_var_run_t:s0
/var/run/thttpd\.pid    --  system_u:object_r:httpd_var_run_t:s0
/var/run/gcache_port    -s  system_u:object_r:httpd_var_run_t:s0
/var/run/cherokee\.pid  --  system_u:object_r:httpd_var_run_t:s0

# yum install setools-console

# sesearch -A -C -s httpd_t -c sock_file -p write | grep httpd_var_run_t
   allow httpd_t httpd_var_run_t : sock_file { ioctl read write create getattr setattr lock append unlink link rename open } ;

# man sesearch
       -A, --allow
              Search for allow rules.
       -C, --show_cond
              Print  the  conditional  expression and state for all conditional rules found.  This
              option has no effect on unconditional rules.
       -s NAME, --source=NAME
              Find rules with type/attribute NAME as their source.
       -p P1[,P2,...] --perm=P1[,P2...]
              Find rules with at least one of the specified permissions.  Multiple permissions may
              be  specified  as a comma separated list; it is recommended that this list be quoted
              for shells that interpret comma as a special character.

To make sure the dir always exists I made use of systemd-tmpfiles:

/etc/tmpfiles.d/PRJ.conf:

d /run/nginx-PRJ 0750 USER GROUP
# systemd-tmpfiles --create PRJ.conf

I'm running CentOS 7, and uwsgi-2.0.17.1-2.el7 in tyrant mode. In this case specifying gid, uid is not necessary. They are taken from the ini-file's permissions.