Project

General

Profile

RedmineAndSELinuxOnCentOS » History » Revision 2

Revision 1 (Sascha Sanches, 2010-09-18 21:14) → Revision 2/3 (Alexander Kirillov, 2011-02-06 09:39)

h1. Redmine, Phusion Passenger, Ruby Enterprise Edition, Apache and ... SELinux 

 _Disclaimer: Please make sure you understand the steps detailed below before applying them. I take no responsibility when things go wrong!! Especially software such as Security Enhanced Linux can cause any part of the system to malfunction. Please make sure you test this in an environment you can afford to reinstall, or that you are able to restore the system in another way to a good state. Keep in mind that this has been written with CentOS 5.5 in mind. Another distribution might do things differently. That being said, these instructions worked fine for me._ 

 This guide has been tested with the following software and versions: 

 * "Ruby Enterprise Edition":http://www.rubyenterpriseedition.com/ _(1.8.7-2010.02)_ 
 * "Phusion Passenger":http://www.modrails.com/ _(2.2.15)_ 
 * "Redmine":http://www.redmine.org/ _(1.0.1)_ 
 * "Apache":http://httpd.apache.org/ _(2.2)_ 
 * "SELinux":http://www.selinuxproject.org/ 
 * "CentOS":http://www.centos.org/ _(5.5)_ 

 I will not go into installing these projects. The first three have excellent documentation on their own websites, and the last three come with the operating system. 


 h3. What I wish to accomplish 

 Mostly, when SELinux is causing problems, the general advice is to disable it. And I know, it can be a real PITA! But it can provide lots of added security as well, so I wish to try to keep it running, at least in targeted mode. Some systems might have problems with a setup like this, such as servers under control of webhosting software. Please consider these things before trying this. I recommend using a test setup to start with. 


 h3. Assumptions 

 * You have at least some experience with commands such as _chown, chmod, chcon_ (change ownership, change permissions, change SELinux security label). 
 * The software referenced above has been installed in a pretty much default way as described on its website. 
 * The software runs well when SELinux is disabled or running in permissive mode. 
 * The same user account on the system is used to run Apache, Phusion Passenger, and thus Redmine. If not, adapt accordingly. 
 * The root user is owner of the websites files, and apache is the group owner, meaning Apache cannot just write to any file or directory. If not, adapt accordingly. 

 Before executing the commands below, you will want to stop Apache, and start it again when finished. 


 h3. Acronyms and paths 

 * Ruby Enterprise will be referred to as RE, and is installed in some path named ${RE}. 
 * Phusion Passenger will be referred to as PP, and is installed in some path named ${PP}. This will probably be some path below RE, such as ${RE}/ruby/gems/1.8/gems/passenger-x.x.x. 
 * Redmine will be referred to as RM, and is installed in some path named ${RM}. 


 h3. Permissions 

 We are going to be dealing with two different sets of permissions here. First, there are the filesystem permissions. Files have to be readable, perhaps writable, or even executable by the webserver user. Second, there are the SELinux permissions. If filesystem permissions disallow access, then access is disallowed. If filesystem permissions allow access, then SELinux can still disallow access based upon its own set of rules. 

 The apache user runs with a certain security label that SELinux understands. Based upon this security label certain actions are allowed or disallowed. For example, the SELinux policy (= rules database) says that the process running with the security label _httpd_t_ (= apache) can listen on port 80. The policy also allows it to read files labeled _httpd_sys_content_t_. 

 We are going to make sure that the filesystem permissions as well as the SELinux permissions allow read/write/execute permissions where needed, using just existing SELinux labels, and that the two sets of permissions are in agreement with each other. 


 h2. Ruby Enterprise Edition and Phusion Passenger 


 h3. Basic permissions 

 First, we will give the root user ownership and revoke all execute permissions on REE files. Then we will restore execute permissions on directories only, so they can be entered. Next we will set a default SELinux user and label, so REE can be used normally (actually, you'll need to follow the steps below as well for this to work). 

 # Give the root user ownership: 
 <pre>chown -R root:root ${RE}</pre> 
 # Revoke all execute permissions, but allow the owner read/write, and everyone else read acces: 
 <pre>chmod -R u=rw,g=r,o=r ${RE}</pre> 
 # Restore execute permissions for directories only (_note that the X in a+X here is a *capital* X_): 
 <pre>chmod -R a+X ${RE}</pre> 
 # Set a default SELinux user and label: 
 <pre>chcon -R -u system_u -t usr_t ${RE}</pre> 


 h3. Libraries 

 Now we will restore execute permissions on REE system libraries, and give them the SELinux label for library types. 

 # Set execute permissions on all "*.so" files: 
 <pre>find -P ${RE} -type f -name "*.so*" -exec chmod a+x {} \;</pre> 
 # Set the SELinux library label on "*.so" files: 
 <pre>find -P ${RE} -type f -name "*.so*" -exec chcon -t lib_t {} \;</pre> 
 # Set execute permissions on "*.a" files: 
 <pre>find -P ${RE} -type f -name "*.a" -exec chmod a+x {} \;</pre> 
 # Set the SELinux library label on "*.a" files: 
 <pre>find -P ${RE} -type f -name "*.a" -exec chcon -t lib_t {} \;</pre> 


 h3. Binaries 

 Here we will restore execute permissions on REE binaries, and set their SELinux label. 

 # Set execute permissions on all files in _bin_ directories: 
 <pre>find -P ${RE} -type d -name "bin" -exec chmod -R a+x {} \;</pre> 
 # Set the SELinux binary label for all files in _bin_ directories: 
 <pre>find -P ${RE} -type d -name "bin" -exec chcon -R -t bin_t {} \;</pre> 


 h3. Apache module 

 Next we will make sure Apache can load Phusion Passenger as a module. SELinux contains a label for that (_httpd_modules_t_). Without this label on the module, apache will not be allowed to load it as such. Phusion Passenger in turn executes a file called _ApplicationPoolServerExecutable_, which must be executable as well. Since it is not in a _bin_ directory, the file has not been marked executable by the actions described above. 

 # Enable Phusion Passenger to run the ApplicationPoolServerExecutable: 
 <pre> 
 chmod a+x ${PP}/etc/apache2/ApplicationPoolServerExecutable 
 chcon -t bin_t ${PP}/etc/apache2/ApplicationPoolServerExecutable 
 </pre> 
 # Enable Apache to run Phusion Passenger as a module: 
 <pre> 
 chmod a+x ${PP}/etc/apache2/mod_passenger.so 
 chcon -t httpd_modules_t ${PP}/etc/apache2/mod_passenger.so 
 </pre> 


 h3. More on Phusion Passenger: the temporary directory 

 Passenger needs a temporary directory where it can write to. I suggest creating one that will only be used by PP, instead of the system default, as I seem to remember this doesn't work anyway when SELinux is enabled. See "this part":http://www.modrails.com/documentation/Users%20guide%20Apache.html#PassengerTempDir of the documentation for some details. 

 The PP temporary directory is set by the _PassengerTempDir_ directive in Apaches configuration. Set it there, create the directory, and adjust permissions: 

 <pre> 
 chown -R apache:apache ${PP_TEMP_DIR} 
 chmod -R u=rwX,g=rX,o-rwx ${PP_TEMP_DIR} 
 chcon -R -u system_u -t httpd_tmpfs_t ${PP_TEMP_DIR} 
 </pre> 

 The _httpd_tmpfs_t_ label grants some additional rights needed by the passenger module, such as creating special files like sockets or fifos. 


 h3. Up until now 

 You can download the steps I have described up until now as a bash script file: attachment:RubyAndSELinux. Please do not just execute this file. Make sure you understand it, and change the filesystem paths near the top according to your setup. 

 There is also a script for making the SELinux changes persistent across a filesystem relabel: attachment:RubyAndSEmanage. Note that this does not change any filesystem permissions, nor does it apply the policy. It includes the changes described within the Ruby Enterprise and Phusion Passenger part excluding for the temporary directory part. To apply the policy, do a <pre>touch /.autorelabel</pre> and reboot. Again, make sure you know what you are doing! You might need to understand some regular expression syntax in order to adapt this file to your particular situation. 


 h2. Redmine 

 If you have made it this far using these instructions, then the next part will be easy to understand. 

 Redmine needs some directories to be writable to function. These are: ${RM}/log, ${RM}/tmp, ${RM}/files, and ${RM}/public/plugin_assets. 

 First we set the basic permissions (_again, the X in ug+X is a *capital* X_): 
 <pre> 
 chown -R root:apache ${RM} 
 chmod -R u=rw,g=r,o-rwx ${RM} 
 chmod -R ug+X ${RM} 
 chcon -R -u system_u -t httpd_sys_content_t ${RM} 
 </pre> 

 And then we apply permissions for individual directories: 
 <pre> 
 chown -R apache:apache ${RM}/log 
 chcon -R -t httpd_log_t ${RM}/log 

 chown -R apache:apache ${RM}/tmp 
 chcon -R -t httpd_tmpfs_t ${RM}/tmp 

 chown -R apache:apache ${RM}/files 
 chcon -R -t httpd_sys_script_rw_t ${RM}/files 

 chown -R apache:apache ${RM}/public/plugin_assets 
 chcon -R -t httpd_sys_script_rw_t ${RM}/public/plugin_assets 
 </pre> 

 You can download the second part I have described as a bash script file as well: attachment:RedmineAndSELinux. Please do not just execute this file. Make sure you understand it, and change the filesystem paths near the top according to your setup. 


 h2. Summary 

 * The default install of Ruby Enterprise Edition seems to have some executable permissions on *.rb-files that I think should not be there. We've fixed this. 
 * The default SELinux label for files in the Ruby installation has been set to _usr_t_, for libraries to _lib_t_, for executables to _bin_t_, and for the Apache module (Phusion Passenger, aka mod_rails) to _httpd_modules_t_. 
 * Phusion Passenger has a working directory where it can store its files, uploads and sockets. 
 * Redmine can write to its logs, files directory, temporary directory, and plugin_assets directory. 


 h2. Notes 

 _I would suggest to stick with Passenger 2.2.15. 
 While it's possible to get 3.0.2 working it will flood your audit log with denials._ 

 <pre> 
 gem uninstall passenger 
 gem install passenger -v=2.2.15 
 passenger-install-apache2-module 
 </pre>