3

I have set up SELinux on a Debian squeeze system, which runs a Joomla website. The Joomla PHP code wants to have write access to certain cache directories.

The /var/log/messages file contains entries like these:

Dec 31 10:26:16 s0022 kernel: [ 2116.423199] type=1400 audit(1356945976.634:14831): 
  avc:  denied  { write } for  pid=1886 comm="apache2" name="_system" dev=xvda3 
  ino=790893 scontext=system_u:system_r:httpd_t:s0
  tcontext=unconfined_u:object_r:httpd_t:s0 tclass=dir
Dec 31 10:26:16 s0022 kernel: [ 2116.447613] type=1400 audit(1356945976.658:14837): 
  avc:  denied  { write } for  pid=1886 comm="apache2" name="mod_mainmenu" dev=xvda3
  ino=791346 scontext=system_u:system_r:httpd_t:s0
  tcontext=unconfined_u:object_r:httpd_t:s0 tclass=dir

The directories corresponding to the inode values are writeable by apache2 (running as wwwrun). The cache files are created when SELinux is turned off but not when it is activated. The path to these directories is however different from Debian Squeeze's default DocumentRoot.

# ls -ldZ cache cache/_system cache/mod_mainmenu
drwxrwxr-x. 5 wwwrun www unconfined_u:object_r:httpd_t:s0 4096 Dec 29 23:13 cache
drwxrwxr-x. 2 wwwrun www unconfined_u:object_r:httpd_t:s0 4096 Dec 30 19:31 cache/mod_mainmenu
drwxrwxr-x. 2 wwwrun www unconfined_u:object_r:httpd_t:s0 4096 Dec 30 19:31 cache/_system

I also tried enabling write related boolean flags, but that did not help either:

# getsebool -a | grep httpd
allow_httpd_anon_write --> on
allow_httpd_mod_auth_pam --> off
allow_httpd_sys_script_anon_write --> on
allow_httpd_user_script_anon_write --> on
httpd_builtin_scripting --> off
httpd_can_network_connect --> off
httpd_can_network_connect_db --> on
httpd_can_network_relay --> off
httpd_can_sendmail --> off
httpd_dbus_avahi --> off
httpd_enable_cgi --> off
httpd_enable_ftp_server --> off
httpd_enable_homedirs --> on
httpd_ssi_exec --> off
httpd_tty_comm --> off
httpd_unified --> off
httpd_use_cifs --> off
httpd_use_gpg --> off
httpd_use_nfs --> off

I have used audit2allow to create loadable modules to enable write access for other daemons (for example for rotatelog) but I don't think this is the way to go in this situation. A module for httpd already exists and I don't want to touch it in any way if I can avoid it.

I am simply looking for a way to let apache2 / php / Joomla write in specific directories inside my specific DocumentRoot, without granting write access to anything else. Please advise.

nn4l
  • 1,336
  • 5
  • 22
  • 40

2 Answers2

4

You need to tell SELinux that the cache location is type httpd_cache_t:

# semanage fcontext -a -t 'httpd_cache_t' '/path/to/wwwroot/cache(/.*)?'
# restorecon -Rvvv /path/to/wwwroot/cache
mricon
  • 1,154
  • 7
  • 9
1

Cache directories are used by all different kind of users, like you already mentioned, the apache user, the php user and maybe even a separate Joomla user if you use mod_fcgid. For directories like this there is the public_content_rw_t type context. That makes it writable for all services involved and (since it's "just" a cache directory with temporary files) shouldn't impose too much of a security risk. So I would suggest to alter the types to the public one, using the command

chcon -R -t public_content_rw_t /path/to/wwwroot/cache
Oldskool
  • 2,005
  • 1
  • 16
  • 26
  • excellent, this statement does exactly what I need. – nn4l Dec 31 '12 at 13:34
  • 2
    I have two corrections: 1. `httpd_cache_t` is a much better choice than `public_content_rw_t`. 2. You shouldn't be using chcon. Instead, do `semanage fcontext -a -t 'httpd_cache_t' '/path/to/wwwroot/cache(/.*)?'` and then `restorecon -Rvvv /path/to/wwwroot/cache`, to tell SELinux what label should be put on all newly created files in that dir. – mricon Dec 31 '12 at 18:22