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:
Press the "@" key to switch to the process list. Verify that the "/usr/sbin/httpd
" process and descendants are assigned profile number 3:
Quit the policy editor and try an operation which is permitted by policy:
The operation was successfully completed, as sending mail is permitted by policy.
Let's try an operation which is not permitted by policy:
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:
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:
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 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 pathnames of files have changed
- The dependencies of files have changed
- The access permissions required have changed or increased
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.