Selinux Config for Apache
This is a go at configuring SE Linux for the Apache web server.
To install Apache on a RedHat Enterprise Linux 8 server and to change the default port:
sudo dnf install -y httpd
sudo sed -i 's/Listen 80/Listen 1100/' /etc/httpd/conf/httpd.conf
sudo systemctl restart httpd
Job for httpd.service failed because the control process exited with error code.
See "systemctl status httpd.service" and "journalctl -xe" for details.
-- Unit httpd.service has begun starting up.
Apr 07 09:59:06 ip-172-31-1-215.ap-south-1.compute.internal httpd[20173]: (13)Permission denied: AH00072: make_sock: could not bind to address [::]:1100
Apr 07 09:59:06 ip-172-31-1-215.ap-south-1.compute.internal httpd[20173]: (13)Permission denied: AH00072: make_sock: could not bind to address 0.0.0.0:1100
At this point, Apache wants to start listening on port 1100 but the permission is denied by SE Linux, so we need to set the http_port_t tag on port 1100 to allow Apache to start up. For this, we can use the semanage command which is within the policycoreutils-python-utils package:
sudo dnf provides semanage #To look up the package name
sudo dnf install -y policycoreutils-python-utils
sudo semanage port -a -t http_port_t -p tcp 1100
Next, we get Apache to serve files from a directory located within our home directory:
chmod a+rx /home/ec2-user/
mkdir /home/ec2-user/blog
echo "One" > /home/ec2-user/blog/1.txt
sudo vi /etc/httpd/conf/httpd.conf
Alias /blog /home/ec2-user/blog
<Directory /home/ec2-user/blog>
Options All
AllowOverride All
Require all granted
order allow,deny
allow from all
</Directory>
sudo systemctl reload httpd
curl localhost:1100/blog/1.txt
Note: “Require all granted” is for Apache 2.4, “order allow,deny” is for Apache 2.2
The curl command returns a 403 Forbidden and we can check the audit log with the “ausearch” command:
sudo ausearch -r -x httpd | grep blog
#Output:
type=AVC msg=audit(1649334257.938:5087): avc: denied { open } for pid=22385 comm="httpd" path="/home/ec2-user/blog/1.txt" dev="xvda2" ino=12666025 scontext=system_u:system_r:httpd_t:s0 tcontext=unconfined_u:object_r:user_home_t:s0 tclass=file permissive=1
The “user_home_t” tag is preventing Apache from accessing the directory containing the files to be served over HTTP. “ls -ldZ /home/ec2-user” will get us the tag on the home directory:
drwxr-xr-x. 4 ec2-user ec2-user unconfined_u:object_r:user_home_dir_t:s0 107 Apr 7 12:11 /home/ec2-user
We can either change the tag or create an SE Linux policy module to allow Apache to access to the home directory.
If we choose to change the tag on the directory, we can look up the tag that Apache requires by looking for the tags on the /var/www directory, which is where the default files served by Apache are located:
sudo semanage fcontext -l | grep http | grep /var/www | head -1
#Output:
/var/www(/.*)? all files system_u:object_r:httpd_sys_content_t:s0
To temporarily set the tag, we can use chcon:
sudo chcon -Rv -u system_u -t httpd_sys_content_t /home/ec2-user
This can be reset with:
sudo restorecon -R -v /home/ec2-user
To make the tag permanent:
sudo semanage fcontext -a -t httpd_sys_content_t '/home/ec2-user/.*'
sudo restorecon -R -v /home/ec2-user
Alternatively, to allow Apache access to the home directory:
cat > httpd_home_access.te <<EOF
module httpd_home_access 1.0;
require {
type user_home_t;
type httpd_t;
class dir search;
class file { getattr open read };
}
#============= mongod_t ==============
allow httpd_t user_home_t:dir search;
allow httpd_t user_home_t:file { getattr open read };
EOF
checkmodule -M -m -o httpd_home_access.mod httpd_home_access.te
semodule_package -o httpd_home_access.pp -m httpd_home_access.mod
sudo semodule -i httpd_home_access.pp
sudo semodule -l | grep httpd_home_access
#sudo semodule -d httpd_home_access #To remove the module