SELinux config for Django, Apache, MariaDB, Fedora38 stack

Ok, I’m coming here after properly watching Thomas Cameron’s lecture on SELinux and reading some other resources. Security-Enhanced Linux for mere mortals - YouTube

I’m running Fedora 38 workstation inside a Vmware Workstation Pro (v17), with the rest of my stack being Apache, MariaDB, Python.

I have Django up and running on localhost:8000, I followed the configuration for mod-wsgi, Apache, Django properly. I have a virtualhost file to run my Django app on localhost:80 as well.

But I kept getting 500 internal server error. Turns out its a SELinux issue, since I did setenforce 0, and everything works fine.

Now I’m trying to troubleshoot whatever is making SELinux upset, so that I can turn it back on enforcing again. Its a local test server.

Please bear in mind that Fedora Documentation (new as well as the wiki) is still lacking significantly on this topic. So I couldn’t get much over there. Nor there is anything related to SELinux on Django documentation.

I have setroubleshoot & setroubleshoot-server installed. Haven’t been able to pinpoint the issue so far. I would appreciate if anyone can help me find what is causing the issue.

here is the paste of my terminal output on sudo sealert -a /var/log/audit/audit.log

and this is when I do `sudo ausearch -i -m AVC (-ts recent gave me no results)

For starters, your sealert log gives you some specific suggestions as to what to do.

Both the alert and ausearch output implies that your configuration is trying to run php - if that’s not desired, you probably want to remove that from your configuration.

Yes, SELinux is a pain. But it all can be made to work. (Fortunately for me, I stopped working in a RedHat environment about 11 years ago now.) Get rid of everything php-related if you don’t need it, and work through the messages as they appear.

Hmm, for organizing things, in above image, you can see I have shortened the messages in auditlog to 11 things.

  1. The boolean “httpd_can_network_connect” is the first option. However the information on this boolean itself is pretty vague & some serious concern is there.

Lets look at the definition on RedHat docs:
“When disabled, this Boolean prevents HTTP scripts and modules from initiating a connection to a network or remote port. Enable this Boolean to allow this access.”

Source: 13.3. Booleans Red Hat Enterprise Linux 7 | Red Hat Customer Portal

Definition from Dan Welsh blog is a bit better imho:
Allow HTTPD scripts and modules to connect to the network using TCP.

Turning on the httpd_can_network_connect boolean, allows the httpd_t domain to connect to ALL tcp network ports.

Bottom Line httpd_can_network_connect_db allows httpd_t to connect to an additional 10 ports while httpd_can_network_connect adds thousands.

Source: How do I tell what would be allowed by a boolean? - Dan Walsh's Blog — LiveJournal

So now the concern arises, are we opening it up a bit too much?

From Ubuntu Man pages:
SELinux policy can be setup such that httpd scripts are not allowed to connect out to the
network. This would prevent a hacker from breaking into you httpd server and attacking
other machines. If you need scripts to be able to connect you can set the
httpd_can_network_connect boolean on.

Source: Ubuntu Manpage: httpd_selinux - Security Enhanced Linux Policy for the httpd daemon

& also this answer by Danila Vershinin on StackExchange-ServerFault
A lot. As you may have guessed it allows httpd_t to talk to any remote servers. There is no specification for which website it is, and it can be a malicious one.

Source: centos - How much does httpd_can_network_connect being set to 1 actually open up on SELinux - Server Fault

Comment: So at his point, the question is whether its really a good idea to do go with this option?

  1. The second option is “httpd_graceful_shutdown”. One of the most vaguely defined booleans.

Dan Welsh’s definition:
httpd_graceful_shutdown Allow HTTPD to connect to port 80 for graceful shutdown

Source: SELinux Apache Security Study - Dan Walsh's Blog — LiveJournal

Better Definition found in some other places:
httpd_graceful_shutdown as that allows Apache to connect to any TCP port labeled http_port_t (80, 81, 443, 488, 8008, 8009, 8443, 9000), and nothing else.(can be proven using sesearch)

Source: I need some clarification on the httpd_graceful_shutdown SELinux boolean - Fedora Discussion

Comment: See the above Link specially, it seems like a bad naming. So a bit more limiting compared to httpd_can_connect_network that opens up thousands of ports, but still seems a bit off, since why would apache be connecting to itself using a port?

  1. Third option is “httpd_can_network_relay”

Again, vague definition on Redhat site:
Enable this Boolean when httpd is being used as a forward or reverse proxy.

Source: 13.3. Booleans Red Hat Enterprise Linux 7 | Red Hat Customer Portal

Dan Welsh to rescue:
httpd_can_network_relay → Allows apache to connect to “apache” ports

sesearch -A -b httpd_can_network_relay -s httpd_t -p name_connect
Found 7 semantic av rules:
allow httpd_t squid_port_t : tcp_socket name_connect ;
allow httpd_t memcache_port_t : tcp_socket name_connect ;
allow httpd_t gopher_port_t : tcp_socket name_connect ;
allow httpd_t ephemeral_port_type : tcp_socket name_connect ;
allow httpd_t ftp_port_t : tcp_socket name_connect ;
allow httpd_t http_cache_port_t : tcp_socket name_connect ;
allow httpd_t http_port_t : tcp_socket name_connect ;

Source1: Small customizations to policy. - Dan Walsh's Blog — LiveJournal
Source2: How do I tell what would be allowed by a boolean? - Dan Walsh's Blog — LiveJournal

Comment: As you can see, a lot wider then httpd_graceful_shutdown, but narrower then httpd_can_network_connect

  1. Fourth option is “nis_enabled”

Unlikely one, as its related to Network Information Services (NIS), and we are not using it. But I must remark, in many man pages, its not even written what nis stands for here. That should be improved imho (saying with due respect as suggestion).

Dan Welsh coming, make way… XD
nis_enabled should only be used in an NIS environment, since it is really loose.

Source: How do I tell what would be allowed by a boolean? - Dan Walsh's Blog — LiveJournal

  1. Fifth option is “php-fpm should be allowed name_connect on port 443”

Following the pattern on Dan Welsh’s blogpost on a similar case here: Share Certs Data into a container.: danwalsh — LiveJournal and by looking at our logs, it seems that httpd_t is trying to connect to http_port_t on port 443

Now strange thing is that I haven’t setup any HTTPS for which the default port is 443. Nor my virtual host file or httpd.conf has anything related to port 443. Strange indeed. I could be wrong on this one, but thats all I can deduce for now.

  1. Sixth option is related to logs in a custom location.

Now in all honestly, when in my virtualhost file, I try to set set the Error & Access log position to anything except the default location of logs in Fedora, I was getting errors when running apachectl configtest *earlier (but not anymore). This might be an old error

This is my current virtual host file (notice the location of Error & Access Logs compared to my Auditlog messages): hastebin

  1. Seventh option is labelling related “httpd_unified” … which basically just combines all httpd_ file type label into one, it used to be enabled earlier for ease of new users, but its best practice now to keep it disabled

Dan Welsh’s opinion:
Most likely the only issue you would have with turning it off, would be changing the labels on any content the web service wants to write, to http_sys_content_rw_t.

Source: Security Vs Usability - Dan Walsh's Blog — LiveJournal

No. 8 to 11 are again related to logs. I just checked again, the folder exist, but the actual log file doesn’t yet. Is this possibly causing it? Or can the system generate the file itself, when any log content is generated?

Currently though the file doesn’t exist, but label is “httpd_sys_content_t”. Perhaps all that is needed is to create a file and change its context to “httpd_sys_content_rw_t” ?

Btw in the meantime I have tried to ask in Fedora IRC/Matrix Server as well in Django discord/Matrix (the matrix server is awfully quiet despite having 5600+ members, its strange, anyone have any idea?) to no avail … at least haven’t recieved any replies yet.