Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I run Flask+Nginx+uWSGI with SELinux in Enforcing mode?

I'm following this tutorial to run Flask on an Nginx server. I've almost got it to work, wherein the page loads when SELinux is set as Permissive but shows a 502 Bad Gateway when SELinux is in the Enforcing mode.

Here are some relevant files:

myproject.ini

[uwsgi]
module = wsgi

master = true
processes = 5

socket = myproject.sock
chmod-socket = 660
vacuum = true

die-on-term = true

myproject.service

[Unit]
Description=uWSGI instance to serve myproject
After=network.target

[Service]
User=thisuser
Group=nginx
WorkingDirectory=/home/thisuser/public_html
Environment="PATH=/home/thisuser/thisuser_env/bin"
ExecStart=/home/thisuser/thisuser_env/bin/uwsgi --ini myproject.ini

[Install]
WantedBy=multi-user.target

thisuser.com.conf (Nginx configuration)

server {
    listen  80;

    server_name thisuser.com www.thisuser.com;
    access_log /home/thisuser/logs/access.log;
    error_log /home/thisuser/logs/error.log;

    location / {
        include uwsgi_params;
        uwsgi_pass unix:/home/thisuser/public_html/myproject.sock;
        try_files $uri $uri/ =404;
    }

}

The location of the Flask files+dirs is /home/thisuser/ and it's contexts are set like so:

[root@dev ~]# ls -ldZ /home/thisuser/
drwx--x--x. thisuser thisuser unconfined_u:object_r:user_home_dir_t:s0 /home/thisuser/
[root@dev ~]# ls -ldZ /home/thisuser/public_html/
drwxrwxr-x. thisuser thisuser unconfined_u:object_r:httpd_sys_content_t:s0 /home/thisuser/public_html/

The errors are as follows:

/var/log/audit/audit.log

type=AVC msg=audit(1498880449.864:156): avc:  denied  { write } for  pid=2667 comm="nginx" name="myproject.sock" dev="dm-2" ino=67165858 scontext=system_u:system_r:httpd_t:s0 tcontext=system_u:object_r:httpd_sys_content_t:s0 tclass=sock_file
type=SYSCALL msg=audit(1498880449.864:156): arch=c000003e syscall=42 success=no exit=-13 a0=f a1=7f526e12e548 a2=6e a3=7ffdf52991b0 items=0 ppid=2666 pid=2667 auid=4294967295 uid=997 gid=995 euid=997 suid=997 fsuid=997 egid=995 sgid=995 fsgid=995 tty=(none) ses=4294967295 comm="nginx" exe="/usr/sbin/nginx" subj=system_u:system_r:httpd_t:s0 key=(null)

and

/home/thisuser/logs/error.log

2017/06/30 23:40:49 [crit] 2667#0: *1 connect() to unix:/home/thisuser/public_html/myproject.sock failed (13: Permission denied) while connecting to upstream, client: 192.168.1.15, server: thisuser.com, request: "GET / HTTP/1.1", upstream: "uwsgi://unix:/home/thisuser/public_html/myproject.sock:", host: "thisuser.com"

Steps tried:

  • tried changing the sock permissions to chmod-socket = 666
  • used setsebool -P httpd_can_network_connect 1
  • changed FROM user=thisuser to user=nginx
  • added thisuser to the nginx group

The only thing that works is changing SELinux to Permissive. Are there some changes/additions I can make, so that SELinux stays Enforcing?

Edit: http(s) has already been allowed in firewalld

[root@dev ~]# firewall-cmd --permanent --zone=public --add-service=https
[root@dev ~]# firewall-cmd --permanent --zone=public --add-service=http
[root@dev ~]# firewall-cmd --reload
like image 692
rahuL Avatar asked Jul 01 '17 04:07

rahuL


1 Answers

Not sure if the below will work but:

  • The socket needs to be associated with the httpd_sys_content_rw_t type so that processes associated with httpd_t can write it. create "myproject/runtime" and associate type httpd_sys_content_rw_t with "runtime" so that the socket gets created with the httpd_sys_content_rw_t type

  • Make systemd manually associate the uwsgi app process with the httpd_sys_script_t type so that the webapp is targeted by SELinux (not sure whether systemd is allowed to do this as is in the policy)

The gist is that:

avc:  denied  { write } for  pid=2667 comm="nginx" name="myproject.sock" dev="dm-2" ino=67165858 scontext=system_u:system_r:httpd_t:s0 tcontext=system_u:object_r:httpd_sys_content_t:s0 tclass=sock_file

Indicates that nginx process associated with type httpd_t was not allowed to write the myproject.sock sock file because it was associated with the "read only" httpd system content type.

It should have been associated with the "read and write" httpd system content type instead. ini:

[uwsgi]
module = wsgi

master = true
processes = 5

socket = /home/thisuser/public_html/myproject/runtime/myproject.sock
chmod-socket = 660
vacuum = true

die-on-term = true

unit:

[Unit]
Description=uWSGI instance to serve myproject
After=network.target

[Service]
User=thisuser
Group=nginx
WorkingDirectory=/home/thisuser/public_html/myproject
Environment="PATH=/home/thisuser/thisuser_env/bin"
ExecStart=/home/thisuser/thisuser_env/bin/uwsgi --ini myproject.ini
SELinuxContext=system_u:system_r:httpd_sys_script_t:s0

[Install]
WantedBy=multi-user.target

conf:

server {
    listen  80;

    server_name thisuser.com www.thisuser.com;
    access_log /home/thisuser/logs/access.log;
    error_log /home/thisuser/logs/error.log;

    location / {
        include uwsgi_params;
        uwsgi_pass unix:/home/thisuser/public_html/myproject/runtime/myproject.sock;
        try_files $uri $uri/ =404;
    }

}

Associate labels:

chcon -t httpd_sys_script_exec_t /home/thisuser/thisuser_env/bin/uwsgi
chcon -Rt httpd_sys_content_rw_t /home/thisuser/public_html/myproject/runtime
like image 75
dac.override Avatar answered Nov 22 '22 10:11

dac.override