Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SELinux wants APPEND not WRITE permission for Fedora/EPEL (RHEL, Centos) #2416

Closed
mortenstevens opened this issue Feb 14, 2019 · 26 comments
Closed
Labels
3rd Party Bug 3rd party bug

Comments

@mortenstevens
Copy link
Contributor

For Fedora and EPEL (RHEL, CentOS) we have some selinux related issues with the latest cacti 1.2.x series.

See: bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1644324

The biggest problem is that we cannot access the cacti logfile, because cacti 1.2.x uses write instead of append. Is it possible to use append for writing to cacti.log?

@netniV
Copy link
Member

netniV commented Feb 14, 2019

I'm not sure I follow why the change is required. When I setup CentOS 7, I applied the following for SELinux for my cacti installations which are under /usr/share/cacti/(site|develop|feature)/:

semanage fcontext -a -t httpd_sys_content_t "/usr/share/cacti(/.*)?"
semanage fcontext -a -t httpd_sys_rw_content_t "/usr/share/cacti/(.*)/((log|rra|resource|scripts|cache)(/.*)?)"
semanage fcontext -a -t httpd_sys_content_t "/usr/share/cacti/.*/.htaccess"
restorecon -R -v /usr/share/cacti

For your own package, you just need to replace /usr/share/cacti/.*/ with the correct path

@netniV netniV added the 3rd Party Bug 3rd party bug label Feb 14, 2019
@mortenstevens
Copy link
Contributor Author

@netniV
It's Fedora/RHEL specific. We can't use httpd_sys_content_t or httpd_sys_rw_content_t for files stored in /usr/share/*

That's the reason why we have some symlinks:
cache -> /var/lib/cacti/cache
cli -> /var/lib/cacti/cli
log -> /var/log/cacti/
rra -> /var/lib/cacti/rra
scripts -> /var/lib/cacti/scripts

For /var/log/cacti/* we have to use httpd_log_t and that's the problem, because we have to use append otherwise selinux doesn't allow writing to /var/log/cacti/cacti.log.

Overall, it should be better for security reasons to use append instead of write.

@netniV
Copy link
Member

netniV commented Feb 15, 2019

Then how are the files even able to be read by apache? Without the above, I was unable to get my cacti working from my git clone.

@mortenstevens
Copy link
Contributor Author

@netniV
If you install the RPM package, it will work for example:
yum install https://dl.fedoraproject.org/pub/epel/testing/7/x86_64/Packages/c/cacti-1.2.0-1.el7.noarch.rpm

If you're using git clone you should clone it to /var/www/ and then you can use httpd_sys_content_t and httpd_sys_rw_content_t for log|rra|resource|scripts|cache.

Anyway, for creating RPM packages for Fedora and Fedora-EPEL we have advanced requirements and cannot use /var/www.
The log files are stored in /var/log/cacti with httpd_log_t. By default, selinux doesn't allow apache to write on files with httpd_log_t context. That's the reason why I'm asking if we can change it from write to append?

@netniV
Copy link
Member

netniV commented Feb 15, 2019

The problem is, that's what we are doing. The file is opened in append mode, and then we write to it using the builtin PHP methods.

Another thing to consider is that cacti can also do the same when it comes to multiple pollers so I think the SELinux restrictions should be reviewed properly and possible even set as I have suggested for the cacti package. On remote pollers, the entire cacti folder would need to be httpd_sys_rw_content_t as it will synchronise all the PHP content

        if (($logdestination == 1 || $logdestination == 2) && read_config_option('log_verbosity') != POLLER_VERBOSITY_NONE) {
                /* echo the data to the log (append) */
                $fp = @fopen($logfile, 'a');

                if ($fp) {
                        $message = $prefix . $message;
                        @fwrite($fp, $message);
                        fclose($fp);
                }
        }

@mortenstevens
Copy link
Contributor Author

mortenstevens commented Feb 15, 2019

@netniV

You're right. I think it's another issue. Writing to the logfile via append is still possible with 1.2.x and selinux enabled.

Since 1.2.x there is a new feature that check's if write access is possible to cacti.log, right? Is it possible to redesign this to check if append accces is possible instead of write access? Otherwise you get this message with selinux enabled:

"System log file is not available for writing, please enable write access Log: /usr/share/cacti/log/cacti.log"

@netniV
Copy link
Member

netniV commented Feb 15, 2019

Ah, now that functionality is fairly new in functions.php:

function is_resource_writable($path) {
        if ($path{strlen($path)-1}=='/') {
                return is_resource_writable($path.uniqid(mt_rand()).'.tmp');
        }

        if (file_exists($path)) {
                if (($f = @fopen($path, 'r+'))) {
                        fclose($f);
                        return true;
                }
                return false;
        }

        if (($f = @fopen($path, 'w'))) {
                fclose($f);
                unlink($path);
                return true;
        }
        return false;
}

We only open in write mode ('w') if the file does not exist, which I don't see as wrong though could effectively be changed to 'a'. If it does exist, we use r+ (read plus write) because we shouldn't be trying to create a file which a+ would do.

Feel free to have a test yourself, if you believe it to work then create a pull request for us to review 👍

@mortenstevens
Copy link
Contributor Author

To clarify this: We have no problem with writing to cacti.log. Sorry for the confusion.

This check #1298 causes issues with selinux, because selinux doesn't allow this to check if write access is possible.

@netniV
Copy link
Member

netniV commented Feb 15, 2019

Wow, 1 second after I posted, you are hot on this today ;-)

@mortenstevens
Copy link
Contributor Author

@netniV

If it does exist, we use r+ (read plus write) because we shouldn't be trying to create a file which a+ would do.

All right. I think this is it and as you can see selinux blocks access to logfiles with httpd_log_t context:

type=AVC msg=audit(1550242972.602:384): avc: denied { write } for pid=1430 comm="php-fpm" name="cacti.log" dev="dm-0" ino=4326773 scontext=system_u:system_r:httpd_t:s0 tcontext=system_u:object_r:httpd_log_t:s0 tclass=file permissive=0

@mortenstevens
Copy link
Contributor Author

