Bugzilla will be upgraded to version 5.0 on a still to be determined date in the near future. The original upgrade date has been delayed.
Bug 1382785 - webalizer run by cron has issues with SELinux in /var/www/usage
webalizer run by cron has issues with SELinux in /var/www/usage
Status: NEW
Product: Fedora
Classification: Fedora
Component: webalizer (Show other bugs)
27
x86_64 Linux
unspecified Severity medium
: ---
: ---
Assigned To: Sergio Monteiro Basto
Fedora Extras Quality Assurance
:
: 996305 1399501 1520587 (view as bug list)
Depends On:
Blocks: 1393066
  Show dependency treegraph
 
Reported: 2016-10-07 13:57 EDT by Vicente
Modified: 2018-07-16 14:51 EDT (History)
7 users (show)

See Also:
Fixed In Version:
Doc Type: If docs needed, set a value
Doc Text:
Story Points: ---
Clone Of:
Environment:
Last Closed:
Type: Bug
Regression: ---
Mount Type: ---
Documentation: ---
CRM:
Verified Versions:
Category: ---
oVirt Team: ---
RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: ---


Attachments (Terms of Use)

  None (edit)
Description Vicente 2016-10-07 13:57:43 EDT
Description of problem:
When webalizer is run as a cron job to analyze squid logs and generate the output in /var/www/usage, it does not work (it issues the error shown below). On the other hand, if webalizer is run manually as root, it runs OK and generates the expected output in /var/www/usage. In addition, if I change SELinux mode from enforcing to permissive, the cron job works as expected.


