<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html lang="en-US">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=us-ascii">
<meta http-equiv="Content-Style-Type" content="text/css">
<title>The world of TOMOYO Linux&nbsp;&nbsp;The fourth installment: "Let's tune policy."</title>
<link rel="stylesheet" href="http://tomoyo.sourceforge.jp/tomoyo.css" media="all" type="text/css">
</head>
<body>
<p>Info: Version <a href="../1.8/">1.8.x</a> is available.</p>
<p style="text-align:right;"><a href="tutorial-4.html.ja">Japanese Page</a></p>
<p style="text-align:right;">Last modified: $Date: 2013-01-17 23:04:43 +0900 (Thu, 17 Jan 2013) $</p>

<h1>The world of TOMOYO Linux<br>The fourth installment: "Let's tune policy."</h1>

<h2>Contents of this installment.</h2>

<p>In this installment, I explain how to tune policy which is essential for fully mastering TOMOYO Linux and functionality for assisting policy tuning.</p>

<h2>About functionality for assisting policy modification</h2>

<p>If you are using secure OS, processes being hijacked or administrator's privileges being stolen won't immediately cause fatal damage. Thus, you may feel easier than normal OS for instantly updating systems, but there is no justification for overconfidence. You should apply updates and keep your systems at the best condition. Regarding OS with mandatory access control functionality, the system's behavior is restricted by policy configuration defined by administrator. Therefore, you may need to adjust policy configuration in order to keep software work properly when program's dependency has changed due to software updates. In TOMOYO Linux, administrators define policy configuration by themselves. Thus, administrators modify policy configuration by themselves. In this installment, I explain functionality for assisting adjusting policy configuration which will be needed by updating softwares.</p>

<p>TOMOYO Linux provides two types of enforcing mode. The former (Fig. 1) type is that access requests that violated policy in enforcing mode are immediately rejected. The latter (Fig. 2) type is that access requests that violated policy in enforcing mode are judged by administrator's interactive operation. The latter type is useful when policy violation occurred in enforcing mode or when you need to adjust policy by software updates.</p>

<table border="1" summary="fig">
<tr><td>
&diams; Fig. 1&nbsp;&nbsp;Reject immediately requests which violate policy<br>
<img src="tutorial/fig-4-1-en.png" alt="fig-4-1-en.png" width="800" height="480">
</td></tr>
</table>

<table border="1" summary="fig">
<tr><td>
&diams; Fig. 2&nbsp;&nbsp;Interactively judge requests which violate policy<br>
<img src="tutorial/fig-4-2-en.png" alt="fig-4-2-en.png" width="800" height="480">
</td></tr>
</table>

<h3>Tools for using this functionality</h3>

<p>TOMOYO Linux provides programs listed in Fig. 3 for assisting adjusting policy configuration.</p>

<table border="1" summary="fig">
<tr><td>
&diams; Fig. 3&nbsp;&nbsp;Programs for managing TOMOYO Linux<br>
<table border="1" summary="fig">
<tr><td>Name of program</td><td>Role of program</td></tr>
<tr><td>ccs-queryd</td><td>Interactively grant access requests</td></tr>
</table>
</td></tr>
</table>

<h3>Operation example on console login session</h3>

<p>I explain using restricting login session as an example. To avoid being locked out by operation errors, I use "example" user account. Also, I switch "root" user and "example" user by switching console windows. You can switch console windows using "ALT" + one of "F1"&sdot;&sdot;&sdot;"F6" keys. Open "window 1" by pressing "ALT" + "F1" keys, and login as "root" user. Assign different shells for "root" user and "example" user. This is for creating different domains for these users by using different login shells, and for applying restriction against specific login shell's domains. In this series, I'm using /bin/bash for "root" user's shell. Thus, I assign /bin/tcsh for "example" user's shell. (Fig. 4)</p>

<table border="1" summary="fig">
<tr><td>
&diams; Fig. 4&nbsp;&nbsp;Assign /bin/tcsh to "example" user
<pre>
# usermod -s /bin/tcsh example
</pre>
</td></tr>
</table>

