tomoyotitle.png

Chapter 7: How do I enforce policy?

7.1. Enabling enforcing mode

Once domain and exception policy have been sufficiently modified, the domain can be set to enforcing mode.

Run the policy editor and change the target domains to profile 3:

editpolicy-httpd-profile3.png

Press the "@" key to switch to the process list. Verify that the "/usr/sbin/httpd" process and descendants are assigned profile number 3:

editpolicy-httpd-process3.png

Quit the policy editor and try an operation which is permitted by policy:

operation-permitted.png

The operation was successfully completed, as sending mail is permitted by policy.

Let's try an operation which is not permitted by policy:

unix-penguin.png

Although it appears to be have been completed successfully, the warning message by /bin/mail shows that the input was empty and so the execution of /bin/cat was rejected:

unix-penguin-rejected.png

If the profile is configured as "PREFERENCE::enforcing={ verbose=yes }" (this is default), the "ERROR:" messages will be printed to the console when policy violations occur:

enforcing-error.png

7.2. Notification daemon

tomoyo-notifyd is a daemon program that can be used to report the occurrence of a policy violation. For example, to notify "root@example.com" via mail, up to once per an hour, add the following to "/etc/crontab":

00 * * * * root /usr/lib/tomoyo/tomoyo-notifyd 0 'mail root@example.com'

Rejected requests will be notified via mail:

# mail
Mail version 8.1 6/6/93.  Type ? for help.
"/var/spool/mail/root": 1 message 1 unread
>U  1 root@localhost.local  Tue Jan 12 16:19  18/1234
&
Message 1:
From root@localhost.localdomain  Tue Jan 12 16:19:17 2010
Date: Tue, 12 Jan 2010 16:19:17 +0900
From: root <root@localhost.localdomain>
To: root@localhost.localdomain

Q0-0
#2010-01-12 16:19:17# profile=3 mode=enforcing (global-pid=4836) task={ pid=4836 ppid=4835 uid=48 gid=48 euid=48 egid=48 suid=48 sgid=48 fsuid=48 fsgid=48 }
<kernel> /usr/sbin/httpd /bin/sh
allow_execute /bin/cat

This log reports that execution of /bin/cat was requested by /bin/sh, which was invoked by /usr/sbin/httpd. As its first line has "mode=enforcing", this request was rejected.

7.3. Handling policy violations in real-time

Policy violations can be handled in real time using tomoyo-queryd. This is especially useful during the installation of software updates. When packages are updated, policy may need to be altered if any of the following occur:

The ideal way to update policy is to rebuild from scratch using learning mode as has been described. However, it is not desirable to change a domain from enforcing mode to learning mode once the system has entered into a production state as this will cause the system to become vulnerable to attack through this unrestricted domain.

Fortunately, tomoyo-queryd can help administrators update policy in real-time while running in "Enforcing Mode". Please note that this method cannot always support every case and the resulting policy may not be fully optimized.

7.3.1. Example usage of "tomoyo-queryd"

The video below demonstrates example usage of tomoyo-queryd, which is summarised in the text below:

Use tomoyo-queryd to view, in realtime, the access requests that have been rejected by policy:

# /usr/sbin/tomoyo-queryd
Monitoring /sys/kernel/security/tomoyo/query . Press Ctrl-C to terminate.

Policy violations may occur while updating packages due to unusual behaviour (e.g. restarting daemons). When a policy violation occurs, a prompt appears in the tomoyo-queryd console:

#2010-01-10 12:29:35# profile=3 mode=enforcing (global-pid=4561) task={ pid=4561 ppid=4557 uid=0 gid=0 euid=0 egid=0 suid=0 sgid=0 fsuid=0 fsgid=0 }
<kernel> /etc/rc.d/init.d/cups
allow_execute /bin/sleep
Allow? ('Y'es/'N'o/'R'etry/'S'how policy/'A'dd to policy and retry):

This indicates that a process that belongs to the domain "<kernel> /etc/rc.d/init.d/sshd" attempted to execute /bin/sleep. Usually this would be instantly denied, but since tomoyo-queryd is running, the kernel waits for the administrators decision before accepting or rejecting the request.

