The script se-file-context.sh sets the SELinux context for ePages applications:
. /etc/default/epages6
# /var/epages/se-file-context.sh -?
Usage:
se-file-context.sh { --set | --restore } [ --perl-cgi ] [ --verbose ]
Options:
--set : set ePages SELinux context for web adapter files
--restore: set default SELinux context for web adapter files
--perl-cgi: set additionally SELinux context for Perl files
--verbose: verbose output
se-file-context.sh is executed by /etc/init.d/epages6 whenever starting an ePages application if the envoronment variable EPAGES_ENABLE_SELINUX is set in /etc/default/epages6.
se-file-context.sh does nothing if:
-
the command chcon isn’t found (SELinux isn’t installed on the system at all)
-
the command getenforce does not return enforcing (SELinux isn’t switched on)
-
the user who executes the command isn’t root
se-file-context.sh --set
se-file-context.sh --set sets the SELinux context so that the MySQL server and the web server work together with ePages.
If epages-mysqld is installed, following parameters are set:
If epages-webconf is installed, following parameters are set:
-
chcon -t httpd_config_t "$EPAGES_CONFIG"/WebInterface.conf
-
chcon -t httpd_modules_t "$EPAGES"/WebAdapter/{lib64/,}*.so
-
chcon -t httpd_log_t "$EPAGES_LOG"/WebAdapter.log 2>/dev/null
-
chcon -RL -t httpd_sys_content_t "$EPAGES_WEBROOT"
Then the web server cannot access to any other file than those menotioned above.
chcon -RL … is executed only if the directory in the argument not yet has the required context.
se-file-context.sh --set --perl-cgi
se-file-context.sh has an additional option --perl-cgi that allows the web server user to access ePages Perl, i.e. to use following files:
-
chcon -t bin_t "$EPAGES_SHARED"/Monitor/spy.pl "$EPAGES"/WebAdapter/monitor.pl
-
chcon -t httpd_sys_content_t "$EPAGES_SHARED"/Monitor/*.tmpl
-
chcon -RL -t usr_t "$EPAGES_CARTRIDGES"
-
chcon -RL -t bin_t "$EPAGES_PERL"/bin
-
find "$EPAGES_PERL"/bin -name ".so" -exec chcon -t lib_t {} \;
-
chcon -RL -t usr_t "$EPAGES_PERL"/lib
-
find "$EPAGES_PERL"/lib* -name ".so" -exec chcon -t lib_t {} \;
-
chcon -t texrel_shlib_t "$EPAGES_PERL"/lib/site_perl/linux/auto/Math/Pari/Pari.so
-
chcon -t texrel_shlib_t "$EPAGES_PERL"/bin/libMagickCore.so.2
-
chcon -t httpd_log_t "$EPAGES_LOG"/error.log "$EPAGES_LOG"/debug.log
Switching --perl-cgi on may be considered as security flaw. Don’t use --perl-cgi if there is no need to access Perl by the web server. Anyway, the access if only required if the CGI scripts spy.pl and monitor.pl (or other CGI scripts created by yourself) are used.
If both environment variables EPAGES_ENABLE_SELINUX and EPAGES_ENABLE_PERL_CGI are set in /etc/default/epages6, se-file-context.sh --set --perl-cgi is executed whenever starting an ePages application.
Default values in /etc/default/epages6 are EPAGES_ENABLE_SELINUX=1 and EPAGES_ENABLE_PERL_CGI=1. If you don’tz want to allow the web server user to run ePages Perl, unset EPAGES_ENABLE_PERL_CGI in /etc/default/epages6.
se-file-context.sh --restore
se-file-context.sh --restore restores the file context to its original value.
se-webnfs-context.sh
If the web server wants to access NFS mounted files (always in distributed installations) then
a) either run setsebool httpd_use_nfs on,
b) or mount all files needed by the web server with SELinux contect.
Variant a) has the drwaback that for the web server no files on the NFS mount is SELinux secured anymore.
se-webnfs-context.sh allows you to choose between both variants:
-
se-webnfs-context.sh --set mounts according variant b)
-
se-webnfs-context.sh --restore mounts according variant a)
Note: this only will work for ePages standard mounts as created by /var/epages/epages-fs.sh.
Variant a) works something like that:
mount FILESERVER:/srv/epages/eproot/Shared/WebRoot /srv/epages/eproot/Shared/WebRoot
setseboot httpd_use_nfs on
/etc/init.d/epages6 start_httpd
Variant b) works something like that:
SELINUX_OPTIONS='nosharecache,context=system_u:object_r:httpd_sys_content_t:s0'
mount -o $SELINUX_OPTIONS FILESERVER:/srv/epages/eproot/Shared/WebRoot /srv/epages/eproot/Shared/WebRoot
setseboot httpd_use_nfs off
/etc/init.d/epages6 start_httpd
Usage:
# se-webnfs-context.sh -?
Usage:
./se-webnfs-context.sh { --set | --restore } [ --perl-cgi ] [ --no-start ] [ --verbose ]
Options:
--set : mount web server files with SELinux context
--restore : mount web server files with httpd_use_nfs on
--perl-cgi: set additionally SELinux context for Perl files
--no-start: do not start ePages at the end of the script
--verbose : verbose output
SELinux Context for Distributed Installations
May server FILESERVER be the file server, request router and application server.
May server WEBSERVER be the web server and MySQL server.
Then run following commands (in that order) on the respecive servers to add the SELinux context to ePages (use your own UUID):
FILESERVER:
UUID=1234abcd-1234-1234-1234-0123456789abcd
export EPAGES_REPOURL=http://epages-software.de/repo/usr/$UUID
rpm -hiv $EPAGES_REPOURL/7.48.0/epages-release.noarch.rpm
/var/epages/epages-fs.sh -share
WEBSERVER:
UUID=1234abcd-1234-1234-1234-0123456789abcd
export EPAGES_REPOURL=http://epages-software.de/repo/usr/$UUID
rpm -hiv $EPAGES_REPOURL/7.48.0/epages-release.noarch.rpm
/var/epages/epages-fs.sh -mount FILESERVER
FILESERVER:
yum -y groupinstall epages-appsrv epages-reqsrv epages-ascsrv
WEBSERVER:
yum -y groupinstall epages-webconf epages-mysqld
FILESERVER:
. /etc/default/epages6
/var/epages/se-file-context.sh --set --perl-cgi --verbose
WEBSERVER:
. /etc/default/epages6
/var/epages/se-file-context.sh --set --perl-cgi --verbose
/var/epages/se-webnfs-context.sh --set --perl-cgi --no-start --verbose
/etc/init.d/epages6 start
FILESERVER:
/etc/init.d/epages6 start
Ready!
SELinux Context for Apache
What rights has the httpd process in in SELinux context?:
# semanage boolean -l | sort | grep httpd
allow_httpd_anon_write -> off Allow Apache to modify public files used for public file transfer services. Directories/Files must be labeled public_rw_content_t.
allow_httpd_mod_auth_ntlm_winbind -> off Allow Apache to use mod_auth_pam
allow_httpd_mod_auth_pam -> off Allow Apache to use mod_auth_pam
allow_httpd_sys_script_anon_write -> off Allow apache scripts to write to public content. Directories/Files must be labeled public_rw_content_t.
httpd_builtin_scripting -> on Allow httpd to use built in scripting (usually php)
httpd_can_check_spam -> off Allow http daemon to check spam
httpd_can_network_connect_cobbler -> off Allow HTTPD scripts and modules to connect to cobbler over the network.
httpd_can_network_connect_db -> off Allow HTTPD scripts and modules to connect to databases over the network.
httpd_can_network_connect -> off Allow HTTPD scripts and modules to connect to the network using TCP.
httpd_can_network_relay -> off Allow httpd to act as a relay
httpd_can_sendmail -> off Allow http daemon to send mail
httpd_dbus_avahi -> on Allow Apache to communicate with avahi service via dbus
httpd_enable_cgi -> on Allow httpd cgi support
httpd_enable_ftp_server -> off Allow httpd to act as a FTP server by listening on the ftp port.
httpd_enable_homedirs -> off Allow httpd to read home directories
httpd_execmem -> off Allow httpd scripts and modules execmem/execstack
httpd_read_user_content -> off Allow httpd to read user content
httpd_setrlimit -> off Allow httpd daemon to change system limits
httpd_ssi_exec -> off Allow HTTPD to run SSI executables in the same domain as system CGI scripts.
httpd_tmp_exec -> off Allow Apache to execute tmp content.
httpd_tty_comm -> on Unify HTTPD to communicate with the terminal. Needed for entering the passphrase for certificates at the terminal.
httpd_unified -> on Unify HTTPD handling of all content files.
httpd_use_cifs -> off Allow httpd to access cifs file systems
httpd_use_gpg -> off Allow httpd to run gpg in gpg-web domain
httpd_use_nfs -> off Allow httpd to access nfs file systems
setseboot VAR=1 switches on the desired variables:
setsebool httpd_builtin_scripting on
setsebool httpd_can_network_connect on
setsebool httpd_can_network_relay on
setsebool httpd_enable_cgi on
setsebool httpd_use_nfs on
Allow httpd to use a different port (e.g. port 81):
# semanage port -l | grep http
http_cache_port_t tcp 3128, 8080, 8118, 10001-10010
http_cache_port_t udp 3130
http_port_t tcp 80, 443, 488, 8008, 8009, 8443
pegasus_http_port_t tcp 5988
pegasus_https_port_t tcp 5989
# semanage port --add --proto tcp --type http_port_t 81
# semanage port -l | grep '^http_port_t$'
http_port_t tcp 81, 80, 443, 488, 8008, 8009, 8443
Show standard policies for httpd files:
# semanage fcontext -l | egrep -i '(Apache|httpd)'
Relabel Files
se-file-context.sh changes the context of files/directories. If the files are releabled, the changes get lost.
Thatswhy is is probably better to make the changes permanent:
# semanage fcontext --add --type httpd_sys_content_t '/srv/epages/eproot/Shared/WebRoot(/.*)?'
# restorecon -R /srv/epages/eproot/Shared/WebRoot
# semanage fcontext -l | grep eproot
/srv/epages/eproot/Shared/WebRoot(/.*)? all files system_u:object_r:httpd_sys_content_t:s0
/etc/selinux/targeted/contexts/customizable_types contains a list of file types. Ifa a file has such a type, it isn’t changed when relabelling:
# cat /etc/selinux/targeted/contexts/customizable_types
sandbox_file_t
svirt_image_t
virt_content_t
httpd_user_htaccess_t
httpd_user_script_exec_t
httpd_user_content_ra_t
httpd_user_content_rw_t
httpd_user_content_t
git_session_content_t
home_bin_t
Relabel all files of the server either by executing:
fixfiles relabel
or by executing:
touch /.autorelabel
reboot
Troubleshooting
If the web server can’t be restarted after running se-file-context.sh --restore:
# se-file-context.sh --restore --verbose
-> chcon --version: chcon (GNU coreutils) 8.4
-> getenforce: Enforcing
-> test -w /etc/passwd
=> epages-mysqld
=> epages-webconf
restorecon $EPAGES_CONFIG/WebInterface.conf
restorecon $EPAGES/WebAdapter/lib64/*.so $EPAGES/WebAdapter/*.so
restorecon $EPAGES_LOG/WebAdapter.log
restorecon -R $EPAGES_WEBROOT $EPAGES_WEBROOT/*
# cat /dev/null > /var/log/audit/audit.log
# /etc/init.d/httpd start
Starting httpd: httpd: Syntax error on line 221 of /etc/httpd/conf/httpd.conf: Syntax error on line 76 of /etc/httpd/conf.d/zzz-epages-httpd.conf: Cannot load /srv/epages/eproot/WebAdapter/lib64/libWIApacheSSL-2.2.8.so into server: /srv/epages/eproot/WebAdapter/lib64/libWIApacheSSL-2.2.8.so: cannot open shared object file: Permission denied
[FAILED]
Then we want to know what went wrong:
# audit2why -i /var/log/audit/audit.log
type=AVC msg=audit(1290176592.874:101): avc: denied { read } for pid=9172 comm="httpd" name="libWIApacheSSL-2.2.8.so" dev=dm-0 ino=278209 scontext=unconfined_u:system_r:httpd_t:s0 tcontext=system_u:object_r:var_t:s0 tclass=file
Was caused by:
Missing type enforcement (TE) allow rule.
Correct the contect and try again:
# chcon -t httpd_modules_t $EPAGES/WebAdapter/lib64/*.so
# cat /dev/null > /var/log/audit/audit.log
# /etc/init.d/httpd start
Starting httpd: [ OK ]
Anyway, it still does not work:
# wget -nv -S http://localhost/WebRoot/Doc/Manual/de/User_concept.txt >/dev/null
http://localhost/WebRoot/Doc/Manual/de/User_concept.txt:
15:40:26 ERROR 403: Forbidden.
What went wrong?:
# tail -1 /var/log/httpd/error_log
[Fri Nov 19 15:40:26 2010] [error] [client 172.20.20.84] (13)Permission denied: access to /WebRoot/Doc/Manual/de/User_concept.txt denied
# audit2why -i /var/log/audit/audit.log
type=AVC msg=audit(1290177626.043:118): avc: denied { getattr } for pid=9313 comm="httpd" path="/srv/epages/eproot/Shared/WebRoot/Doc/Manual/de/User_concept.txt" dev=dm-0 ino=288079 scontext=unconfined_u:system_r:httpd_t:s0 tcontext=system_u:object_r:var_t:s0 tclass=file
Was caused by:
Missing type enforcement (TE) allow rule.
Solution:
# se-file-context.sh --set --verbose
-> chcon --version: chcon (GNU coreutils) 8.4
-> getenforce: Enforcing
-> test -w /etc/passwd
=> epages-mysqld
=> epages-webconf
chcon -t httpd_config_t $EPAGES_CONFIG/WebInterface.conf
chcon -t httpd_modules_t $EPAGES/WebAdapter/lib64/*.so $EPAGES/WebAdapter/*.so
chcon -t httpd_log_t $EPAGES_LOG/WebAdapter.log
chcon -RL -t httpd_sys_content_t $EPAGES_WEBROOT
SELinux Context for MySQL
What rights has the MySQL process in in SELinux context?:
# semanage boolean -l | sort | grep mysql
allow_user_mysql_connect -> off Allow users to connect to mysql
exim_can_connect_db -> off Allow exim to connect to databases (postgres, mysql)
ftpd_connect_db -> off Allow ftp servers to use connect to mysql database
mysql_connect_any -> off Allow mysqld to connect to all ports
setseboot VAR=1 switches on the desired variables:
setsebool allow_user_mysql_connect on
Allow specific MySQL ports:
# semanage port -l | grep mysql
mysqld_port_t tcp 1186, 3306, 63132-63164
mysqlmanagerd_port_t tcp 2273
Show standard policies for mysql files:
# semanage fcontext -l | grep mysql
Move /var/lib/mysql to Different Directory
First move /var/lib/mysql ans create a symbolic link:
/etc/init.d/mysqld stop
mv /var/lib/mysql /some/local/directory/
( cd /var/lib ; ln -s /some/local/directory/mysql )
Finally execute se-file-context.sh --set. This sets the SELinux context of following files:
chcon -h system_u:object_r:mysqld_db_t:s0 /var/lib/mysql
chcon -h system_u:object_r:var_lib_t:s0 /some/local/directory
Move /var/lib/mysql to File Server
mysql.sock
Even if /var/lib/mysql resides on a different server, mysql.sock must remain local. Also, the directory that contains mysql.sock, must have a special SELinux context (/tmp/mysql/ may vary):
/etc/init.d/mysqld stop
sed -i 's,^\(socket\)=.*,\1=/tmp/mysql/mysql.sock,' /etc/my.cnf
mkdir -m 755 -p /tmp/mysql
chown mysql:mysql /tmp/mysql
semanage fcontext --add --type mysqld_db_t '/tmp/mysql(/.*)?'
semanage fcontext -f -s --add --type mysqld_var_run_t '/tmp/mysql/mysql\.sock'
restorecon -R /tmp/mysql
Note that $EPAGES_CONFIG/Database.d/*.conf must have the right datasource=dbi:mysql, either the new socket or a TCP connection:
# either:
datasource=dbi:mysql:mysql_socket=/tmp/mysql/mysql.sock;...
# or:
datasource=dbi:mysql:hostname=mysql-server;port=3306;...
Example:
cd $EPAGES_CONFIG
for i in Database.d/*.conf ; do
sed -i 's,^\(datasource=dbi:mysql\),\1:hostname='`hostname`';port=3306,' $i
done
mount FILESERVER:lib/mysql
Assumed that lib/mysql is stored in /home/lib/mysql on the file server $FILESERVER. The file server shares /home/lib/mysql (or a superior directory). Then /home/lib/mysql is mounted as follows:
mkdir -m 755 -p /var/lib/mysql
MOUNT_OPT='async,exec,noatime,nodev,nolock,bg,hard,intr,rw,rsize=16384,wsize=16384'
SELINUX_MOUNT_OPT='nosharecache,context=system_u:object_r:mysqld_db_t:s0'
echo "$FILESERVER:/home/lib/mysql /var/lib/mysql nfs $SELINUX_MOUNT_OPT,$MOUNT_OPT 0 0" >> /etc/fstab
mount /var/lib/mysql
The SELinux mount options are necessary because otherwise the mounted files would get the context nfs_t and therefore couldn’t be read by mysqld.
The SELinux mount option nosharecache is only necessary if the share is mounted twice.