Django, nginx, FastCGI - running via unix sockets, permission problems
Solution 1
Nginx is running under some user (on Debian it is usually www-data), you can check it by:
ps aux | grep nginx | grep worker
User will be in the first column.
This user have to have access to /tmp/django.socket for writing and reading. You can solve it by running django under the same user as nginx is running (i.e. www-data on Debian), or you have to add nginx user to the same group, as user, under which are you running django, and socket have to have permission to read and write for group.
The first solution is simplier and (for me) better.
Solution 2
I had exactly this problem. I was running django-site on Gunicorn running via unix socket(on fedora 19). But nginx was not starting. I saw nginx-errors.log file
2014/03/15 04:25:01 [crit] 18309#0: *422 connect() to unix:/webapps/django/run/gunicorn.sock failed (13: Permission denied) while connecting to upstream
I set all files permissions and owners correctly. In the end I learnt that this is due to SElinux and found the solution here
UPDATE
following on the first comment
The solution described on the link that I provided is very long. So I'm just copying part of this solution here -
One quick solution is disable selinux
setenforce 0
This command disables selinux for all programs. To allow nginx to read unix socket while selinux is enabled, follow this procedure -
By default, SELinux log messages are written to /var/log/audit/audit.log
via the Linux Auditing System auditd. If the auditd daemon is not running, then messages are written to /var/log/messages
. SELinux log messages are labeled with the AVC keyword so that they might be easily filtered from other messages, as with grep.
So, by greping nginx in /var/log/audit/audit.log
I found those relative AVC messages, which indicate indeed a denial of nginx connection to gitlab.socket.
type=AVC msg=audit(1377542938.307:248364): avc: denied { write } for pid=2597 comm="nginx" name="gitlab.socket" dev="vda1" ino=1180273 scontext=system_u:system_r:httpd_t:s0 tcontext=system_u:object_r:httpd_sys_content_t:s0 tclass=sock_file
type=AVC msg=audit(1377542938.307:248364): avc: denied { connectto } for pid=2597 comm="nginx" path="/home/git/gitlab/tmp/sockets/gitlab.socket" scontext=system_u:system_r:httpd_t:s0 tcontext=system_u:system_r:initrc_t:s0 tclass=unix_stream_socket`
Using a tool called audit2allow we are able to clear the AVC messages. If you haven't got it installed, it is shipped with the policycoreutils-devel package.
grep nginx /var/log/audit/audit.log | audit2allow
and the result is:
#============= httpd_t ==============
#!!!! This avc is allowed in the current policy
allow httpd_t http_cache_port_t:tcp_socket name_connect;
# !!! This avc is allowed in the current policy
allow httpd_t httpd_log_t:file setattr;
#!!!! This avc is allowed in the current policy
allow httpd_t httpd_sys_content_t:sock_file write;
#!!!! This avc is allowed in the current policy
allow httpd_t initrc_t:unix_stream_socket connectto;
#!!!! This avc is allowed in the current policy
allow httpd_t user_home_dir_t:dir search;
#!!!! This avc is allowed in the current policy
allow httpd_t user_home_t:dir { search getattr };
#!!!! This avc is allowed in the current policy
allow httpd_t user_home_t:sock_file write;
#!!!! This avc is allowed in the current policy
allow httpd_t var_run_t:file { read write };
These are the policies that should be used with SELinux. Notice that user_home is essential since GitLab's APP_ROOT is in /home/git/. Similarly, you notice a policy related to the denied socket connection: unix_stream_socket connectto.
We can then go ahead and use audit2allow to make a custom policy module to allow these actions:
grep nginx /var/log/audit/audit.log | audit2allow -M nginx
semodule -i nginx.pp`
We can check the policy module loaded correctly by listing loaded modules with semodule -l.
After that, remember to enable SELinux again with setenforce 1.
Related videos on Youtube
InfinityGoesAround
Updated on September 18, 2022Comments
-
InfinityGoesAround over 1 year
I've configured nginx to run django site via socket:
fastcgi_pass unix:/tmp/django.socket;
now I'm (manually) running
./manage.py runfcgi socket=/tmp/django.socket
http request results in 502 bad gateway, and the error is following:
connect() to unix:/tmp/django.socket failed (13: Permission denied) while connecting to upstream,
what permissions should I set, to be able to restart django fcgi easily?
-
InfinityGoesAround over 12 yearsthank you! just in case anyone is interested: gksudo -u www-data ./manage.py runfcgi pidfile=/tmp/django.pid socket=/tmp/django.socket