Info: Version 1.7.x is available.

Japanese Page

# TOMOYO Linux Install manual

Last modified: $Date: 2012-03-02 10:34:04 +0900 (Fri, 02 Mar 2012) $

# Installation

## Install TOMOYO Linux kernel and tool

To compile kernel, see TOMOYO Linux kernel compilation. To compile tool, run the following commands.

wget -O ccs-tools-1.6.9-20120301.tar.gz 'http://sourceforge.jp/frs/redir.php?m=jaist&f=/tomoyo/30298/ccs-tools-1.6.9-20120301.tar.gz' tar -zxf ccs-tools-1.6.9-20120301.tar.gz make -C ccstools/ install

## Create Policy

Run the following command.

/usr/lib/ccs/init_policy.sh

## Reboot

Reboot with TOMOYO Linux kernel.

reboot

After the system boots, login as root.

# Preparation

## About domains

The MAC in TOMOYO Linux is applied in the units of domains. Every process belongs to single domain, and basically the process will transit to different domain whenever it executes a program. The name of a domain is a concatenated string expression for the process execution history. For example, the name of domain which the kernel belongs to is "<kernel>", the name of domain which /sbin/init invoked by the kernel belongs to is "<kernel> /sbin/init", the name of domain which /etc/rc.d/rc invoked by the /sbin/init belongs to is "<kernel> /sbin/init /etc/rc.d/rc". The exceptions of this transition rule are described later.

## About profiles

TOMOYO Linux can perform several MACs besides MAC for files, but to reduce the load of policy managements, you can disable MACs you think unnecessary. The configurable parameters are determined in the kernel compilation time. Only topics included in /proc/ccs/profile are configurable.

Name | Control | Default value | Learning mode supported
COMMENT | A line of text that describes the content of the profile. |  | -
MAC_FOR_FILE | Enable Mandatory Access Control(MAC) for files. | disabled | Yes
MAC_FOR_ARGV0 | Enable MAC for argv[0] checks. | disabled | Yes
MAC_FOR_ENV | Enable MAC for environment variables' names. | disabled | Yes
MAC_FOR_CAPABILITY:: | Enable MAC for capabilities. There are 31 types of capabilities and you can enable/disable selectively. | disabled | Yes
MAC_FOR_NETWORK | Enable MAC for network addresses and ports. | disabled | Yes
MAC_FOR_SIGNAL | Enable MAC for signal. | disabled | Yes
DENY_CONCEAL_MOUNT | Forbid mount requests that hides an existing mount. | disabled | No
RESTRICT_CHROOT | Enable restrictions for chroot directories. | disabled | Yes
RESTRICT_MOUNT | Enable restrictions for mount parameters. | disabled | Yes
RESTRICT_UNMOUNT | Forbid unmount requests for specified directories. | disabled | No
RESTRICT_PIVOT_ROOT | Enable restrictions for pivot_root directories. | disabled | Yes
RESTRICT_AUTOBIND | Forbid selecting specific local port number when automatic local port binding happens. | disabled | No
MAX_ACCEPT_ENTRY | Limits the max number of ACL entries that are automatically appended during learning mode. | 2048 | -
MAX_GRANT_LOG | Limits the max number of access requests that didn't violate policies. | 1024 | -
MAX_REJECT_LOG | Limits the max number of access requests that violated policies. | 1024 | -
TOMOYO_VERBOSE | Dump domain policy violation messages to syslog. | enabled | -
SLEEP_PERIOD | Specifies how long should the process that violated policy in enforcing mode sleep for, in 0.1 seconds. | 0 | -

You can give the following values for RESTRICT_AUTOBIND

Value | Meaning
disabled | Off. Works as if regular kernel.
enabled | On

You can give any integer greater or equals to 0 for MAX_ACCEPT_ENTRY, MAX_GRANT_LOG, MAX_REJECT_LOG and SLEEP_PERIOD.

You can give the following values for TOMOYO_VERBOSE

Value | Meaning
disabled | Don't dump domain policy violation messages.
enabled | Dump domain policy violation messages.

You can give the following values for all but listed above.

Value | Meaning
disabled | Disabled. Works as if regular kernel.
learning | Learning mode. Not rejected if the request violates policy. Automatically appended to policy.
permissive | Permissive mode. Not rejected if the request violates policy. Not appended to policy automatically.
enforcing | Enforcing mode. Rejected if the request violates policy.

## Creating profiles

Write profiles for "disabled", "learning mode", "permissive mode" and "enforcing mode" in /etc/ccs/profile.conf . The following example is profiles for applying MAC for files and networks. The heading integer is name of profile that is used for assigning profiles to domains. The profile name takes an integer between 0 and 255.

0-COMMENT=----- All Disabled ----- 1-COMMENT=----- FILE and NETWORK with Learning Mode ----- 1-MAC_FOR_FILE=learning 1-MAC_FOR_NETWORK=learning 2-COMMENT=----- FILE and NETWORK with Permissive Mode ----- 2-MAC_FOR_FILE=permissive 2-MAC_FOR_NETWORK=permissive 3-COMMENT=----- FILE and NETWORK with enforcing mode ----- 3-MAC_FOR_FILE=enforcing 3-MAC_FOR_NETWORK=enforcing 3-MAX_GRANT_LOG=0

In this manual, we assume that
profile 0 is for "disabled",
profile 1 is for "learning mode",
profile 2 is for "permissive mode",
profile 3 is for "enforcing mode".

You won't need to edit profiles after you once create them because you can control how to apply MAC on per-a-domain basis by changing profiles of domains. But if you edited /etc/ccs/profile.conf by some reason (for example, you want to add profiles), run the following command.

