3

I am currently 'lost' in the CentOS Selinux forest.

My setup involves setting up a WSGI socket in /var/www/demo/out which nginx uses to communicate with the UWSGI process. Whenever I request the page in my browser I get an nginx error.

Why is this Selinux related?

  • Disabling Selinux with setenforce 0 fixes it.
  • /var/log/audit/audit.log and audit2why display a denied and missing type enforcement (TE) allow rule

I have tried adding the httpd_sys_content_t label to the socket so nginx was allowed to read and write to the socket file, restorecon after adding the new label.

Running the violation through audit2allow returns the following policy:

module nginx 1.0;

require {
        type httpd_t;
        type var_t;
        type httpd_sys_content_t;
        class sock_file write;
}

#============= httpd_t ==============
allow httpd_t httpd_sys_content_t:sock_file write;

#!!!! WARNING: 'var_t' is a base type.
allow httpd_t var_t:sock_file write;

The first rule I understand, however what is the second rule conveying? I am guessing because the nginx process is requesting a tcontext that has var_t in it a new selinux policy is required that includes this new context?

So why is this warning here? Is it complaining that adding a directory like var to a policy is too general / isn't specific enough? If this is the case, can't this policy be narrowed to something like var_www_t? Also if this is the case then why is the uwsgi process, which is running under a non root user, allowed to write to the socket?

3 Answers3

3

Consider placing your socket in a location where SELinux already expects it to be.

# semanage fcontext -l | grep httpd_var_run_t | grep wsgi
/var/run/wsgi.*                                    socket             system_u:object_r:httpd_var_run_t:s0 

Thus if you create /run/wsgi.anything and use that as the socket then it will work perfectly. Keep in mind that since this is a temporary directory cleared on every boot, you should create the socket yourself at startup, usually with a tmpfiles.d configuration. For example:

p+ /run/wsgi.anything 0660 user group - -
Michael Hampton
  • 237,123
  • 42
  • 477
  • 940
2

The warning is there because you may be giving too much away. You allowing httpd to write to any socket in /var which may not be what you want.

The httpd_sys_content_t context only allows read access to a file unless you have enabled the httpd_unified boolean. If you want your socket to be writable by httpd you need to set it to be httpd_sys_rw_content_t

semanage fcontext -a -t httpd_sys_rw_content_t "/var/www/demo/out"
restorecon -Rv /var/www/demo/out

Michael Hampton will be along soon to correct me I'm sure

user9517
  • 114,104
  • 20
  • 206
  • 289
1

A selinux base type is a generic type which, when granted, allow access to a very significant portion of the underlying system. Enabling selinux access for var_t is almost equiparable to run the process unconfined.

From the blog of one of the selinux developer:

The thing we really want to stop is domains writing to BASE types. If I allow a confined domain to write to a BASE type like etc_t or usr_t, then a hacked system can attack other domains, since almost all other domains need to read some etc_t or usr_t content.

Files under /var/www/ are already labeled with httpd_sys_content_t; by relabeling it with the same label you change nothing. From what I remember, httpd_sys_content_t should be used for static HTML files rather than sockets. Try relabeling your socket with something as:

semanage fcontext -a -t httpd_var_run_t </your/socket/path>
restorecon -RF </your/socket/path>

You can read here for a similar problem.

shodanshok
  • 44,038
  • 6
  • 98
  • 162