Log entries found in /var/log/cron (SELinux mode is enforcing):
Oct  7 09:55:01 proxy2 CROND[1137]: (root) CMD (run-parts /etc/cron.daily)
Oct  7 09:55:01 proxy2 run-parts[1137]: (/etc/cron.daily) starting 00webalizer
Oct  7 09:55:01 proxy2 CROND[1136]: (root) CMDOUT (/etc/cron.daily/00webalizer:)
Oct  7 09:55:01 proxy2 CROND[1136]: (root) CMDOUT ()
Oct  7 09:55:01 proxy2 CROND[1136]: (root) CMDOUT (Error: Can't change directory to /var/www/usage)
Oct  7 09:55:01 proxy2 run-parts[1137]: (/etc/cron.daily) finished 00webalizer


Log entries found in /var/log/audit/audit.log (SELinux mode is permissive):
type=AVC msg=audit(1475853301.494:183): avc:  denied  { getattr } for  pid=1063 comm="webalizer" path="/var/www/usage/daily_usage_201610.png" dev="dm-0" ino=
510047 scontext=system_u:system_r:webalizer_t:s0-s0:c0.c1023 tcontext=unconfined_u:object_r:webalizer_rw_content_t:s0 tclass=file permissive=1

type=AVC msg=audit(1475853301.495:184): avc:  denied  { write } for  pid=1063 comm="webalizer" name="daily_usage_201610.png" dev="dm-0" ino=510047 scontext=s
ystem_u:system_r:webalizer_t:s0-s0:c0.c1023 tcontext=unconfined_u:object_r:webalizer_rw_content_t:s0 tclass=file permissive=1

type=AVC msg=audit(1475853301.495:185): avc:  denied  { open } for  pid=1063 comm="webalizer" path="/var/www/usage/daily_usage_201610.png" dev="dm-0" ino=510
047 scontext=system_u:system_r:webalizer_t:s0-s0:c0.c1023 tcontext=unconfined_u:object_r:webalizer_rw_content_t:s0 tclass=file permissive=1



Version-Release number of selected component (if applicable):
Source RPM  : webalizer-2.23_08-3.fc24.src.rpm
Source RPM  : selinux-policy-3.13.1-191.16.fc24.src.rpm
Source RPM  : squid-3.5.20-1.fc24.src.rpm
Source RPM  : httpd-2.4.23-4.fc24.src.rpm
Source RPM  : kernel-4.7.3-200.fc24.src.rpm



How reproducible:
100%



Steps to Reproduce:
1. Install and upgrade required packages with dnf:
dnf upgrade
dnf install squid
dnf install webalizer

2. Configure services as needed (squid, httpd, webalizer)
vi /etc/webalizer.conf
   #LogFile        /var/log/httpd/access_log
   LogFile        /var/log/squid/access.log
   LogType         squid

3. Start and enable services
systemctl start squid.service
systemctl enable squid.service
systemctl start httpd.service
systemctl enable httpd.service

4. Enable webalizer in cron
vi /etc/sysconfig/webalizer
WEBALIZER_CRON=yes

vi /etc/crontab
35 10 * * * root run-parts /etc/cron.daily

cat /etc/cron.daily/00webalizer
#!/bin/bash
NAME=webalizer
[ -f /etc/sysconfig/$NAME ] || exit 0
source /etc/sysconfig/$NAME
[ "z$WEBALIZER_CRON" != "zyes" ] && exit 0
exec /usr/bin/webalizer -Q



Actual results:
Failure to run by cron as noted above unless SELinux changed to permissive or run manual.

Expected results:
Should run as a cron job with SELinux mode is enforcing.

Additional info:
# ls -laZ /var/www
drwxr-xr-x.  5 root      root system_u:object_r:httpd_sys_content_t:s0       46 Sep 22 18:57 .
drwxr-xr-x. 22 root      root system_u:object_r:var_t:s0                   4096 Oct  7 10:30 ..
drwxr-xr-x.  2 root      root system_u:object_r:httpd_sys_script_exec_t:s0    6 Jul 18 10:47 cgi-bin
drwxr-xr-x.  2 root      root system_u:object_r:httpd_sys_content_t:s0        6 Jul 18 10:47 html
drwxr-xr-x.  2 webalizer root system_u:object_r:webalizer_rw_content_t:s0  4096 Oct  3 18:06 usage

# ls -laZ /var/www/usage
drwxr-xr-x. 2 webalizer root system_u:object_r:webalizer_rw_content_t:s0      4096 Oct  3 18:06 .
drwxr-xr-x. 5 root      root system_u:object_r:httpd_sys_content_t:s0           46 Sep 22 18:57 ..
-rw-r--r--. 1 root      root unconfined_u:object_r:webalizer_rw_content_t:s0  2330 Sep 30 10:21 ctry_usage_201609.png
-rw-r--r--. 1 root      root unconfined_u:object_r:webalizer_rw_content_t:s0  2771 Oct  7 10:15 ctry_usage_201610.png
-rw-r--r--. 1 root      root unconfined_u:object_r:webalizer_rw_content_t:s0  2576 Sep 30 10:21 daily_usage_201609.png
-rw-r--r--. 1 root      root unconfined_u:object_r:webalizer_rw_content_t:s0  2796 Oct  7 10:15 daily_usage_201610.png
-rw-r--r--. 1 root      root unconfined_u:object_r:webalizer_rw_content_t:s0  1692 Sep 30 10:21 hourly_usage_201609.png
-rw-r--r--. 1 root      root unconfined_u:object_r:webalizer_rw_content_t:s0  1864 Oct  7 10:15 hourly_usage_201610.png
-rw-r--r--. 1 root      root unconfined_u:object_r:webalizer_rw_content_t:s0  4235 Oct  7 10:15 index.html
-rw-r--r--. 1 webalizer root system_u:object_r:webalizer_rw_content_t:s0      1478 Mar 21  2008 msfree.png
-rw-r--r--. 1 root      root unconfined_u:object_r:webalizer_rw_content_t:s0 48691 Sep 30 10:21 usage_201609.html
-rw-r--r--. 1 root      root unconfined_u:object_r:webalizer_rw_content_t:s0 59716 Oct  7 10:15 usage_201610.html
-rw-r--r--. 1 root      root unconfined_u:object_r:webalizer_rw_content_t:s0  2264 Oct  7 10:15 usage.png
-rw-r--r--. 1 webalizer root system_u:object_r:webalizer_rw_content_t:s0      1253 Mar 21  2008 webalizer.png
Comment 1 Vicente 2016-10-18 11:28:48 EDT
I reproduced from scratch, and after the first run of webalizer with SElinux set to permissive, I get the following audit:

type=AVC msg=audit(1476779941.922:242): avc:  denied  { write } for  pid=1867 comm="webalizer" name="usage" dev="dm-0" ino=16807402 scontext=system_u:system_r:webalizer_t:s0-s0:c0.c1023 tcontext=system_u:object_r:webalizer_rw_content_t:s0 tclass=dir permissive=1

type=AVC msg=audit(1476779941.922:243): avc:  denied  { add_name } for  pid=1867 comm="webalizer" name="daily_usage_201610.png" scontext=system_u:system_r:webalizer_t:s0-s0:c0.c1023 tcontext=system_u:object_r:webalizer_rw_content_t:s0 tclass=dir permissive=1

type=AVC msg=audit(1476779941.923:244): avc:  denied  { create } for  pid=1867 comm="webalizer" name="daily_usage_201610.png" scontext=system_u:system_r:webalizer_t:s0-s0:c0.c1023 tcontext=system_u:object_r:webalizer_rw_content_t:s0 tclass=file permissive=1

type=AVC msg=audit(1476779941.923:245): avc:  denied  { write open } for  pid=1867 comm="webalizer" path="/var/www/usage/daily_usage_201610.png" dev="dm-0" ino=16807408 scontext=system_u:system_r:webalizer_t:s0-s0:c0.c1023 tcontext=system_u:object_r:webalizer_rw_content_t:s0 tclass=file permissive=1

type=AVC msg=audit(1476779941.923:246): avc:  denied  { getattr } for  pid=1867 comm="webalizer" path="/var/www/usage/daily_usage_201610.png" dev="dm-0" ino=16807408 scontext=system_u:system_r:webalizer_t:s0-s0:c0.c1023 tcontext=system_u:object_r:webalizer_rw_content_t:s0 tclass=file permissive=1
Comment 2 Fedora Admin XMLRPC Client 2016-11-16 03:29:29 EST
This package has changed ownership in the Fedora Package Database.  Reassigning to the new owner of this component.
Comment 3 Sergio Monteiro Basto 2016-12-01 18:57:06 EST
*** Bug 996305 has been marked as a duplicate of this bug. ***
Comment 4 Sergio Monteiro Basto 2017-02-19 21:01:54 EST
Vicent , have you any solution for this bug ? i.e. what we need to run to work with selinux enabled, sorry but I disable selinux by default.
Comment 5 Joel C Ewing 2017-02-20 00:37:36 EST
The fix seems so obvious I don't understand why it hasn't been implemented.   

The /var/www/usage directory is the default target for webalizer output.  The default fcontext for that directory and files is webalizer_rw_content_t , which by its name is obviously intended to be writable by webalizer.  Webalizer under cron runs as webalizer_t.  Obviously webalizer_t should be able to read/create/update files and directories that are webalizer_rw_content_t, but there are no rules defined to allow that.
sesearch -s webalizer_t -t webalizer_rw_content_t -SA
shows there are no access rules (this is in f25, but has been that way at least since f22)
sesearch -s webalizer_t -t httpd_sys_content_t -SA
shows that there are rules giving webalizer_t read/write access to files and directories with that context, which is much wider access than webalizer_t needs.  Obviously the rules people and file context people are not talking to each other.

A circumvention is to either define local rules to add the access to webalizer_t, or an easier  circumvention is to just change the file context of everything in  /Var/www/usage directory and below to something that works by either (as su)

chcon -R -t httpd_sys_content_t  /var www/usage

 or more permanently (so it won't be undone by restorecon) by

semanage fcontext -a -t httpd_sys_content_t  '/var/www/usage(/.*)?'
restorecon -R -v /var/www/usage        (-v to show what it changes)

but I see no reason why this circumvention should still be required!  The supplied policy definitions should fix this by the cleaner solution of granting the necessary authority to webalizer_t to actually allow the read/write authority to webalizer_rw_content_t that webalizer_t was obviously intended to have.  I would suggest the specific rules but I am not confident that I understand the syntax and semantics of policy rules well enough to do that.
Comment 6 Joel C Ewing 2017-02-20 01:15:22 EST
Also, this is not really a duplicate of 996305.  While that is also most certainly an SELinux issue, it is a different problem and requires a different circumvention.

  If you create an /etc/webalizer/ directory with multiple webalizer conf files as suggested by webalizer documentation for multiple invocations, the default context that will be assigned to /etc/webalizer and the files below is etc_t .  In order for the  webalizer script and webalizer running under cron to access the conf files they must be  changed to webalizer_etc_t  by a similar technique to above (but be careful if you go the semange route because the directory MUST remain etc_t in order to be accessible by both the cron 00webalizer script and webalizer itself).  Something like the following (note subtle pattern change to exclude directory)

semanage fcontext -a -t webalizer_etc_t  '/etc/webalizer/(.+)'
restorecon -R -v /etc/webalizer/*
   or again one could just use chcon for a less permanent change

And in addition, when using conf files under /etc/webalizer/ be sure to rename or otherwise get rid of the original /etc/webalizer.conf file or webalizer will attempt to use that IN ADDITION TO whatever conf files 00webalzer explicitly supplies as parameter.  Probably not what you want.

If you try any thing too elaborate within the 00webalizer cron script, one needs to be aware that it runs in system_cronjob_t and only the actual webalizer execution within it runs in context webalizer_t, so the cron script itself does not have the same directory and file access as the webalizer program itself running under the cron script.

Having just jumped to f25 in the last several days and having to re-visit all of these webalizer issues, they are painfully fresh in my mind.

Since the use of a webalizer directory with multiple files is the recommended way for multiple webalizer executions under a single 00webalizer, the supplied SELinux rules should be changed to map things under, but not including, the directory /etc/webalizer to webalizer_etc_t .
Comment 7 Sergio Monteiro Basto 2017-02-22 12:44:02 EST
Hi, 

(In reply to Joel C Ewing from comment #5)
> The fix seems so obvious I don't understand why it hasn't been implemented. 

Can you resume (preferably in a patch to webalizer.spec) what we need to add to webalizer.spec ? 

Thanks
Comment 8 Joel C Ewing 2017-02-22 19:27:26 EST
I have no experience with packaging specifications, only with what is visible from the user side after install so I can't translate the requirements as I see them into .spec changes  .

I can diagnose what's missing by looking at assigned file contexts and assigned running context and by using sesearch to see what kind of access rules appear to be present or absent, but I'm not an se policy development expert and have no idea how that translates into packaging changes or policy access rules.

I would think that given my semanage circumvention
semanage fcontext -a -t webalizer_etc_t  '/etc/webalizer/(.+)'

and the knowledge that at a minimum
Webalizer_rw_content_t directories need
read/write/update/search by webalizer_t
read/search by apache httpd (httpd_t ?)

and webalizer_rw_content_t files need
read/write/create by webalizer_t
read by apache httpd

Someone with real se policy development experience should be able get a start on what is needed.  I suspect some other authority grants would need to be cloned for webalizer_rw_content_t from those rules that cover httpd_sys_content_t if some of those apply to processes that scan all httpd files or all files in the filesystem.  If in doubt, one could just clone all the httpd_sys_content_t permits to apply to webalizer_rw_content_t, but sounds like that would be overkeill and a non-optimum solution.

My other semanage command defines a file context change that is only needed if the policy rules for access aren't fixed, and fixing the rules seems like the logical way to go.
Comment 9 Sergio Monteiro Basto 2017-02-22 20:00:44 EST
Hi, Joel 

I don't want understand selinux , I just want that you list me what we need to run :

semanage fcontext -a -t webalizer_etc_t  '/etc/webalizer/(.+)'
restorecon -R -v /etc/webalizer/*

anything else ? please just send sh commands
Comment 10 Joel C Ewing 2017-02-23 09:47:30 EST
This bug was cross referenced with bug #1399501 under selinux-policy.  I have no idea whether it is appropriate to run semanage from a .spec script or not, but strongly suspect running that restorecon would also require webalizer package to first create the /etc/webalizer directory, which at this point is only created by the user as part of cron-webalizer customization.  

These are questions that should be asked of selinux-policy or fedora packaging experts, and I am neither, only a sophisticated fedora user with 30+ yrs comp sci, mainframe z/OS sys prog experience.

SELinux has been around long enough there obviously needs to be more application development awareness -- at least enough to know whether an selinux security issue should be addressed by the application support or by selinux-policy support.  I'm still not sure myself, but maybe if an selinux-policy developer looks at this, between the two groups someone can figure that out.
Comment 11 Fedora End Of Life 2017-07-25 19:23:48 EDT
This message is a reminder that Fedora 24 is nearing its end of life.
Approximately 2 (two) weeks from now Fedora will stop maintaining
and issuing updates for Fedora 24. It is Fedora's policy to close all
bug reports from releases that are no longer maintained. At that time
this bug will be closed as EOL if it remains open with a Fedora  'version'
of '24'.

Package Maintainer: If you wish for this bug to remain open because you
plan to fix it in a currently maintained version, simply change the 'version'
to a later Fedora version.

Thank you for reporting this issue and we are sorry that we were not
able to fix it before Fedora 24 is end of life. If you would still like
to see this bug fixed and are able to reproduce it against a later version
of Fedora, you are encouraged  change the 'version' to a later Fedora
version prior this bug is closed as described in the policy above.

Although we aim to fix as many bugs as possible during every release's
lifetime, sometimes those efforts are overtaken by events. Often a
more recent Fedora release includes newer upstream software that fixes
bugs or makes them obsolete.
Comment 12 Jan Kurik 2017-08-15 05:33:46 EDT
This bug appears to have been reported against 'rawhide' during the Fedora 27 development cycle.
Changing version to '27'.
Comment 13 Sergio Monteiro Basto 2017-08-20 12:50:34 EDT
*** Bug 1399501 has been marked as a duplicate of this bug. ***
Comment 14 Sergio Monteiro Basto 2017-11-06 10:33:23 EST
I have a project in work that I have SELinux enabled, so I started understand a little more of SELinux 

for reference : 
https://forums.fedoraforum.org/showpost.php?p=1537563&postcount=3 

@Joel C Ewing please can you summarize what you wrote ? , you wrote too much for me , that something don't work but should work and may work doesn't matter to me , I just want to know what I should add to webalizer.spec in code or as a patch, don't want know the reason ! 

Thanks.
Comment 15 Joel C Ewing 2017-11-06 18:13:25 EST
Again repeating that I know very little about Fedora packaging conventions; but a 5 minute search at least turns up a reference that suggests that it is possible to incorporate an "semanage" command into spec scripts, which suggests that a circumvention to the problem might be afforded by including in a spec script

semanage fcontext -a -t httpd_sys_content_t  '/var/www/usage(/.*)?'
restorecon -R  /var/www/usage 
semanage fcontext -a -t webalizer_etc_t  '/etc/webalizer/(.+)'
restorecon -R  /etc/webalizer/*

(That last command might fail if directory /etc/webalizer hasn't already been created, but if the directory doesn't exist, it can't have any incorrect selinux attributes and the restorecon is not needed)
   ---- end of executive summary ----

But again, this is a jerry rigged solution that doesn't really address the underlying problem; and it is impossible to appreciate that without further explanation. 

Webalizer doesn't need and probably shouldn't have the ability to change any arbitrary http served content beyond its own /var/www/usage directory.  Someone obviously started to fix that unnecessary exposure by creating file context webalizer_rw_content_t with the implied intent that webalizer would only be allowed to update that context under /var/wwww, but the project was left incomplete with things in a broken state.

Someone went to all the effort to create the definitions that are in package selinux-policy-targeted for the run type webalizer_t and the file context type webalizer_rw_content_t and assign the latter by default to /var/www/usage and  make cron-initiated webalizer processes run as webalizer_t; but no policy rules were included to actually allow a run context of webalizer_t the authority to read & write files and directories with file context webalizer_rw_content_t, despite the fact that file-context naming conventions definitely implies that was the whole intent of defining the new file context type! 

Someone, either from selinux or webalizer (or maybe even cron?) development, had to have been involved in setting up these definitions, but now no one will fess up or assume responsibility for seeing that the partial definitions that are included with selinux-policy-targeted are completed.  To fix things right requires not just file context changes, but selinux policy module changes to change file access rules.   I have looked at policy definitions just enough to know that while I can make educated guesses, I don't understand the syntax or semantics of the policy statements well enough to give advise on creating an selinux policy module for webalizer.  I can describe what is logically required, but know that I am not currently qualified to write actual code for a valid policy definition.

It is unclear to me whether it is legit to somehow include selinux policy modules within a package, or, if it is possible, just how that would react with rules already in selinux-policy-targeted.

Webalizer can for now circumvent the problem via semanage kludges at the package level, but it really seems like selinux-policy-targeted imbedded support for webalizer must eventually be changed -- and of course selinux says that webalizer developers should drive that.  Based on the years it has taken just to just get this far, I don't see that happening unless someone who is active with webalizer development will also decide to become active on selinux-policy-targeted development and become familiar with their conventions enough to submit revised selinux definitions for webalizer.
Comment 16 Sergio Monteiro Basto 2017-12-06 06:11:59 EST
*** Bug 1520587 has been marked as a duplicate of this bug. ***
Comment 17 Joel C Ewing 2018-07-16 14:51:58 EDT
Finally had a chance to revisit this on f27.  After getting a little more understanding of selinux custom module definitions using .te files, the closest to a better circumvention seems to be hinted to in  bug #1399501, which is closed as a duplicate of this bug.   It proposes definitions for creating a custom selinux module, but trying the suggested definitions didn't appear to be sufficient to fix the problem on my f27 system, possibly because there are added requirements after the initial running of webalizer.  However, by comparing with the access permissions granted to webalizer_t for access to http_sys_content_t directories & files (a context that was used in the past as a circumvention) and adding some of the same permissions for webalizer_rw_content_t in a  file my_webalizer.te, I finally got a working definition file after three iterations (which is why my customization file is at version "3.0"):
 
          ---------my_webalizer.te file first line below---------------
module my-webalizer 3.0;
require {
        type webalizer_t;
        type webalizer_rw_content_t;
        class dir { open read write  search add_name remove_name getattr setattr lock };  
        class file { open create read write append rename getattr setattr lock link unlink};
#file { unlink } needed for webalizer.hist file
}
#============= webalizer_t ==============
allow webalizer_t webalizer_rw_content_t:dir { open read write  search add_name remove_name getattr setattr lock };
allow webalizer_t webalizer_rw_content_t:file { open create read write append rename getattr setattr lock link unlink};
             ----------follows my_webalizer.te last line------------------

The permissions in the above definitions appear to be sufficient for webalizer to run, but there could be some that are not necessary.

As su, that .te definition file may be compiled to a .mod file, a .pp file generated, and installed via following steps (may require setools package):

cd <directory containing the te file>
checkmodule -M -m -o my-webalizer.mod my-webalizer.te
semodule_package -o my-webalizer.pp -m my-webalizer.mod
semodule -i my-webalizer.pp

The successful installation can be confirmed by listing active definitions for webalizer running under cron as webalizer_t to webalizer_rw_content_t with
sesearch -s webalizer_t -t webalizer_rw_content_t -A

This change allows webalizer to run under cron using the default se context assignments to /var/www/usage directory and its content.

Still don't know enough about packaging conventions to know how to integrate these definitions into the webalizer package, but this is a cleaner circumvention than just changing the file and directory context of /var/www/usage content from the default "webalizer_rw_content_t" to "httpd_sys_content_t.  If these new allow rules could be integrated into the webalizer package, that would also allow some future change (no idea by whom) to deny webalizer running as webalizer_t from updating other web content not classified as webalizer_rw__content_t, as webalizer should have no need to update any web content other than that under /var/www/usage .

There are still [previously mentioned] issues with the default selinux context assignment and access rules when making multiple webalizer runs under cron using the documented approach with multiple configuration files under an /etc/webalizer directory.  Those issues may still need a new file context rule or other changes to access rules to resolve; but that is a separate issue and only affects those needing multiple webalizer runs using different conf files.

Note You need to log in before you can comment on or make changes to this bug.