/usr/sbin/ccs-loadpolicy p

To see the profiles currently configured, run the following command.

cat /proc/ccs/profile

## Assigning profiles to domains

To assign profiles to domains, use "ccs-setprofile" command. For example,

/usr/sbin/ccs-setprofile -r 0 '<kernel>'

will assign profile 0 to all domains. Also,

/usr/sbin/ccs-setprofile -r 1 '<kernel> /sbin/init'

will assign profile 1 to all domains whose domainname starts with "<kernel> /sbin/init". Also,

/usr/sbin/ccs-setprofile 2 '<kernel> /sbin/init'

will assign profile 2 to only domain whose domainname is "<kernel> /sbin/init".

To see the profiles currently assigned to domains, run the following command. A list with profiles and domainnames are shown.

cat /proc/ccs/.domain_status

Basically, you don't need to switch profiles of all domains at boot because you can assign profiles by per-a-domain basis and the profile previously assigned remains in the domain policy file (/etc/ccs/domain_policy.conf) using "use_profile" directive. But if you can't boot by some reason (for example, you assigned profiles for "enforcing mode" before giving enough permissions to domains), you can pass "CCS=disabled" to the kernel's command line to boot the system with MAC disabled.

To see the profiles of currently running processes and their domainnames, use "ccs-ccstree" command.

/usr/sbin/ccs-ccstree

The "ccs-ccstree" command will show a list of profile, name of process, PID and name of domain the process belongs to like pstree command, as shown below.

0 init (1) <kernel> /sbin/init 0 +- mingetty (743) <kernel> /sbin/mingetty 0 +- mingetty (744) <kernel> /sbin/mingetty 0 +- mingetty (745) <kernel> /sbin/mingetty 0 +- mingetty (746) <kernel> /sbin/mingetty 0 +- mingetty (747) <kernel> /sbin/mingetty 0 +- rc (748) <kernel> /sbin/init /etc/rc.d/rc 0 +- S91smb (3468) <kernel> /etc/rc.d/init.d/smb 0 +- initlog (3475) <kernel> /etc/rc.d/init.d/smb /sbin/initlog 0 +- nmbd (3476) <kernel> /etc/rc.d/init.d/smb /sbin/initlog /usr/sbin/nmbd 0 +- syslogd (3158) <kernel> /etc/rc.d/init.d/syslog /sbin/initlog /sbin/syslogd 0 +- klogd (3162) <kernel> /etc/rc.d/init.d/syslog /sbin/initlog /sbin/klogd 0 +- portmap (3172) <kernel> /etc/rc.d/init.d/portmap /sbin/initlog /sbin/portmap 0 +- rpc.statd (3191) <kernel> /etc/rc.d/init.d/nfslock /sbin/initlog /sbin/rpc.statd 0 +- cardmgr (3245) <kernel> /etc/rc.d/init.d/pcmcia /sbin/cardmgr 0 +- apmd (3270) <kernel> /etc/rc.d/init.d/apmd /sbin/initlog /usr/sbin/apmd 0 +- sshd (3307) <kernel> /usr/sbin/sshd 0 +- sshd (3393) <kernel> /usr/sbin/sshd 0 +- tcsh (3434) <kernel> /usr/sbin/sshd /bin/tcsh 0 +- ccs-ccstree (3477) <kernel> /usr/sbin/sshd /bin/tcsh /usr/sbin/ccs-ccstree 0 +- xinetd (3321) <kernel> /usr/sbin/xinetd 0 +- rpc.rquotad (3342) <kernel> /etc/rc.d/init.d/nfs /sbin/initlog /usr/sbin/rpc.rquotad 0 +- rpc.mountd (3361) <kernel> /etc/rc.d/init.d/nfs /sbin/initlog /usr/sbin/rpc.mountd 0 +- vsftpd (3371) <kernel> /usr/sbin/vsftpd 0 +- sendmail (3395) <kernel> /etc/rc.d/init.d/sendmail /sbin/initlog /usr/sbin/sendmail.sendmail 0 +- sendmail (3404) <kernel> /etc/rc.d/init.d/sendmail /sbin/initlog /usr/sbin/sendmail.sendmail 0 +- spamd (3414) <kernel> /etc/rc.d/init.d/spamassassin /sbin/initlog /usr/bin/spamd 0 +- gpm (3423) <kernel> /etc/rc.d/init.d/gpm /sbin/initlog /usr/sbin/gpm 0 +- httpd (3455) <kernel> /usr/sbin/httpd 0 +- crond (3464) <kernel> /usr/sbin/crond 0 +- smbd (3473) <kernel> /usr/sbin/smbd

If you give -a option to ccs-ccstree, you can also see kernel processes that are out of TOMOYO Linux's MAC scope.

## Changes for Audit Logs

