SELinux and apache (httpd)

I’ve just built a new web server vm, basically identical to my mariadb one, and the fedora cloud image. This is documentation on how I configured it, as well as the ttrss update daemon.

To get nfs to work, install nfs-utils. I need some packages also for ttrss.

$ yum install nfs-utils httpd php php-mysql php-mbstring php-xml

I’m putting the web root on an nfs mount from my nas. I have multiple virtualhosts.

/etc/httpd/conf.d/ttrss.chrisirwin.ca:

# Bind only this IP address
<VirtualHost *:80>
    ServerAdmin     [email protected]
    ServerName      ttrss.chrisirwin.ca

    DocumentRoot    /var/www/sites/ttrss.chrisirwin.ca

    <Directory />
        Options +FollowSymLinks +MultiViews -Indexes
        AllowOverride None
    </Directory>

    <Directory /var/www/sites/ttrss.chrisirwin.ca/>
        Options +FollowSymLinks +MultiViews +ExecCGI -Indexes
        AllowOverride All
        Order allow,deny
        allow from all
        Require all granted
    </Directory>
</VirtualHost>

Make the sites directory, and restrict it’s permissions:

$ mkdir -p        /var/www/sites
$ chown root:root /var/www/sites
$ chmod 0000      /var/www/sites

Add an fstab entry. For selinux, we need the httpd_sys_script_exec_t context to allow server-side code to run:

nas:/hosts/web/var/www/sites    /var/www/sites    nfs4    nosharecache,context="system_u:object_r:httpd_sys_script_exec_t:s0" 0 0

Finally, we need to tell selinux that we’re okay with our scripts connecting to a network sql server:

$ setsebool -P httpd_can_network_connect_db on

Now, unfortunately, ttrss won’t work. It needs r/w in some of it’s directories, and selinux won’t allow write in the script context. However, we can move those write directories elsewhere, using a different context. Luckily, the context of a symlink is determined by it’s destination!

$ mkdir -p        /var/www/data
$ chown root:root /var/www/data
$ chmod 0000      /var/www/data

Add another fstab entry, but with httpd_sys_rw_content_t context

nas:/hosts/web/var/www/data    /var/www/data    nfs4    nosharecache,context="system_u:object_r:httpd_sys_rw_content_t:s0" 0 0

We need to move and symlink the rw directories:

for item in cache feed-icons lock; do
    $ mv      /var/www/sites/ttrss.chrisirwin.ca/${item}
              /var/www/data/ttrss.chrisirwin.ca/${item}

    $ ln -sfn /var/www/sites/ttrss.chrisirwin.ca/${item}
              /var/www/data/ttrss.chrisirwin.ca/${item}
fi

Now, enable httpd, and start the service:

$ systemctl enable httpd
$ systemctl start  httpd

If you’re having issues starting the service, you can check for any recent selinux denials.

$ ausearch -m avc | tail

Finally, the update daemon. I’m using the following service file, /etc/systemd/ttrss.chrisirwin.ca.service:

[Unit]
Description=Tiny Tiny RSS update daemon
# Can't depend on mysqld/mariadb, since it's on another host.
#After=network.target mysqld.service
After=network.target
#Requires=mysqld.service

[Service]
User=apache
Group=apache
WorkingDirectory=/var/www/sites/ttrss.chrisirwin.ca
Type=simple
StandardOutput=null
StandardError=syslog
ExecStart=/bin/php ./update_daemon2.php
PrivateTmp=true
InaccessibleDirectories=/home /root /boot /mnt /media
ReadOnlyDirectories=/etc /usr

[Install]
WantedBy=multi-user.target

Now, enable ttrss, and start the service:

$ systemctl enable /etc/systemd/ttrss.chrisirwin.ca.service
$ systemctl start  ttrss

If you edit the service file after installing it, you’ll need to reload systemd for it to re-parse the service file:

$ systemctl daemon-reload