Press "Y" to grant the request.
Press "N" to reject the request.
Press "R" to retry the request (for example after editing domain policy manually).
Press "S" to show domain policy for the process.
Press "A" to append the request to domain policy and retry (a chance to edit the request is given first).

Do not grant access requests unconditionally. Policy violations are not always due to updating packages, but may be malicious requests by attackers.

Do not logout while this program is running. Access requests that violated policy are kept pending and may otherwise sleep forever. Monitor the output to make sure programs have the minimum permissions to run properly. If permissions are missing, they will be printed to the console output. Once policy has been updated, the program can be stopped with "Ctrl-C".

#2010-01-10 12:30:10# profile=3 mode=enforcing (global-pid=4630) task={ pid=4630 ppid=4629 uid=0 gid=0 euid=0 egid=0 suid=0 sgid=0 fsuid=0 fsgid=0 }
<kernel> /usr/sbin/acpid
allow_unlink /var/run/acpid.socket
Allow? ('Y'es/'N'o/'R'etry/'S'how policy/'A'dd to policy and retry):a
Enter new entry> allow_unlink /var/run/acpid.socket
Added 'allow_unlink /var/run/acpid.socket'.

The pathname /usr/lib/libpurple.so.0.5.9 was deleted. Deleted from globally readable file.

The pathname /usr/lib/libpurple-client.so.0.5.9 was deleted. Deleted from globally readable file.

When the location of shared libraries in "/etc/ld.so.cache" has changed, "tomoyo-queryd" automatically appends shared libraries to exception policy using "allow_read" directive. The following line indicates that the pathname "/usr/lib/libpurple.so.0.6.3" was appended to exception policy as it was registered to "/etc/ld.so.cache":

The pathname /usr/lib/libpurple.so.0.6.3 was created. Appended to globally readable file.

In addition, "tomoyo-queryd" automatically removes the pathname from exception policy when it is unregistered from "/etc/ld.so.cache":

The pathname /usr/lib/libpurple.so.0.5.9 was deleted. Deleted from globally readable file.

Note that this program directly edits policy currently loaded into the kernel, so run tomoyo-savepolicy to save policy to disk, otherwise policy will be lost on shutdown.

# /usr/sbin/tomoyo-savepolicy

7.3.2. Example output from "tomoyo-queryd"

This is an example of what the output might look like while running tomoyo-queryd:

#2010-01-10 12:27:10# profile=3 mode=enforcing (global-pid=4210) task={ pid=4210 ppid=4205 uid=0 gid=0 euid=0 egid=0 suid=0 sgid=0 fsuid=0 fsgid=0 }
<kernel> /etc/rc.d/init.d/sshd
allow_ioctl /dev/null 0x5401
Allow? ('Y'es/'N'o/'R'etry/'S'how policy/'A'dd to policy and retry):s
# select global-pid=4210
<kernel> /etc/rc.d/init.d/sshd
use_profile 3

allow_read /bin/bash
allow_read/write /dev/tty
allow_read/write /dev/pts/\$
allow_read /usr/lib/locale/locale-archive
allow_read /etc/nsswitch.conf
allow_read /etc/passwd
allow_read /etc/rc.d/init.d/sshd
allow_read /etc/rc.d/init.d/functions
allow_execute /sbin/consoletype
allow_read /etc/profile.d/lang.sh
allow_read /etc/sysconfig/i18n
allow_read /etc/sysconfig/init
allow_execute /sbin/runlevel
allow_execute /bin/cp
allow_execute /usr/sbin/sshd
allow_execute /bin/touch
allow_read/write /dev/console
allow_execute /bin/unicode_start
allow_read /var/run/sshd.pid
allow_write /dev/null
allow_execute /bin/usleep
allow_execute /bin/rm
allow_execute /usr/bin/killall
allow_execute /usr/bin/rhgb-client
allow_execute /bin/sleep
allow_ioctl /dev/console 0x5401
allow_ioctl /etc/rc.d/init.d/sshd 0x5401
allow_ioctl /var/run/sshd.pid 0x5401
allow_ioctl /dev/pts/\$ 0x5401