<p>Next, open "window 2" by pressing "ALT" + "F2" keys, and login as "example" user. If you are using CentOS 5.9, the domain for console login will be "&lt;kernel&gt; /sbin/mingetty /bin/login /bin/tcsh". (If you login via /usr/sbin/sshd , the domain will be "&lt;kernel&gt; /usr/sbin/sshd /bin/tcsh".) Switch to "window1" and assign a profile for enforcing mode (i.e. profile 3) to domains for "example" user's login shell. (Fig. 5)</p>

<table border="1" summary="fig">
<tr><td>
&diams; Fig. 5&nbsp;&nbsp;Assign a profile for enforcing mode example to "example" user's shell domain (window 2)
<pre>
# /usr/sbin/ccs-setprofile -r 3 '&lt;kernel&gt; /sbin/mingetty /bin/login /bin/tcsh'
</pre>
</td></tr>
</table>

<p>Now, almost everything is forbidden for "example" user's shell (i.e. "window 2"). (Fig. 6)</p>

<table border="1" summary="fig">
<tr><td>
&diams; Fig. 6&nbsp;&nbsp;Verify the result of applying Fig. 5
<pre>
$ ls
/bin/ls: Operation not permitted.
$ cat /etc/passwd
/bin/cat: Operation not permitted.
</pre>
</td></tr>
</table>

<p>By using ccs-queryd command (Fig. 7), you can ask for administrator's decision when a process which belongs to domains with a profile for enforcing mode requested an access that violated policy instead of immediately reject the access. This feature is specific to TOMOYO Linux, not available in SELinux or AppArmor.</p>

<table border="1" summary="fig">
<tr><td>
&diams; Fig. 7&nbsp;&nbsp;Executing ccs-queryd command
<pre>
# /usr/sbin/ccs-queryd
</pre>
</td></tr>
</table>

<p>Switch to "window 2" and request for execution of /bin/ls command. (Fig. 8)</p>

<table border="1" summary="fig">
<tr><td>
&diams; Fig. 8&nbsp;&nbsp;Executing ls command
<pre>
$ /bin/ls
</pre>
</td></tr>
</table>

<p>Last time, the request was rejected immediately. But this time, it is stopped instead of rejected. Switch to "window 1" while keeping this state, and you will see prompt like Fig. 9.</p>

<table border="1" summary="fig">
<tr><td>
&diams; Fig. 9&nbsp;&nbsp;Prompt shown on window 1 after executing Fig. 8
<pre>
#2010-05-13 15:29:35# profile=3 mode=enforcing (global-pid=4561) task={ pid=4561 ppid=4557 uid=502 gid=502 euid=502 egid=502 suid=502 sgid=502 fsuid=502 fsgid=502 state[0]=0 state[1]=0 state[2]=0 type!=execute_handler } path1={ uid=0 gid=0 ino=1507379 major=8 minor=1 perm=0755 type=file } path1.parent={ uid=0 gid=0 ino=1507329 perm=0755 } exec={ realpath="/bin/ls" argc=1 envc=6 argv[]={ "ls" } envp[]={ "TERM=xterm" "PATH=/sbin:/usr/sbin:/bin:/usr/bin" "PWD=/" "LANG=en_US.UTF-8" "SHLVL=1" "_=/bin/cat" } }
&lt;kernel&gt; /sbin/mingetty /bin/login /bin/tcsh
allow_execute /bin/ls
Allow? ('Y'es/'N'o/'R'etry/'S'how policy/'A'dd to policy and retry):
</pre>
</td></tr>
</table>

<p>The first line shows information about the process which requested an access that violated policy and about the file the process is requesting. The second line shows domainname of domain which the process which requested an access that violated policy belongs to. The third line shows the access that violated policy. This way the request is displayed in the same syntax with domain policy. If you press "Y" key here, the access is granted. If you press "N" key here, the access is rejected. If you pressed "Y" key, the execution of /bin/ls is granted, but since domain policy does not contain domain for executing /bin/ls , and prompt like Fig. 10 will be printed.</p>

