Skip to end of metadata
Go to start of metadata

You are viewing an old version of this page. View the current version.

Compare with Current View Page History

« Previous Version 2 Current »

The information on this page is largely derived, with necessary modifications, from Creating and enforcing an SELinux policy for a custom application.

Prerequisites

dnf -y install selinux-policy-devel setroubleshoot-server
dnf -y group install 'Development Tools'
    # needed for at least g++ and rpmbuild. Not sure if anything else is needed from this group.

Become root

All of this documentation is to be completed as root.

Creating the service

Create mydaemon.cpp

cat > mydaemon.cpp << EOF
#include <iostream>
#include <fstream>
#include <chrono>
#include <ctime>
#include <thread>

using namespace std;

int main() {
    while (1) {
        time_t t = chrono::system_clock::to_time_t(chrono::system_clock::now());
        ofstream MyFile("/var/log/mydaemon.log", ios_base::app);  // app = append, not overwrite
        MyFile << ctime(&t);
        MyFile.close();
        this_thread::sleep_for(chrono::milliseconds(5000));
    }
}
EOF

Build it

g++ -o /usr/local/bin/mydaemon mydaemon.cpp

Create the systemd unit

cat > /etc/systemd/system/mydaemon.service << EOF
[Unit]
Description=Simple testing daemon

[Service]
Type=simple
ExecStart=/usr/local/bin/mydaemon

[Install]
WantedBy=multi-user.target
EOF

By default, the unit file has selinux context that systemd cannot access, so fix that and load it:

restorecon /usr/lib/systemd/system/mydaemon.service
systemctl daemon-reload

Try to start the service. Notice it fails.

systemctl start mydaemon
systemctl status mydaemon

Notice that it's running in unconfined_t

ps -efZ | grep mydaemon

Generate a custom policy for the daemon:

mkdir ~/mydaemon-sepolicy
cd ~/mydaemon-sepolicy
sepolicy generate --init /usr/local/bin/mydaemon

Created the following files:
/root/mydaemon-sepolicy/mydaemon.te # Type Enforcement file
/root/mydaemon-sepolicy/mydaemon.if # Interface file
/root/mydaemon-sepolicy/mydaemon.fc # File Contexts file
/root/mydaemon-sepolicy/mydaemon_selinux.spec # Spec file
/root/mydaemon-sepolicy/mydaemon.sh # Setup Script

Build it

./mydaemon.sh

Note that the setup script relabels the daemon to the newly created domain mydaemon_exec_t

ls -lZ /usr/local/bin/mydaemon

-rwxr-xr-x. 1 root root system_u:object_r:mydaemon_exec_t:s0 24504 Dec  1 15:24 /usr/local/bin/mydaemon

Temporarily set selinux to permissive and clear the audit log

setenforce 0
semodule --reload

Restart the daemon, and check that it now runs confined by SELinux:

systemctl restart mydaemon
ps -efZ | grep mydaemon

For your information. (Just get a look at what selinux would have blocked.)

sealert -l "*"

Build whatever new policy you need

mkdir ~/mydaemon-sepolicy2
cd ~/mydaemon-sepolicy2

# Make up a meaningful name for the module, such as "httpdwritehomes"
export newmod=mydaemonwritefiles

audit2allow -m $newmod -l -i /var/log/audit/audit.log > $newmod.te

# Edit the $newmod.te file and verify that it looks like what you want.

# Finally, to build & install the new module:
checkmodule -M -m -o $newmod.mod $newmod.te
semodule_package -o $newmod.pp -m $newmod.mod
semodule -i $newmod.pp

Re-enable selinux, restart the daemon, confirm that it’s working properly

setenforce 1
systemctl stop mydaemon
ps -eZ | grep mydaemon

# Confirm it's not running

rm -f /var/log/mydaemon.log 
systemctl start mydaemon
ps -eZ | grep mydaemon

# Confirm it's running, and confined by selinux under mydaemon_t
system_u:system_r:mydaemon_t:s0   54205 ?        00:00:00 mydaemon

# Confirm it's successfully writing
cat /var/log/mydaemon.log
  • No labels