TOMOYO Linux can record "access granted logs" (access requests that didn't violate domain policy) and "access rejected logs" (access requests that violated domain policy).
The logs are in the form of domain policy so that the logs can be directly appended to domain policy. Add the "access rejected logs" to domain policy if you consider you should allow the access.

You can use a daemon program that reads from /proc/ccs/grant_log and /proc/ccs/reject_log and writes to files. Run in the following way from (for example) /etc/rc.local .

/usr/sbin/ccs-auditd $location_to_store_access_granted_logs $location_to_store_access_rejected_logs

You may give MAX_GRANT_LOG=0 for profiles and give /dev/null for $location_to_store_access_granted_logs if you don't want "access granted logs". Since "ccs-auditd" doesn't have filtering functions, be careful with the disk's free space if you want to save "access granted logs".

You may give MAX_REJECT_LOG=0 for profiles and give /dev/null for $location_to_store_access_rejected_logs if you don't want "access rejected logs". But I recommend you to save "access rejected logs". This manual assumes that "access rejected logs" is saved in /var/log/tomoyo/reject_log.conf .

/usr/sbin/ccs-auditd /dev/null /var/log/tomoyo/reject_log.conf

Create directories manually for storing access logs.

mkdir -p /var/log/tomoyo

If you want to rotate using "logrotate", create /etc/logrotate.d/tomoyo with the following content. Be sure to give "nocreate" option, or logs after the first rotation will not be saved.

/var/log/tomoyo/reject_log.conf { weekly rotate 9 missingok notifempty nocreate }

If you don't want neither "access granted logs" nor "access rejected logs", you needn't to run "ccs-auditd" and you can give MAX_GRANT_LOG=0 and MAX_REJECT_LOG=0 for profiles to save memory and improve performance.

## Changes for Policy Violation notification

TOMOYO Linux can report the occurrence of policy violation in enforcing mode, if you have set up a mean to notify (e.g. mail).

You can use cron daemon for notifying. For example, to notify root@example.com via mail, once per an hour, add

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

to /etc/crontab .

## Creating exception policy

Create /etc/ccs/exception_policy.conf and define the following types of exceptions.

1. Pathname pattern
2. Pathname group
3. Address group
4. Unconditionally readable files
5. Unconditionally usable environment variable names
6. Non-rewritable files
7. Programs invocable via symbolic links
8. Program aggregations
9. Programs that cause domain transition initialization
10. Programs that prevent domain transition initialization
11. Domains that prevent domain transition
12. Domains that cause domain transition

### (1) Pathname pattern

Register pathnames with patterns using the "file_pattern" directive. When a file operation is performed and the requested pathname matches a patterned pathname registered with "file_pattern" directive, policy is generated using patterned pathnames.
The following is the guideline.

- Files under /proc/PID/ directory.
- Files under /sys/ directory. (Applicable to 2.6 kernels only)
- Some files under /dev/ directory.
- Policy files under /usr/lib/security/ directory.
- Manual pages.
- Spool directories.
- Temporary files used for sending and receiving mails.
- Temporary files used by man command.
- Temporary files used by mount command.

TOMOYO Linux needs more patterned pathnames depending on the applications installed and their configurations. You can add missing patterned pathnames after running the system.

### (2) Pathname group

Register pathname groups using the "path_group" directive. This is a macro to reduce the amount of domain policy by grouping multiple pathnames using group names. An example usage is shown later.

### (3) Address group

Register IPv4 or IPv6 address groups using the "address_group" directive. This is a macro to reduce the amount of domain policy by grouping multiple addresses using group names. An example usage is shown later.

### (4) Unconditionally readable files

Register files that are allowed to be read by all programs using the "allow_read" directive. Patterns are allowed. When a file open request for reading is issued and the requested pathname matches a pathname registered with "allow_read" directive, the open request for read access is granted even if the pathname is not explicitly permitted by the domain policy.
The following is the guideline.

- Dynamically-linked library files that are registered with ldconfig.
- Some files under /proc/ directory.
- Some locale data under /usr/share/locale/ directory.

You may find more files depending on applications in your system or configurations. Add missing files after observing which files are used for read access.

### (5) Unconditionally usable environment variable names

Register environment variable names that are allowed to be passed to all programs using the "allow_env" directive. Patterns are allowed. When execve() request is issued and the passed environment variable name matches environment variable names registered with "allow_env" directive, the environment variable name is granted without checking domain policy.
The following is the guideline.

- Commonly used environment variable names such as PATH and HOME

You may find more files depending on applications in your system or configurations. Add missing files after observing which files are used for read access.

### (6) Non-rewritable files

Register files that you don't want to allow overwriting existing contents (like log files) using "deny_rewrite" directive. Patterns are allowed. Files registered with "deny_rewrite" directive are (as long as it is not explicitly given by "allow_rewrite" directive in domain policy) forbidden to "open for writing but not append mode" and "truncate".
The following is the guideline.

- Files under /var/log/ directory.

You may find more files depending on applications in your system or configurations. Add missing files after observing which files are used for append-only access.

### (7) Programs invocable via symbolic links

Basically, TOMOYO Linux checks execute permissions using the dereferenced pathname if the requested program is a symbolic link. But to handle programs that behave differently depending on the name of invocation, you may define domains using the name of symbolic links.
To allow executing programs using the name of symbolic links, use alias directive followed by dereferenced pathname and reference pathname. No patterns are allowed.
For example, /sbin/pidof is a symbolic link to /sbin/killall5 . In normal case, if /sbin/pidof is executed, the domain is defined as if /sbin/killall5 is executed. By specifying "alias /sbin/killall5 /sbin/pidof", you can run /sbin/pidof in the domain for /sbin/pidof .

### (8) Program aggregations

To deal multiple programs as a single program, use aggregator directive followed by name of original program and aggregated program. Patterns are allowed for name of original program.
For example, /usr/bin/tac and /bin/cat are similar. By specifying "aggregator /usr/bin/tac /bin/cat", you can run /usr/bin/tac in the domain for /bin/cat .

### (9) Programs that cause domain transition initialization

Register programs that initializes the domain transition history using the "initialize_domain" directive. No patterns allowed. When a program that is registered with "initialize_domain" directive is executed, the program runs just under the <kernel> domain.
The following is the guideline.

- Scripts that start or terminate daemon programs located under /etc/init.d/ directory.
- Daemon programs that you want to make domain names shorter (for example, httpd and sshd).

You may find more programs depending on applications in your system or configurations. Add missing programs after observing which programs should be initialize their domain transition history. But be careful with the side effect of other domains. For example, when the domain policy already includes

<kernel> ... /bin/bash use_profile 3 allow_execute /bin/tcsh <kernel> ... /bin/bash /bin/tcsh use_profile 3 allow_execute /bin/cat <kernel> ... /bin/bash /bin/tcsh /bin/cat use_profile 3 allow_read /etc/fstab

and you add /bin/tcsh as initialize_domain, "<kernel> ... /bin/bash /bin/tcsh" will become unreachable domain because /bin/tcsh runs in "<kernel> /bin/tcsh" domain. In that case, you will need to replace "<kernel> ... /bin/bash /bin/tcsh" with "<kernel> /bin/tcsh" as shown below.

<kernel> ... /bin/bash use_profile 3 allow_execute /bin/tcsh <kernel> /bin/tcsh use_profile 3 allow_execute /bin/cat <kernel> /bin/tcsh /bin/cat use_profile 3 allow_read /etc/fstab

### (10) Programs that prevent domain transition initialization

To deny the effect of "initialize_domain" directive under specific conditions, use "no_initialize_domain" directive.

### (11) Domains that prevent domain transition

To declare domain keepers, use "keep_domain" directive followed by domain definition.
For example, if "keep_domain <kernel> /usr/sbin/sshd /bin/tcsh" is given, any process that belongs to "<kernel> /usr/sbin/sshd /bin/tcsh" domain stays at that domain unless any program registered with "initialize_domain" directive is executed.

### (12) Domains that cause domain transition

To deny the effect of "keep_domain" directive under specific conditions, use "no_keep_domain" directive.

# Creating Domain Policy

## Basic Procedure

The following is the basic procedure for creating domain policy.

1. Create domains
2. Append ACLs to domains
3. Confirm ACLs for domains
4. Enforce using ACLs

You don't need to create the whole policy for all allications at one time.

### (1) Create domains

Assign a profile that doesn't perform MAC (in this manual, profile 0) and invoke applications. The purpose of this procedure is to create domains for applications.

For example, if you want to protect /usr/sbin/httpd , firstly create domains for /usr/sbin/httpd . If /usr/sbin/httpd is registered with "initialize_domain", a domain named "<kernel> /usr/sbin/httpd" is created by invoking /usr/sbin/httpd . If not registered, a child domain of invoker domain (for example, if you invoked from "<kernel> /usr/sbin/mingetty /bin/login /bin/bash", it is "<kernel> /usr/sbin/mingetty /bin/login /bin/bash /usr/sbin/httpd") is created. This manual assumes that /usr/sbin/httpd is registered with "initialize_domain".

Assign a profile that doesn't perform MAC (in this manual, profile 0) to the domain current process (normally a shell) belongs to using "ccs-setprofile" command.

xargs -0 /usr/sbin/ccs-setprofile 0 < /proc/ccs/self_domain

This is needed to avoid assigning a profile that performs MAC in "enforcing mode" to the newly created domain, for newly created domain inherits the creator's profile.

Start /usr/sbin/httpd .

service httpd start

You can use the following command to confirm that the domain is created. Make sure the domain for application you want to protect is created.

less /proc/ccs/.domain_status

After you confirmed that the domain is created, proceed to the next step.

### (2) Append ACLs to domains

After you confirmed that the domain is created, assign a profile that perform MAC in "learning mode" (in this manual, profile 1) to the domain using "ccs-setprofile" command.

/usr/sbin/ccs-setprofile -r 1 '<kernel> /usr/sbin/httpd'

Start /usr/sbin/httpd and let the system append ACLs needed for /usr/sbin/httpd .

service httpd restart

If the profile is configured as "1-TOMOYO_VERBOSE=enabled" (this is default), the "TOMOYO-WARNING:" messages will be printed to the console when policy violation occurs. But regarding "learning mode", the "TOMOYO-WARNING:" messages are printed only once because necessary ACLs are automatically appended when you do the same operation again.

If the "TOMOYO-WARNING:" messages are no longer printed when you do the operation you want to allow, proceed to the next step.

### (3) Confirm ACLs for domains

After you judged that necessary ACLs are appended, assign a profile that perform MAC in "permissive mode" (in this manual, profile 2) to the domain using "ccs-setprofile" command.

/usr/sbin/ccs-setprofile -r 2 '<kernel> /usr/sbin/httpd'

Start /usr/sbin/httpd and confirm that all necessary ACLs are appended.

If the profile is configured as "2-TOMOYO_VERBOSE=enabled" (this is default), the "TOMOYO-WARNING:" messages will be printed to the console when policy violation occurs. Regarding "permissive mode", the "TOMOYO-WARNING:" messages are printed again because necessary ACLs are not automatically appended when you do the same operation again.

If the "TOMOYO-WARNING:" messages are no longer printed when you do the operation you want to allow, proceed to the next step.

### (4) Enforce using ACLs

After you judged that necessary ACLs are given, assign a profile that perform MAC in "enforcing mode" (in this manual, profile 3) to the domain using "ccs-setprofile" command.

/usr/sbin/ccs-setprofile -r 3 '<kernel> /usr/sbin/httpd'

And now, /usr/sbin/httpd is protected by MAC.

If the profile is configured with "3-TOMOYO_VERBOSE=enabled" (this is default), the "TOMOYO-ERROR:" messages will be printed to the console and the requests are rejected when policy violation occurs. Also, the history of policy violation is accumulated to /proc/ccs/reject_log .

## Creating policy all at once using "permissive mode"

TOMOYO Linux allows administrators generate domain policy from policy violation logs. If you want to do so, assign a profile that perform MAC in "permissive mode" (in this manual, profile 2) to the domain.

/usr/sbin/ccs-setprofile -r 2 '<kernel> /usr/sbin/httpd'

The log file /var/log/tomoyo/reject_log.conf created by "ccs-auditd" contains list of ACLs that violated domain policy in time series. Select appropriate range and pass to the filter as show below. This filter program sorts by domains and removes duplicated entries. (In other words, "sort" by domains and "uniq".)

/usr/sbin/ccs-sortpolicy < /var/log/tomoyo/reject_log.conf

Check the output and judge whether these ACLs should be added or not. And if you judged to add, add to /etc/ccs/domain_policy.conf and run "ccs-loadpolicy" to reload domain policy.

/usr/sbin/ccs-loadpolicy d

If you run "ccs-loadpolicy" with "f" option (i.e. "ccs-loadpolicy df"), the domain policy currently in the kernel are erased before the domain policy currently on the disk is loaded.

### Operation Example

Rename the current reject log file. "ccs-auditd" will detect the disappearance of the current reject log file and recreates it.

[root@sakura tomoyo]# mv /var/log/tomoyo/reject_log.conf /var/log/tomoyo/reject_log.tmp

Check the logs. Select ranges you want to use using some text editor if necessary.

[root@sakura tomoyo]# cat /var/log/tomoyo/reject_log.tmp #2006-11-10 10:17:29# pid=4498 uid=0 gid=0 euid=0 egid=0 suid=0 sgid=0 fsuid=0 fsgid=0 <kernel> /usr/sbin/sshd /bin/tcsh /bin/cat allow_read /etc/inittab #2006-11-10 10:17:41# pid=4501 uid=0 gid=0 euid=0 egid=0 suid=0 sgid=0 fsuid=0 fsgid=0 <kernel> /usr/sbin/sshd /bin/tcsh /bin/cat allow_read /etc/resolv.conf #2006-11-10 10:18:00# pid=4502 uid=0 gid=0 euid=0 egid=0 suid=0 sgid=0 fsuid=0 fsgid=0 <kernel> /usr/sbin/sshd /bin/tcsh allow_execute /usr/bin/whoami #2006-11-10 10:18:00# pid=4502 uid=0 gid=0 euid=0 egid=0 suid=0 sgid=0 fsuid=0 fsgid=0 <kernel> /usr/sbin/sshd /bin/tcsh /usr/bin/whoami allow_read /etc/nsswitch.conf #2006-11-10 10:18:00# pid=4502 uid=0 gid=0 euid=0 egid=0 suid=0 sgid=0 fsuid=0 fsgid=0 <kernel> /usr/sbin/sshd /bin/tcsh /usr/bin/whoami allow_read /etc/passwd

Sort the log by domains.

[root@sakura tomoyo]# /usr/sbin/ccs-sortpolicy < /var/log/tomoyo/reject_log.tmp <kernel> /usr/sbin/sshd /bin/tcsh allow_execute /usr/bin/whoami #2006-11-10 10:18:00# pid=4502 uid=0 gid=0 euid=0 egid=0 suid=0 sgid=0 fsuid=0 fsgid=0 <kernel> /usr/sbin/sshd /bin/tcsh /bin/cat allow_read /etc/inittab allow_read /etc/resolv.conf #2006-11-10 10:17:41# pid=4501 uid=0 gid=0 euid=0 egid=0 suid=0 sgid=0 fsuid=0 fsgid=0 #2006-11-10 10:18:00# pid=4502 uid=0 gid=0 euid=0 egid=0 suid=0 sgid=0 fsuid=0 fsgid=0 <kernel> /usr/sbin/sshd /bin/tcsh /usr/bin/whoami allow_read /etc/nsswitch.conf allow_read /etc/passwd #2006-11-10 10:18:00# pid=4502 uid=0 gid=0 euid=0 egid=0 suid=0 sgid=0 fsuid=0 fsgid=0

Since the line of timestamp is disturbing, remove lines starting with # before sorting.

[root@sakura tomoyo]# grep -v '^#' /var/log/tomoyo/reject_log.tmp | /usr/sbin/ccs-sortpolicy > /var/log/tomoyo/diff.tmp

Check the output. This is in the form of domain policy.

[root@sakura tomoyo]# cat /var/log/tomoyo/diff.tmp <kernel> /usr/sbin/sshd /bin/tcsh allow_execute /usr/bin/whoami <kernel> /usr/sbin/sshd /bin/tcsh /bin/cat allow_read /etc/inittab allow_read /etc/resolv.conf <kernel> /usr/sbin/sshd /bin/tcsh /usr/bin/whoami allow_read /etc/nsswitch.conf allow_read /etc/passwd

## Creating policy interactively using "enforcing mode"

TOMOYO Linux allows administrators modify policies when the system is running in "enforcing mode". If you want to do so, start "ccs-queryd" command. The "ccs-queryd" command detects the policy violations and shows ACLs needed for allowing the requests. You can judge and append these ACLs to domain policy manually.

/usr/sbin/ccs-queryd

If "ccs-queryd" is running, the access requests that violated policy are kept pending. Otherwise, the access requests that violated policy are rejected immediately.

To avoid sleeping forever because of pending access requests, never logout (for example, detaching from screen(1)) if "ccs-queryd" is running.

To terminate "ccs-queryd", use Ctrl-C.

## Saving Policy

To save the policy currently in the kernel onto the disk, use "ccs-savepolicy" command.

/usr/sbin/ccs-savepolicy

By executing "ccs-savepolicy", three files ("system_policy.conf", "exception_policy.conf", "domain_policy.conf") are created in the /etc/ccs/ directory. To be accurate, they are symbolic links to text files whose filenames contain the creation time.

## Loading Policy

To load the policy currently on the disk into the kernel, use "ccs-loadpolicy" command.

/usr/sbin/ccs-loadpolicy af

The "a" option means load three files ("system_policy.conf", "exception_policy.conf", "domain_policy.conf"). The "f" option means erase the policy currently in the kernel before loading the policy currently on the disk. If "f" is not given, the policy currently on the disk will be added to the policy currently in the kernel.

## Editing Policy

To edit the policy currently in the kernel, use "ccs-editpolicy" command. See Using Policy Editor for usage.

/usr/sbin/ccs-editpolicy

To edit the policy currently on the disk, pass the policy directory /etc/ccs/ to "ccs-editpolicy" command. You can edit policy files in /etc/ccs/ directory using "ccs-editpolicy" even when you are not running the system with TOMOYO Linux kernel.

/usr/sbin/ccs-editpolicy /etc/ccs/

# Tuning Policy

## Patterning File Access Permissions

Append access permissions for files that are not necessarily accessed in the learning mode such as WWW contents for WWW service to /etc/ccs/domain_policy.conf .
The following example allows /usr/sbin/httpd to read files in the /var/www/html/ directory.

<kernel> /usr/sbin/httpd use_profile 3 allow_read /var/www/html/\* allow_read /var/www/html/\*/\* allow_read /var/www/html/\*/\*/\* allow_read /var/www/html/\*/\*/\*/\* allow_read /var/www/html/\*/\*/\*/\*/\*

TOMOYO Linux 1.3.2 supports pathname grouping. By defining a pathname group

path_group WEB-CONTENTS /var/www/html/\* path_group WEB-CONTENTS /var/www/html/\*/\* path_group WEB-CONTENTS /var/www/html/\*/\*/\* path_group WEB-CONTENTS /var/www/html/\*/\*/\*/\* path_group WEB-CONTENTS /var/www/html/\*/\*/\*/\*/\*

in the exception policy, you can simplify

<kernel> /usr/sbin/httpd use_profile 3 allow_read @WEB-CONTENTS

in the domain policy.

In the same way, modify access permissions for files using patterns that should be grouped.
The following example shows /usr/sbin/smbd should handle all log files equally.

Before | After
<kernel> /usr/sbin/smbd use_profile 3 allow_write /var/log/samba/host1.log allow_write /var/log/samba/host2.log allow_write /var/log/samba/host3.log allow_write /var/log/samba/host4.log allow_write /var/log/samba/host5.log | <kernel> /usr/sbin/smbd use_profile 3 allow_write /var/log/samba/\*.log

You can confirm the range of accessible files by using pathmatch command that lists pathnames matching to the given pathname patterns.

[root@sakura ~]# /usr/sbin/ccs-pathmatch '/var/log/samba/\*.log' /var/log/samba/host1.log /var/log/samba/host2.log /var/log/samba/host3.log /var/log/samba/host4.log /var/log/samba/host5.log

### Operation example

Save the domain policy currently in the kernel onto the disk.

[root@sakura ~]# ccs-savepolicy d

List up pathnames that can be temporary files.

[root@sakura ~]# findtemp < /etc/ccs/domain_policy.conf /etc/mtab.tmp /etc/mtab~ /etc/mtab~2302 /etc/mtab~2328 /etc/mtab~2329 /etc/mtab~2330 /etc/mtab~2331 /etc/mtab~2332 /etc/mtab~2339 /etc/mtab~2383 /halt /selinux/disable /selinux/enforce /selinux/policyvers /tmp/sh-thd-1163110572 /tmp/sh-thd-1163113704 /var/cache/samba/browse.dat. /var/lib/nfs/etab.tmp /var/lib/nfs/xtab.tmp /var/lock/mrtg/mrtg_l

Find domains that access these files.

[root@sakura ~]# /usr/sbin/ccs-domainmatch /etc/mtab~2302 <kernel> /sbin/init /etc/rc.d/rc.sysinit /sbin/initlog /etc/rc.d/rc.sysinit /sbin/initlog /bin/mount allow_create /etc/mtab~2302 allow_write /etc/mtab~2302 allow_link /etc/mtab~2302 /etc/mtab~ allow_unlink /etc/mtab~2302 [root@sakura ~]# /usr/sbin/ccs-domainmatch /tmp/sh-thd-1163113704 <kernel> /etc/rc.d/init.d/smartd /sbin/initlog /usr/sbin/smartd /bin/sh allow_create /tmp/sh-thd-1163113704 allow_read/write /tmp/sh-thd-1163113704 allow_unlink /tmp/sh-thd-1163113704

Save the exception policy currently in the kernel onto the disk.

[root@sakura ~]# /usr/sbin/ccs-savepolicy e

Append patterns to the exception policy on the disk if needed.

[root@sakura ~]# echo 'file_pattern /etc/mtab~\$' >> /etc/ccs/exception_policy.conf [root@sakura ~]# echo 'file_pattern /tmp/sh-thd-\$' >> /etc/ccs/exception_policy.conf

Load the exception policy on the disk to the kernel.

[root@sakura ~]# /usr/sbin/ccs-loadpolicy ef

Patternize pathnames that match '/etc/mtab~\$' and '/tmp/sh-thd-\$'.

[root@sakura ~]# /usr/sbin/ccs-patternize '/etc/mtab~\$' '/tmp/sh-thd-\$' < /etc/ccs/domain_policy.conf > /etc/ccs/domain_policy.tmp

Confirm that these files are patternized.

[root@sakura ~]# /usr/sbin/ccs-findtemp < /etc/ccs/domain_policy.tmp /etc/mtab.tmp /etc/mtab~ /halt /selinux/disable /selinux/enforce /selinux/policyvers /var/cache/samba/browse.dat. /var/lib/nfs/etab.tmp /var/lib/nfs/xtab.tmp /var/lock/mrtg/mrtg_l

Verify that the patterning are done as you have intended by diff'ing the domain policy before patternize and the one after the patternize.

[root@sakura ~]# diff /etc/ccs/domain_policy.conf /etc/ccs/domain_policy.tmp 2326,2331c2326,2331 < allow_read/write /tmp/sh-thd-1163110572 < allow_read/write /tmp/sh-thd-1163113704 < allow_create /tmp/sh-thd-1163110572 < allow_create /tmp/sh-thd-1163113704 < allow_unlink /tmp/sh-thd-1163110572 < allow_unlink /tmp/sh-thd-1163113704 --- > allow_read/write /tmp/sh-thd-\$ > allow_read/write /tmp/sh-thd-\$ > allow_create /tmp/sh-thd-\$ > allow_create /tmp/sh-thd-\$ > allow_unlink /tmp/sh-thd-\$ > allow_unlink /tmp/sh-thd-\$ 3331,3336c3331,3336 < allow_write /etc/mtab~2328 < allow_write /etc/mtab~2329 < allow_write /etc/mtab~2330 < allow_write /etc/mtab~2331 < allow_write /etc/mtab~2332 < allow_write /etc/mtab~2383 --- > allow_write /etc/mtab~\$ > allow_write /etc/mtab~\$ > allow_write /etc/mtab~\$ > allow_write /etc/mtab~\$ > allow_write /etc/mtab~\$ > allow_write /etc/mtab~\$ 3338,3349c3338,3349 < allow_create /etc/mtab~2328 < allow_create /etc/mtab~2329 < allow_create /etc/mtab~2330 < allow_create /etc/mtab~2331 < allow_create /etc/mtab~2332 < allow_create /etc/mtab~2383 < allow_link /etc/mtab~2328 /etc/mtab~ < allow_link /etc/mtab~2329 /etc/mtab~ < allow_link /etc/mtab~2330 /etc/mtab~ < allow_link /etc/mtab~2331 /etc/mtab~ < allow_link /etc/mtab~2332 /etc/mtab~ < allow_link /etc/mtab~2383 /etc/mtab~ --- > allow_create /etc/mtab~\$ > allow_create /etc/mtab~\$ > allow_create /etc/mtab~\$ > allow_create /etc/mtab~\$ > allow_create /etc/mtab~\$ > allow_create /etc/mtab~\$ > allow_link /etc/mtab~\$ /etc/mtab~ > allow_link /etc/mtab~\$ /etc/mtab~ > allow_link /etc/mtab~\$ /etc/mtab~ > allow_link /etc/mtab~\$ /etc/mtab~ > allow_link /etc/mtab~\$ /etc/mtab~ > allow_link /etc/mtab~\$ /etc/mtab~ 3351,3356c3351,3356 < allow_unlink /etc/mtab~2328 < allow_unlink /etc/mtab~2329 < allow_unlink /etc/mtab~2330 < allow_unlink /etc/mtab~2331 < allow_unlink /etc/mtab~2332 < allow_unlink /etc/mtab~2383 --- > allow_unlink /etc/mtab~\$ > allow_unlink /etc/mtab~\$ > allow_unlink /etc/mtab~\$ > allow_unlink /etc/mtab~\$ > allow_unlink /etc/mtab~\$ > allow_unlink /etc/mtab~\$ 3439,3440c3439,3440 < allow_write /etc/mtab~2302 < allow_write /etc/mtab~2339 --- > allow_write /etc/mtab~\$ > allow_write /etc/mtab~\$ 3443,3446c3443,3446 < allow_create /etc/mtab~2302 < allow_create /etc/mtab~2339 < allow_link /etc/mtab~2302 /etc/mtab~ < allow_link /etc/mtab~2339 /etc/mtab~ --- > allow_create /etc/mtab~\$ > allow_create /etc/mtab~\$ > allow_link /etc/mtab~\$ /etc/mtab~ > allow_link /etc/mtab~\$ /etc/mtab~ 3449,3450c3449,3450 < allow_unlink /etc/mtab~2302 < allow_unlink /etc/mtab~2339 --- > allow_unlink /etc/mtab~\$ > allow_unlink /etc/mtab~\$

Update the domain policy on the disk.

[root@sakura ~]# cat /etc/ccs/domain_policy.tmp > /etc/ccs/domain_policy.conf

Load the domain policy on the disk to the kernel.

[root@sakura ~]# /usr/sbin/ccs-loadpolicy df

Confirm that the domain policy currently in the kernel is updated.

[root@sakura ~]# /usr/sbin/ccs-findtemp < /proc/ccs/domain_policy /etc/mtab.tmp /etc/mtab~ /halt /selinux/disable /selinux/enforce /selinux/policyvers /var/cache/samba/browse.dat. /var/lib/nfs/etab.tmp /var/lib/nfs/xtab.tmp /var/lock/mrtg/mrtg_l

## Patterning Network Access Permissions

Similarly, make patterns for "allow_network" directives. Don't copy the following permissions.

Before | After
<kernel> /usr/sbin/sshd use_profile 7 allow_network TCP accept 0:0:0:0:0:0:0:1 43768 allow_network TCP accept 0:0:0:0:0:ffff:a00:1 35086 allow_network TCP accept 0:0:0:0:0:ffff:a00:a1 47590 allow_network TCP accept 10.0.0.10 56709 allow_network TCP accept 10.0.0.200 16384 | <kernel> /usr/sbin/sshd use_profile 7 allow_network TCP accept 0:0:0:0:0:0:0:1 1024-65535 allow_network TCP accept 0:0:0:0:0:ffff:a00:1-0:0:0:0:0:ffff:a00:ff 1024-65535 allow_network TCP accept 10.0.0.1-10.0.0.255 1024-65535

By defining a address group

address_group SSH-CLIENT-ADDRESS 0:0:0:0:0:0:0:1 address_group SSH-CLIENT-ADDRESS 0:0:0:0:0:ffff:a00:1-0:0:0:0:0:ffff:a00:ff address_group SSH-CLIENT-ADDRESS 10.0.0.1-10.0.0.255

in the exception policy, you can simplify

<kernel> /usr/sbin/sshd use_profile 7 allow_network TCP accept @SSH-CLIENT-ADDRESS 1024-65535

in the domain policy.

## Add conditions to ACLs

You can add conditions to individual ACLs if necessary. By using this feature, you can control system's user ID based access control.

You can define the following path_group in the exception policy.

path_group HOME-FTP-FILE /home/\*/ftp/\* path_group HOME-FTP-FILE /home/\*/ftp/\*/\* path_group HOME-FTP-FILE /home/\*/ftp/\*/\*/\* path_group HOME-FTP-FILE /home/\*/ftp/\*/\*/\*/\* path_group HOME-FTP-DIR /home/\*/ftp/\*/ path_group HOME-FTP-DIR /home/\*/ftp/\*/\*/ path_group HOME-FTP-DIR /home/\*/ftp/\*/\*/\*/ path_group HOME-SMB-FILE /home/\*/samba/\* path_group HOME-SMB-FILE /home/\*/samba/\*/\* path_group HOME-SMB-FILE /home/\*/samba/\*/\*/\* path_group HOME-SMB-FILE /home/\*/samba/\*/\*/\*/\* path_group HOME-SMB-DIR /home/\*/samba/\*/ path_group HOME-SMB-DIR /home/\*/samba/\*/\*/ path_group HOME-SMB-DIR /home/\*/samba/\*/\*/\*/

If you want to protect non-anonymous FTP service, by adding conditions in the following manner, you can forbid access to directories outside the user's home directory. To reduce damages when it is cracked, it is recommended that you should expose directories only under specific (such as "ftp") directory rather than exposing whole of home directories. If you use vsftpd, you can give like the following way.

Before | After
<kernel> /usr/sbin/vsftpd use_profile 3 allow_read/write @HOME-FTP-FILE allow_mkdir @HOME-FTP-DIR allow_rmdir @HOME-FTP-DIR allow_create @HOME-FTP-FILE allow_truncate @HOME-FTP-FILE allow_unlink @HOME-FTP-FILE allow_rename @HOME-FTP-FILE @HOME-FTP-FILE allow_rename @HOME-FTP-DIR @HOME-FTP-DIR | <kernel> /usr/sbin/vsftpd use_profile 3 allow_read/write @HOME-FTP-FILE if task.uid=path1.uid allow_mkdir @HOME-FTP-DIR if task.uid=path1.parent.uid allow_rmdir @HOME-FTP-DIR if task.uid=path1.uid allow_create @HOME-FTP-FILE if task.uid=path1.parent.uid allow_truncate @HOME-FTP-FILE if task.uid=path1.uid allow_unlink @HOME-FTP-FILE if task.uid=path1.uid allow_rename @HOME-FTP-FILE @HOME-FTP-FILE if task.uid=path1.parent.uid task.uid=path2.parent.uid allow_rename @HOME-FTP-DIR @HOME-FTP-DIR if task.uid=path1.parent.uid task.uid=path2.parent.uid

If you want to protect Samba service, by adding conditions in the following manner, you can forbid access to directories outside the user's home directory. To reduce damages when it is cracked, it is recommended that you should expose directories only under specific (such as "samba") directory rather than exposing whole of home directories.

Before | After
<kernel> /usr/sbin/smbd use_profile 3 allow_read/write @HOME-SMB-FILE allow_mkdir @HOME-SMB-DIR allow_rmdir @HOME-SMB-DIR allow_create @HOME-SMB-FILE allow_truncate @HOME-SMB-FILE allow_unlink @HOME-SMB-FILE allow_rename @HOME-SMB-FILE @HOME-SMB-FILE allow_rename @HOME-SMB-DIR @HOME-SMB-DIR | <kernel> /usr/sbin/smbd use_profile 3 allow_read/write @HOME-SMB-FILE if task.euid=path1.uid allow_mkdir @HOME-SMB-DIR if task.euid=path1.parent.uid allow_rmdir @HOME-SMB-DIR if task.euid=path1.uid allow_create @HOME-SMB-FILE if task.euid=path1.parent.uid allow_truncate @HOME-SMB-FILE if task.euid=path1.uid allow_unlink @HOME-SMB-FILE if task.euid=path1.uid allow_rename @HOME-SMB-FILE @HOME-SMB-FILE if task.euid=path1.parent.uid task.euid=path2.parent.uid allow_rename @HOME-SMB-DIR @HOME-SMB-DIR if task.euid=path1.parent.uid task.euid=path2.parent.uid

If you want to protect SSH service, by adding conditions in the following manner, you can forbid login as user "root".

Before | After
<kernel> /usr/sbin/sshd use_profile 3 allow_execute /bin/bash | <kernel> /usr/sbin/sshd use_profile 3 allow_execute /bin/bash if task.uid!=0 task.euid!=0

## Updating softwares

You may need to adjust policies due to software updates and configuration changes. To adjust policy, see TOMOYO Linux Maintenance manual.