<table border="1" summary="fig">
<tr><td>
&diams; Fig. 10&nbsp;&nbsp;Prompt for asking for permission to create a domain
<pre>
#2010-05-13 15:29:40# profile=3 mode=enforcing (global-pid=4561) task={ pid=4561 ppid=4557 uid=502 gid=502 euid=502 egid=502 suid=502 sgid=502 fsuid=502 fsgid=502 state[0]=0 state[1]=0 state[2]=0 type!=execute_handler } path1={ uid=0 gid=0 ino=1507379 major=8 minor=1 perm=0755 type=file } path1.parent={ uid=0 gid=0 ino=1507329 perm=0755 } exec={ realpath="/bin/ls" argc=1 envc=6 argv[]={ "ls" } envp[]={ "TERM=xterm" "PATH=/sbin:/usr/sbin:/bin:/usr/bin" "PWD=/" "LANG=en_US.UTF-8" "SHLVL=1" "_=/bin/cat" } }
&lt;kernel&gt; /sbin/mingetty /bin/login /bin/tcsh
# wants to create domain
&lt;kernel&gt; /sbin/mingetty /bin/login /bin/tcsh /bin/ls
Allow? ('Y'es/'N'o/'R'etry):
</pre>
</td></tr>
</table>

<p>If you pressed "Y" key here, the domain for /bin/ls is created and the process can execute /bin/ls . If you pressed "N" key here, execution of /bin/ls is rejected because the process cannot find domain for /bin/ls . If you granted creation of domain for /bin/ls , you will see prompt like Fig. 11.</p>

<table border="1" summary="fig">
<tr><td>
&diams; Fig. 11&nbsp;&nbsp;Prompt after allowing domain creation
<pre>
#2010-05-13 15:29:45# profile=3 mode=enforcing (global-pid=4561) task={ pid=4561 ppid=4557 uid=502 gid=502 euid=502 egid=502 suid=502 sgid=502 fsuid=502 fsgid=502 state[0]=0 state[1]=0 state[2]=0 type!=execute_handler } path1={ uid=0 gid=0 ino=1507380 major=8 minor=1 perm=0755 type=file } path1.parent={ uid=0 gid=0 ino=1507329 perm=0755 }
&lt;kernel&gt; /sbin/mingetty /bin/login /bin/tcsh /bin/ls
allow_read /etc/selinux/config
Allow? ('Y'es/'N'o/'R'etry/'S'how policy/'A'dd to policy and retry):
</pre>
</td></tr>
</table>

<p>Since the domain for /bin/ls was just created, no permissions are given to this domain. Read the prompt and carefully judge whether the access should be granted or not and answer. If you press "A" key, you can add permission to domain policy (after editing the permission if you needed) and retry the request. For example, if you want to allow not only /etc/passwd but also all /etc/\* except /etc/\*shadow\* , change /etc/passwd to /etc/\*\-\*shadow\* and then press "Enter" key.</p>

<p>To terminate ccs-queryd program, press "CTRL" + "C" keys.</p>

<h3>Precautions when using ccs-queryd command</h3>

<p>You have to be aware two things when using ccs-queryd command. One is that you must not unconditionally grant the request. The cause of policy violation may be attacks by malicious users. If you grant access requests caused by attacks by malicious users, the protection by mandatory access control becomes invalid. The other is that if "ccs-queryd" is running, the access requests that violated policy are kept pending until administrator answers. Thus, never leave or logout while "ccs-queryd" is running.</p>

<h3>About shared libraries</h3>

<p>Regarding shared libraries which are registered in /etc/ld.so.cache (which you can view by "/sbin/ldconfig -NXp") are specified using "allow_read" keyword in exception policy (i.e. allow read access by any domain) by init_policy command executed upon installing TOMOYO Linux. Therefore, you don't need to specify "allow_read" keyword in each domain in domain policy. But restarting daemon programs after updating software might fail if the filename of shared libraries was changed and the change is not reflected to exception policy. Regarding shared libraries newly installed, read access to these files will be rejected (i.e. policy violated) if these files are requested before reflecting to exception policy or domain policy.</p>

<p>It is possible to let ccs-queryd command detect read access to shared libraries and append permissions to policy configuration. But in this case, it will be convenient for you to automatically reflect change of shared libraries to exception policy. Therefore, ccs-queryd command monitors not only policy violations but also changes in /etc/ld.so.cache (which contains the list of shared libraries) and reflects to exception policy.</p>

