ISPmanager and selinux
From ISPWiki
Contents |
Software requirements
- Centos 5.3
- ISPmanager-Pro 4.3.32. - .34
Introduction
We have managed to make ISPmanager work together with SELinux which enables to separate client hosting from the server. Even though the system lacks the security feature that allows, for example, an attacker to use root privileges, his access to resources and the possible damage he can do will be limited.
The main principle of this method is that you need to have two httpd, one for ispmgr, the other for hosting clients. Optionally you may deploy a very useful feature, i.e. errors in the configuration file of the client's Apache will not cause ISPmanager to fail. The client's Apache runs on a standard context of SELinux. There is a module for ispmgr apache that starts it in unconfined_c, thus disabling SELinux.
Creating SELlinux module for ispmgr
We would recommend that you not perform these actions on the machine where the hosting service is hosted. To set up the module you will need the same distribution version as will be used for hosting. If you are using the machine where the hosting is running, you need to enable SELinux and restore the attributes (see information below).
yum install selinux-policy-devel.noarch policycoreutils mkdir ~/policy cd ~/policy
In this directory create the files: ispmgr.fc ispmgr.if ispmgr.te
ispmgr.fc
/usr/sbin/httpd_ispmgr -- gen_context(system_u:object_r:ispmgr_exec_t,s0) /usr/sbin/httpd_ispmgr.worker -- gen_context(system_u:object_r:ispmgr_exec_t,s0)
ispmgr.if
######################################## ## <summary> ## Execute a domain transition to run ispmgr. ## </summary>
interface(`ispmgr_domtrans',`
gen_require(`
type ispmgr_t, ispmgr_exec_t;
')
domain_auto_trans($1,ispmgr_exec_t,unconfined_t)
allow $1 ispmgr_t:fd use;
allow ispmgr_t $1:fd use;
allow $1 ispmgr_t:fifo_file rw_file_perms;
allow $1 ispmgr_t:process sigchld;
')
ispmgr.te
policy_module(ispmgr,1.0.5) type ispmgr_t; type ispmgr_exec_t;
require {
type initrc_t;
type unconfined_t;
}
domain_type(ispmgr_t) domain_entry_file(ispmgr_t, ispmgr_exec_t)
ispmgr_domtrans(initrc_t)
Compilation
Run the make command
make -f /usr/share/selinux/devel/Makefile Compiling targeted ispmgr module /usr/bin/checkmodule: loading policy configuration from tmp/ispmgr.tmp /usr/bin/checkmodule: policy configuration loaded /usr/bin/checkmodule: writing binary representation (version 6) to tmp/ispmgr.mod Creating targeted ispmgr.pp policy package rm tmp/ispmgr.mod.fc tmp/ispmgr.mod
Booting the module
If everything went well, you will see the ispmgr.pp file. If not, you will need to delete the tmp subdirectory and the ispmgr.pp file before restarting make.
Boot the newly created module and make sure that it is put on the list.
semodule -i ispmgr.pp semodule -l
If you are creating the module on the machine where the hosting service is hosted, delete selinux-policy-devel.noarch package
Activating SELinux and installing the module
Perform the following actions on the machines with ispmgr
Enable selinux to run in permissive mode and restore the file attributes, because ispmgr did not installed them, if selinux was disabled.
Specify SELINUX=permissive in /etc/selinux/config
touch /.autorelabel shutdown -rf now
Depending on the number of files on the disk it may take some time to reboot.
yum install policycoreutils
If you are creating the module on another machine, you need to copy the ispmgr.pp module, boot and locate it:
semodule -i ispmgr.pp semodule -l
Creating the httpd clone
cp -ax /usr/sbin/httpd /usr/sbin/httpd_ispmgr cp -ax /usr/sbin/httpd.worker /usr/sbin/httpd_ispmgr.worker
Set up the context and make sure that it is ispmgr_exec_t
restorecon -F /usr/sbin/httpd_ispmgr /usr/sbin/httpd_ispmgr.worker ls -lZ /usr/sbin/httpd_ispmgr /usr/sbin/httpd_ispmgr.worker
If the context differs, try to find out what's happening to ispmgr.pp
View the logs:
mkdir /var/log/httpd_ispmgr chmod 700 /var/log/httpd_ispmgr cd /etc/httpd ln -s ../../var/log/httpd_ispmgr logs_ispmgr
Clone the configs, directories and start-up scripts. The differences from the original are described below: cp -ax /usr/sbin/apachectl /usr/sbin/apachectl_ispmgr
diff -u /usr/sbin/apachectl /usr/sbin/apachectl_ispmgr
--- /usr/sbin/apachectl 2009-07-14 14:03:18.000000000 +0400 +++ /usr/sbin/apachectl_ispmgr 2009-10-19 07:34:44.000000000 +0400 @@ -41,7 +41,7 @@ # -------------------- -------------------- # # the path to your httpd binary, including options if necessary -HTTPD='/usr/sbin/httpd' +HTTPD='/usr/sbin/httpd_ispmgr' # # # the command that outputs a formatted text version of the HTML at the @@ -58,8 +58,8 @@ STATUSURL="http://localhost:80/server-status" # Source /etc/sysconfig/httpd for $HTTPD setting, etc. -if [ -r /etc/sysconfig/httpd ]; then - . /etc/sysconfig/httpd +if [ -r /etc/sysconfig/httpd_ispmgr ]; then + . /etc/sysconfig/httpd_ispmgr fi #
If necessary, you may edit the following line in both described above files: STATUSURL="http://localhost:80/server-status" according to the peculiarities of each server.
cp -ax /etc/rc.d/init.d/httpd /etc/rc.d/init.d/httpd_ispmgr
diff -u /etc/rc.d/init.d/httpd /etc/rc.d/init.d/httpd_ispmgr
--- /etc/rc.d/init.d/httpd 2009-07-14 14:08:09.000000000 +0400
+++ /etc/rc.d/init.d/httpd_ispmgr 2009-10-19 07:18:30.000000000 +0400
@@ -5,16 +5,16 @@
# chkconfig: - 85 15
# description: Apache is a World Wide Web server. It is used to serve \
# HTML files and CGI.
-# processname: httpd
-# config: /etc/httpd/conf/httpd.conf
-# config: /etc/sysconfig/httpd
-# pidfile: /var/run/httpd.pid
+# processname: httpd_ispmgr
+# config: /etc/httpd/conf/httpd_ispmgr.conf
+# config: /etc/sysconfig/httpd_ispmgr
+# pidfile: /var/run/httpd_ispmgr.pid
# Source function library.
. /etc/rc.d/init.d/functions
-if [ -f /etc/sysconfig/httpd ]; then
- . /etc/sysconfig/httpd
+if [ -f /etc/sysconfig/httpd_ispmgr ]; then
+ . /etc/sysconfig/httpd_ispmgr
fi
# Start httpd in the C locale by default.
@@ -30,15 +30,15 @@
# Path to the apachectl script, server binary, and short-form for messages.
apachectl=/usr/sbin/apachectl
-httpd=${HTTPD-/usr/sbin/httpd}
-prog=httpd
-pidfile=${PIDFILE-/var/run/httpd.pid}
-lockfile=${LOCKFILE-/var/lock/subsys/httpd}
+httpd=${HTTPD-/usr/sbin/httpd_ispmgr}
+prog=httpd_ispmgr
+pidfile=${PIDFILE-/var/run/httpd_ispmgr.pid}
+lockfile=${LOCKFILE-/var/lock/subsys/httpd_ispmgr}
RETVAL=0
# check for 1.3 configuration
check13 () {
- CONFFILE=/etc/httpd/conf/httpd.conf
+ CONFFILE=/etc/httpd/conf/httpd_ispmgr.conf
GONE="(ServerType|BindAddress|Port|AddModule|ClearModuleList|"
GONE="${GONE}AgentLog|RefererLog|RefererIgnore|FancyIndexing|"
GONE="${GONE}AccessConfig|ResourceConfig)"
cp -ax /etc/sysconfig/httpd /etc/sysconfig/httpd_ispmgr
diff -u /etc/sysconfig/httpd /etc/sysconfig/httpd_ispmgr
--- /etc/sysconfig/httpd 2009-07-14 14:08:09.000000000 +0400 +++ /etc/sysconfig/httpd_ispmgr 2009-10-19 07:39:15.000000000 +0400 @@ -6,13 +6,13 @@ # available, but does not work with some modules (such as PHP). # The service must be stopped before changing this variable. # -#HTTPD=/usr/sbin/httpd.worker +#HTTPD=/usr/sbin/httpd_ispmgr.worker # # To pass additional options (such as -D definitions) to the # httpd binary at startup, set OPTIONS here. # -#OPTIONS= +OPTIONS="-f conf/httpd_ispmgr.conf" # # The httpd process is started in the C locale as default; to
cp -ax /etc/httpd/conf.d/ssl.conf /etc/httpd/conf.d/ssl.conf_ispmgr mv /etc/httpd/conf.d/ssl.conf /etc/httpd/conf.d/ssl.conf_others
diff -u /etc/httpd/conf.d/ssl.conf_others /etc/httpd/conf.d/ssl.conf_ispmgr
--- /etc/httpd/conf.d/ssl.conf_others 2009-12-10 06:00:30.000000000 +0300
+++ /etc/httpd/conf.d/ssl.conf_ispmgr 2009-11-28 02:39:26.000000000 +0300
@@ -15,10 +15,7 @@
# When we also provide SSL we have to listen to the
# the HTTPS port in addition.
#
-Listen 192.168.8.69:443
-Listen 123.456.78.202:443
-Listen 123.456.78.203:443
-Listen 123.456.78.204:443
+Listen 123.456.78.198:443
##
## SSL Global Context
@@ -89,8 +86,8 @@
# Use separate log files for the SSL virtual host; note that LogLevel
# is not inherited from httpd.conf.
-ErrorLog logs/ssl_error_log
-TransferLog logs/ssl_access_log
+ErrorLog logs_ispmgr/ssl_error_log
+TransferLog logs_ispmgr/ssl_access_log
LogLevel warn
# SSL Engine Switch:
@@ -225,7 +222,7 @@
# Per-Server Logging:
# The home of a custom SSL log file. Use this when you want a
# compact non-error SSL logfile on a virtual host basis.
-CustomLog logs/ssl_request_log \
+CustomLog logs_ispmgr/ssl_request_log \
"%t %h %{SSL_PROTOCOL}x %{SSL_CIPHER}x \"%r\" %b"
</VirtualHost>
The Listen directive should be edited according to your server's peculiarities. I put ispmgr to the IP address that is bound to the license, and left the rest of them for the users' Apache.
cp -ax /etc/httpd/conf/httpd.conf /etc/httpd/conf/httpd_ispmgr.conf
diff -U 1 /etc/httpd/conf/httpd.conf /etc/httpd/conf/httpd_ispmgr.conf
--- /etc/httpd/conf/httpd.conf 2009-12-10 05:59:52.000000000 +0300
+++ /etc/httpd/conf/httpd_ispmgr.conf 2009-11-28 02:39:05.000000000 +0300
@@ -27,5 +27,5 @@
# server will use that explicit path. If the filenames do *not* begin
-# with "/", the value of ServerRoot is prepended -- so "logs/foo.log"
+# with "/", the value of ServerRoot is prepended -- so "logs_ispmgr/foo.log"
# with ServerRoot set to "/etc/httpd" will be interpreted by the
-# server as "/etc/httpd/logs/foo.log".
+# server as "/etc/httpd/logs_ispmgr/foo.log".
#
@@ -62,3 +62,3 @@
#
-PidFile run/httpd.pid
+PidFile run/httpd_ispmgr.pid
@@ -133,6 +133,3 @@
#Listen 12.34.56.78:80
-Listen 192.168.8.69:80
-Listen 123.456.78.202:80
-Listen 123.456.78.203:80
-Listen 123.456.78.204:80
+Listen 123.456.78.198:80
@@ -213,3 +210,3 @@
Include conf.d/*.conf
-Include conf.d/*.conf_others
+Include conf.d/*.conf_ispmgr
@@ -475,3 +472,3 @@
#
-ErrorLog logs/error_log
+ErrorLog logs_ispmgr/error_log
@@ -504,3 +501,3 @@
#
-#CustomLog logs/access_log common
+#CustomLog logs_ispmgr/access_log common
@@ -510,4 +507,4 @@
#
-#CustomLog logs/referer_log referer
-#CustomLog logs/agent_log agent
+#CustomLog logs_ispmgr/referer_log referer
+#CustomLog logs_ispmgr/agent_log agent
@@ -517,3 +514,3 @@
#
-CustomLog logs/access_log combined
+CustomLog logs_ispmgr/access_log combined
@@ -854,6 +851,2 @@
</Directory>
-<Directory /var/www/u1/data/www/r.isptest.mns.ru>
- php_admin_value open_basedir "/var/www/u1/data:."
- Options +ExecCGI
-</Directory>
@@ -996,47 +989,6 @@
# ServerName dummy-host.example.com
-# ErrorLog logs/dummy-host.example.com-error_log
-# CustomLog logs/dummy-host.example.com-access_log common
+# ErrorLog logs_ispmgr/dummy-host.example.com-error_log
+# CustomLog logs_ispmgr/dummy-host.example.com-access_log common
#</VirtualHost>
Edit Listen in both files according to the peculiarities of your hosting. Configure the required parameters (ISPmanager SSL-certificates, etc.) Restart the users' apache in order to free *.80 and *.443
service httpd restart
Enable the panel's web-server in rcX.d and start it:
chkconfig httpd_ispmgr --add chkconfig httpd_ispmgr on service httpd_ispmgr start
If everything went well, and I did everything correctly, both Apache web servers will start, the users' apache will start in the httpd_t domain and the panel's one in unconfined_t.
ps -Chttpd_ispmgr -Chttpd -Z
root:system_r:httpd_t 23592 ? 00:00:00 httpd root:system_r:httpd_t 23593 ? 00:00:00 httpd root:system_r:httpd_t 23594 ? 00:00:00 httpd root:system_r:httpd_t 23595 ? 00:00:00 httpd root:system_r:httpd_t 23596 ? 00:00:00 httpd root:system_r:httpd_t 23597 ? 00:00:00 httpd root:system_r:httpd_t 23598 ? 00:00:00 httpd root:system_r:httpd_t 23599 ? 00:00:00 httpd root:system_r:httpd_t 2455 ? 00:00:01 httpd root:system_r:httpd_t 30644 ? 00:00:00 httpd system_u:system_r:unconfined_t 2235 ? 00:00:01 httpd_ispmgr system_u:system_r:unconfined_t 23602 ? 00:00:00 httpd_ispmgr system_u:system_r:unconfined_t 23603 ? 00:00:00 httpd_ispmgr system_u:system_r:unconfined_t 23604 ? 00:00:00 httpd_ispmgr system_u:system_r:unconfined_t 23605 ? 00:00:00 httpd_ispmgr system_u:system_r:unconfined_t 23606 ? 00:00:00 httpd_ispmgr system_u:system_r:unconfined_t 23607 ? 00:00:00 httpd_ispmgr system_u:system_r:unconfined_t 23608 ? 00:00:00 httpd_ispmgr system_u:system_r:unconfined_t 23617 ? 00:00:00 httpd_ispmgr
Afterword
After you have completed the main operations, enable selinux in the Enforced mode and reboot it. Do not use setenforce! Reboot is required, as the processes get the context while creating, and it is inconvenient to restart them manually.
Edit /etc/selinux/config SELINUX=enforcing and reboot.
Then you customize selinux for standard services, specify nonstandard directories to the file's context, set up selinux booleans, etc. If you have any questions, you can find more information in corresponding documents. I will list the commands and the file you will need to create. More information can be found on the Internet and in user manuals.
Specify your context here:
/etc/selinux/targeted/contexts/files/file_contexts.local
Example on how to do that can be found here:
/etc/selinux/targeted/contexts/files/file_contexts
Useful commands
getsebool setsebool getenforce setenforce audit2allow audit2who checkmodule semodule_package semodule
Use the instructions below to proceed:
- go to permissive
- restart a problem service
- let it do what it prompts
- watch the records in audit log
- use it in audit2allow to get a template module
- analyse the template, and edit it and file_contexts.local
- prepare and boot the module
- set up the correct context of the line that we specified in file_contexts.local
- go to enforced
- reboot the problem service and check its performance
WBR, Vadim Shkolin, vadim аt vsh.spb.su