@netniV
if (($f = @fopen($path, 'a'))) {

if (($f = @fopen($path, 'a+'))) {

I have tested this. No selinux issues if we change it from r+ to a or a+
Should I create a pull request?

@netniV
Copy link
Member

netniV commented Feb 15, 2019

Does it work if the file does not exist?

@mortenstevens
Copy link
Contributor Author

mortenstevens commented Feb 15, 2019

@netniV

Yes, it works for me. A quick test:

  1. rm /var/log/cacti/cacti.log
  2. Open a browser and navigate to cacti

Result: It was able to create a new cacti.log file.

@netniV
Copy link
Member

netniV commented Feb 15, 2019

Cool. If you make that last change we can merge it later and you'll become a contributor (if you aren't already that is lol).

@netniV
Copy link
Member

netniV commented Feb 15, 2019

So, the code is now merged and you should be OK to close this now.

@mortenstevens
Copy link
Contributor Author

@netniV
Thank you. I think I'm able to fix most of the cacti selinux issues reported here: https://bugzilla.redhat.com/show_bug.cgi?id=1644324

But there is one last issue during the installation of cacti:

Cacti creates tmp files in the log directory, right?

Since we can only use httpd_log_t for logfiles the problem is that cacti cannot remove these files.

type=AVC msg=audit(1550328376.889:30666): avc: denied { remove_name } for pid=1138 comm="php-fpm" name="1585169355c682238d956b.tmp" dev="sda3" ino=39605439 scontext=system_u:system_r:httpd_t:s0 tcontext=system_u:object_r:httpd_log_t:s0 tclass=dir permissive=1
type=AVC msg=audit(1550328376.889:30667): avc: denied { unlink } for pid=1138 comm="php-fpm" name="1585169355c682238d956b.tmp" dev="sda3" ino=39605439 scontext=system_u:system_r:httpd_t:s0 tcontext=system_u:object_r:httpd_log_t:s0 tclass=file permissive=1

The solution could be: Use the cache directory for tmp files instead of the log directory? Is that possible?

@netniV
Copy link
Member

netniV commented Feb 16, 2019

No. The temporary files are there to specifically test that any file can be created in the directory. In fact, Cacti itself will rotate and remove logs if it’s enabled to do so, thus the limitation breaks that functionality too.

@mortenstevens
Copy link
Contributor Author

@netniV
All right. But this is not the best solution for SELinux enabled systems, because the log_directory should use httpd_log_t and not httpd_sys_rw_content_t.

@cigamit
Copy link
Member

cigamit commented Feb 21, 2019

@mortenstevens,

We have provided an option in config.php.dist to disable/hide the builtin Cacti log-rotation functionality so you can capture that setting in /etc/logrotate.d/cacti. So, if you incorporate that into the RPM scripts, I think we are safe.

@netniV
Copy link
Member

netniV commented Feb 21, 2019

Disabling that functionality doesn't stop the is_resource_writable() from creating temporary files though. I only mentioned the log rotating functionality as it is possible for someone to re-enable it if they messed with their config.php

@mortenstevens
Copy link
Contributor Author

@netniV
@cigamit

The last issue on SELinux enabled systems is only creating/deleting tmp files in the log directory. Since the log directory should use httpd_log_t the best way would be to use a tmp or cache directory for creating/deleting tmp files.

@netniV
Copy link
Member

netniV commented Feb 21, 2019

The code is a common function and uses tmp files to ensure that it isn't overwriting legitimate files. Plus, just because a directory has write permission doesn't mean the user can actually create/write files (as we have already witnessed above due to SELinux).

Additionally, the user is able to change the location and name of their logs, rrd's, etc and when doing so, we make sure that the location is writable.

@cigamit
Copy link
Member

cigamit commented Feb 23, 2019

Maybe we can get the value of getenforce during that function and if it's enforcing, assume we have write, and block the error in cases where that is not the case.

@netniV
Copy link
Member

netniV commented Feb 23, 2019

We can't assume we can write, that was half the issues we had in the past.

@netniV netniV changed the title selinux issues with cacti 1.2.x SELinux wants APPEND not WRITE permission for Fedora/EPEL (RHEL, Centos) Feb 24, 2019
@mortenstevens
Copy link
Contributor Author

mortenstevens commented Mar 7, 2019

@netniV
@cigamit

I'm not sure what's the best solution for this. The result is that we can write *.tmp files to the log directory (httpd_log_t) but httpd_log_t doesn't allow you to delete these tmp files.

The result is many *.tmp files in the log directory that have to be manually deleted by the user.
For example: ls /var/log/cacti/
10148015525c2f81407cec2.tmp
12029377195c2f83f9b305f.tmp
12393867025c68213260784.tmp
13153290865c682133de242.tmp
1365382775c682117a3e58.tmp
15127376425c68213290f09.tmp
15622356085c2f8428b27de.tmp
15974321625c2f83f9b2a44.tmp
16992076625c2f81405f03d.tmp
18140276095c6821d8f1b01.tmp
18274662785c682117c3299.tmp
1933165155c6821d92e805.tmp
1956086765c682117c2bd7.tmp
20557862355c2f8428cc1d8.tmp
21235666375c6821dac37ba.tmp
2501401085c6821da904f3.tmp
5264615365c6821341b42b.tmp
530427515c6821dac3b6d.tmp
5667156295c2f83f999097.tmp
723706085c2f81407c8b5.tmp
7388562715c2f8428cbb71.tmp
7678884185c68213291334.tmp
7836789455c6821d92e43f.tmp
8726300755c6821341b037.tmp

@netniV
Copy link
Member

netniV commented Mar 7, 2019

My only solution would be to not store the logs in a location that is forcing the use of http_log_t. Checking that we can actually create a file in a directory is vital and we do this by not trying to overwrite or append to a file that may exist since that provides no guarantee we can do it if that file is removed.

@cigamit cigamit added this to the 3rd Party milestone Mar 10, 2019
@netniV netniV closed this as completed Jun 9, 2019
@github-actions github-actions bot locked as resolved and limited conversation to collaborators Jun 30, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
3rd Party Bug 3rd party bug
Projects
None yet
Development

No branches or pull requests

3 participants