<h3>An operation example for actual service</h3>

<p>Please see <a href="http://tomoyo.sourceforge.jp/1.7/enforcing.html.en#using_interactive_mode">Handling policy violation arising in during software updates</a>.</p>

<h2>About removing garbage from policy configuration</h2>

<h3>Tools for using this functionality</h3>

<p>TOMOYO Linux provides programs listed in Fig. 12 for assisting removing unnecessary permissions from policy configuration.</p>

<table border="1" summary="fig">
<tr><td>
&diams; Fig. 12&nbsp;&nbsp;Programs for managing TOMOYO Linux<br>
<table border="1" summary="fig">
<tr><td>Name of program</td><td>Role of program</td></tr>
<tr><td>ccs-findtemp</td><td>Detect nonexistent pathnames</td></tr>
<tr><td>ccs-domainmatch</td><td>Find domains which contain specified permissions</td></tr>
</table>
</td></tr>
</table>

<p>By using these programs, you can detect and remove redundant pathnames (e.g. not yet patternized temporary files and library files deleted by software updates).</p>

<h3>An operation example on console session</h3>

<p>To handily try this functionality, I explain using console session. Do operations listed in Fig. 13 in learning mode.</p>

<table border="1" summary="fig">
<tr><td>
&diams; Fig. 13&nbsp;&nbsp;Operations for learning mode
<pre>
# touch /tmp/abc12345
# rm -f /tmp/abc12345
</pre>
</td></tr>
</table>

<p>By doing these operations, touch command and rm command learned access to /tmp/abc12345 but the file /tmp/abc12345 no longer exists. If these operations were redundant, redundant permissions (or garbage) which won't be used are left. Pathnames which exists in policy configuration but do not exist are likely either used as temporary files or deleted by software updates. By using ccs-findtemp command, pathnames which exists in policy configuration but do not exist are printed. Note that Fig. 14 shows only /tmp/abc12345 but other pathnames will be also printed for actual systems.</p>

<table border="1" summary="fig">
<tr><td>
&diams; Fig. 14&nbsp;&nbsp;Executing ccs-findtemp command
<pre>
# /usr/sbin/ccs-findtemp &lt; /proc/ccs/domain_policy
/tmp/abc12345
# /usr/sbin/ccs-findtemp --with-domainname &lt; /proc/ccs/domain_policy
&lt;kernel&gt; /sbin/mingetty /bin/login /bin/bash /bin/touch
/tmp/abc12345
/tmp/abc12345
&lt;kernel&gt; /sbin/mingetty /bin/login /bin/bash /bin/rm
/tmp/abc12345
# /usr/sbin/ccs-domainmatch /tmp/abc12345
&lt;kernel&gt; /sbin/mingetty /bin/login /bin/bash /bin/touch
allow_create /tmp/abc12345 0666
allow_write /tmp/abc12345
&lt;kernel&gt; /sbin/mingetty /bin/login /bin/bash /bin/rm
allow_unlink /tmp/abc12345
</pre>
</td></tr>
</table>

<p>By executing ccs-domainmatch command with pathnames printed by ccs-findtemp command as command line arguments, domainnames which contains permission against command line arguments are printed. If you think the permission is redundant, you can execute ccs-editpolicy command and go to appropriate domains and delete the permission.</p>

<h2>Saving access logs</h2>

<p>TOMOYO Linux can generate "Log of access requests which did not violate policy" (in short, "access granted log") and "Log of access requests which violated policy" (in short, "access rejected log"). You can use a daemon program ccs-auditd for reading "access granted log" and "access rejected log" from kernel and writing to files on disk.</p>

<h3>Let's save access logs</h3>

<p>First, create directory for saving access logs. (Fig. 15)</p>

<table border="1" summary="fig">
<tr><td>
&diams; Fig. 15&nbsp;&nbsp;Creating directory for saving access logs
<pre>
# mkdir -p /var/log/tomoyo
</pre>
</td></tr>
</table>

<p>Next, append a line in Fig. 16 to /etc/rc.d/rc.local . The first argument is the location to save "access granted logs" and the second argument is the location to save "access rejected logs".</p>

