caddyserver / dist

Resources for packaging and distributing Caddy
Apache License 2.0
116 stars 118 forks source link

Investigate whether SELinux rules need to be added for rpm #95

Closed francislavoie closed 1 year ago

francislavoie commented 1 year ago

I'm opening this up as followup from mentioning this in Slack.

We've had some users in the forums recently that got snagged on SELinux rules preventing the caddy user from reading/writing files in /var/www/html and /var/log/caddy.

Is there anything that can be done in the .rpm to smooth this over?

carlwgeorge commented 1 year ago

The RPM has had the necessary SELinux booleans, file contexts, and ports configured since the beginning.

https://github.com/caddyserver/dist/blob/ee5797ca8886d135b21b6487565ccfdd830cc743/rpm/caddy.spec#L71-L92

There are several other things that can cause an SELinux denial. I just ran into a case of it when caddy-2.6.4-1 from the copr enabled PrivateDevices in the unit file. I've reverted that and am rebuilding the package now.

francislavoie commented 1 year ago

Copying the debug steps recommended by @carlwgeorge in our conversation in Slack (with a bit of editorial adjustments from me):


If you see questions on the forum or wherever that you suspect might be SElinux related, the basic steps to give users are:

  1. Run getenforce to check if SElinux is enforcing, permissive, or off
  2. If something isn't working and SElinux is enforcing, temporarily switch it to permissive with setenforce 0
  3. If the thing you were doing works now, SElinux is indeed blocking it. If it still behaves the same way, it's something else.
  4. Turn SElinux back to enforcing with setenforce 1

A good command to run to find denials is ausearch -m avc -c caddy. That will inject easy timestamps and only show what you're looking for. This searches through the /var/log/audit/audit.log log file.

Example denial:

type=AVC msg=audit(1676699621.345:8536): avc:  denied  { read } for  pid=4413 comm="caddy" name="rhelish.ius.io.key" dev="xvda1" ino=1052117 scontext=system_u:system_r:init_t:s0 tcontext=system_u:object_r:httpd_var_lib_t:s0 tclass=file permissive=0

I think what my example is saying is that SElinux stopped the source context (scontext) (the caddy binary) from accessing the target context (tcontext) (the key file) because of a type mismatch (init_t vs httpd_var_lib_t).

The caddy binary has a context of httpd_exec_t outside of the systemd isolation, and selinux allows going from httpd_exec_t to httpd_var_lib_t. In this case, I think PrivateDevices is changing the scontext to init_t.

A common denial I see with caddy is name="somaxconn" going from scontext=system_u:system_r:httpd_t:s0 to tcontext=system_u:object_r:sysctl_net_t:s0. I'm not sure why it does it, but it's done it for a long time and it doesn't seem to stop any functionality. Seeing that in the ausearch output is normal and can probably be ignored. At some point we may need to write a policy to allow that behavior by default.

splashsky commented 1 year ago

While clearly @carlwgeorge has pointed out all the markers are there, this still seems to be an infrequent but annoying issue to troubleshoot. Is there a permanent way to fix SELinux permissions so that Caddy works as intended every time?

I've installed this on a live Rocky 9 server with no problems, but ran into SELinux roadblocks on a local installation.

francislavoie commented 1 year ago

@splashsky can you share more detail than that? Nothing we can do without specifics. Did you try the steps outlined above? What did you see?

splashsky commented 1 year ago

I followed the above debug steps and found the example denial:

type=AVC msg=audit(1676699621.345:8536): avc:  denied  { read } for  pid=4413 comm="caddy" name="rhelish.ius.io.key" dev="xvda1" ino=1052117 scontext=system_u:system_r:init_t:s0 tcontext=system_u:object_r:httpd_var_lib_t:s0 tclass=file permissive=0

My installation as as minimal as possible:

After following the above debug and seeing the example denial, I tested using setenforce 0 and used systemctl restart caddy, at which point the server responded as expected with both the HTML and PHP pages. It began erroring again after using setenforce 1.

Afterwards, I found this guide from Linode and executed these commands on the /srv/www directory:

sudo chcon -t httpd_sys_content_t /var/www/example.com -R
sudo chcon -t httpd_sys_rw_content_t /var/www/example.com -R

And restarted Caddy once again using systemctl. It now works as expected.

francislavoie commented 1 year ago

I followed the above debug steps and found the example denial:

You just copy-pasted that from above. What did you see specifically?

carlwgeorge commented 1 year ago

@splashsky I can't tell for sure without seeing your actual denial message (not the example one), but if I'm following you correctly things started working for you after you set the appropriate selinux context on your web content in /var/www/example.com (or some similar directory that you're masking from us). The caddy packages can't do that for you because everyone's content directory is going to be different. It's standard practice while administering an selinux-enabled machine that you need to validate the context of your own files that aren't owned by packages.

carlwgeorge commented 1 year ago

Nothing to do here, the caddy RPM already handles everything SELinux wise that it can.

dennislapchenko commented 8 months ago

@splashsky Thanks, that instantly worked.