#2010-01-10 12:27:20# profile=3 mode=enforcing (global-pid=4210) task={ pid=4210 ppid=4205 uid=0 gid=0 euid=0 egid=0 suid=0 sgid=0 fsuid=0 fsgid=0 }
<kernel> /etc/rc.d/init.d/sshd
allow_ioctl /dev/null 0x5401
Allow? ('Y'es/'N'o/'R'etry/'S'how policy/'A'dd to policy and retry):a
Enter new entry> allow_ioctl /dev/null 0x5401
Added 'allow_ioctl /dev/null 0x5401'.

The pathname /usr/lib/libpurple.so.0.6.3 was created. Appended to globally readable file.

The pathname /usr/lib/libpurple-client.so.0.6.3 was created. Appended to globally readable file.

----------------------------------------
#2010-01-10 12:29:35# profile=3 mode=enforcing (global-pid=4561) task={ pid=4561 ppid=4557 uid=0 gid=0 euid=0 egid=0 suid=0 sgid=0 fsuid=0 fsgid=0 }
<kernel> /etc/rc.d/init.d/cups
allow_execute /bin/sleep
Allow? ('Y'es/'N'o/'R'etry/'S'how policy/'A'dd to policy and retry):a
Enter new entry> allow_execute /bin/sleep
Added 'allow_execute /bin/sleep'.

#2010-01-10 12:29:55# profile=3 mode=enforcing (global-pid=4561) task={ pid=4561 ppid=4557 uid=0 gid=0 euid=0 egid=0 suid=0 sgid=0 fsuid=0 fsgid=0 }
<kernel> /etc/rc.d/init.d/cups
# wants to create domain
<kernel> /etc/rc.d/init.d/cups /bin/sleep
Allow? ('Y'es/'N'o/'R'etry):y

#2010-01-10 12:29:58# profile=3 mode=enforcing (global-pid=4561) task={ pid=4561 ppid=4557 uid=0 gid=0 euid=0 egid=0 suid=0 sgid=0 fsuid=0 fsgid=0 }
<kernel> /etc/rc.d/init.d/cups /bin/sleep
allow_read /usr/lib/locale/locale-archive
Allow? ('Y'es/'N'o/'R'etry/'S'how policy/'A'dd to policy and retry):a
Enter new entry> allow_read /usr/lib/locale/locale-archive
Added 'allow_read /usr/lib/locale/locale-archive'.

----------------------------------------
#2010-01-10 12:30:10# profile=3 mode=enforcing (global-pid=4630) task={ pid=4630 ppid=4629 uid=0 gid=0 euid=0 egid=0 suid=0 sgid=0 fsuid=0 fsgid=0 }
<kernel> /usr/sbin/acpid
allow_unlink /var/run/acpid.socket
Allow? ('Y'es/'N'o/'R'etry/'S'how policy/'A'dd to policy and retry):a
Enter new entry> allow_unlink /var/run/acpid.socket
Added 'allow_unlink /var/run/acpid.socket'.

The pathname /usr/lib/libpurple.so.0.5.9 was deleted. Deleted from globally readable file.

The pathname /usr/lib/libpurple-client.so.0.5.9 was deleted. Deleted from globally readable file.

7.4. Enable enforcing mode for every domain

Once you are familiar with the methods and tools described in the previous chapters, it will be possible to develop policy for every domain in the system. Placing every domain in "Enforcing Mode" will reduce the points of vulnerability through which a system might be compromised. Thus, all the previous steps should be repeated for all the other domains.

7.5. Beyond the core topics

The chapters in this guide so far aim to provide enough knowledge to set up TOMOYO Linux on a system. In order to further improve your knowledge, please read on. The following chapters cover advanced topics that are not absolutely essential, but can help to increase the security of a system. The appendices found at the end of this guide can also be very helpful, particularly the specification.

Remember that security is only as strong as the weakest point. While proper use of the Mandatory Access Control possible with TOMOYO Linux will strengthen a system against being compromised, other security practices and system-hardening methods must not be forgotten. These methods are beyond the scope of this guide but should be eagerly pursued by any who wish to maximize the security of their system.