<table border="1" summary="fig">
<tr><td>
&diams; Fig. 16&nbsp;&nbsp;Contents to append to /etc/rc.d/rc.local
<pre>
/usr/sbin/ccs-auditd /dev/null /var/log/tomoyo/reject_log.conf
</pre>
</td></tr>
</table>

<p>Then, create /etc/logrotate.d/tomoyo with the contents in Fig. 17 in order to let logrotate command rotate automatically. Be sure to specify "nocreate" option, or access logs won't be saved after the first rotation.</p>

<table border="1" summary="fig">
<tr><td>
&diams; Fig. 17&nbsp;&nbsp;Configure logrotate to rotate access logs ( /etc/logrotate.d/tomoyo )
<pre>
/var/log/tomoyo/reject_log.conf {
    weekly
    rotate 9
    missingok
    notifempty
    nocreate
}
</pre>
</td></tr>
</table>

<p>If you don't want to save access granted logs, you can specify "PREFERENCE::audit={ max_grant_log=0 }" in the profiles and specify /dev/null as the location to save "access granted logs". Be careful with disk's free space when saving access granted logs because ccs-auditd command does not have filtering functionality. If you don't want to save access rejected logs, you can specify "PREFERENCE::audit={ max_reject_log=0 }" in the profiles and specify /dev/null as the location to save "access rejected logs". But saving "access rejected logs" is recommended. If you don't want to save both "access granted logs" and "access rejected logs", you don't need to run ccs-auditd command. Also, you can expect saving memory and improvement of response speed by specifying "PREFERENCE::audit={ max_grant_log=0 max_reject_log=0 }" in the profiles.</p>

<h3>Let's browse access logs</h3>

<p>Access logs are in the form of domain policy (Fig. 18). Therefore you can append access logs to /etc/ccs/domain_policy.conf .</p>

<table border="1" summary="fig">
<tr><td>
&diams; Fig. 18&nbsp;&nbsp;Contents of access logs ( /var/log/tomoyo/reject_log.conf )
<pre>
# cat /var/log/tomoyo/reject_log.conf
#2010-05-13 15:36:22# profile=3 mode=enforcing (global-pid=4350) task={ pid=4350 ppid=4312 uid=500 gid=500 euid=500 egid=500 suid=500 sgid=500 fsuid=500 fsgid=500 state[0]=0 state[1]=0 state[2]=0 type!=execute_handler } path1={ uid=501 gid=501 ino=393251 major=253 minor=0 perm=0555 type=file } path1.parent={ uid=0 gid=0 ino=393217 perm=01777 }
&lt;kernel&gt; /sbin/mingetty /bin/login /bin/bash /bin/cat
allow_read /tmp/testfile2

#2010-05-13 15:36:36# profile=3 mode=enforcing (global-pid=4518) task={ pid=4518 ppid=4480 uid=501 gid=501 euid=501 egid=501 suid=501 sgid=501 fsuid=501 fsgid=501 state[0]=0 state[1]=0 state[2]=0 type!=execute_handler } path1={ uid=500 gid=500 ino=393250 major=253 minor=0 perm=0555 type=file } path1.parent={ uid=0 gid=0 ino=393217 perm=01777 }
&lt;kernel&gt; /sbin/mingetty /bin/login /bin/bash /bin/cat
allow_read /tmp/testfile1
</pre>
</td></tr>
</table>

<p>Access logs contain information such as process's credentials (e.g. UID) in addition to requested pathnames. This information can be used for specifying conditional access control list which I explain in the next installment.</p>

<h2>Trailer</h2>

<p>In this installment, I explained how to tune policy. In the next installment, I explain conditional access control list. Don't miss it!</p>

<p><a href="tutorial-3.html.en">Go back to the third installment.</a>&nbsp;&nbsp;<a href="tutorial-5.html.en">Proceed to the fifth installment.</a></p>

<hr>

<p><a href="index.html.en#tutorial">Return to index page.</a></p>
<p><a href="http://sourceforge.jp/"><img src="http://sourceforge.jp/sflogo.php?group_id=1973" width="96" height="31" alt="sflogo.php" title="SourceForge.jp"></a></p>
</body>
</html>
