Info: Version 1.8.x is available.
Last modified: $Date: 2024-03-30 20:25:00 +0900 (Sat, 30 Mar 2024) $
This page describes how to tune TOMOYO Linux's policy.
Append access permissions for files that are not necessarily accessed in the learning mode such as WWW contents for WWW service.
| Before | After |
|
<kernel> /usr/sbin/httpd allow_read /var/www/html/index.html allow_read /var/www/html/blog/index.html allow_read /var/www/html/blog/page1.html allow_read /var/www/html/blog/page2.html allow_read /var/www/html/blog/page3.html allow_read /var/www/html/blog/image1.jpg allow_read /var/www/html/blog/image2.jpg |
<kernel> /usr/sbin/httpd allow_read /var/www/html/\*.html allow_read /var/www/html/\{\*\}/\*.html allow_read /var/www/html/\{\*\}/\*.jpg |
If you define
|
path_group WEB-CONTENTS /var/www/html/\*.html path_group WEB-CONTENTS /var/www/html/\{\*\}/\*.html path_group WEB-CONTENTS /var/www/html/\{\*\}/\*.jpg |
in the exception policy, you can simplify like
|
<kernel> /usr/sbin/httpd allow_read @WEB-CONTENTS |
in the domain policy.
You can not handle temporary files by simply using "learning mode" and "permissive mode". You need to interactively handle temporary files according to To remove redundant ACL entries.
But if you want to convert temporary files into patterns non-interactively, you can do it as shown below.
List up pathnames that can be temporary files.
|
[root@tomoyo ~]# /usr/sbin/ccs-findtemp < /proc/ccs/domain_policy /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 |
We can consider that "/etc/mtab~numeric" and "/tmp/sh-thd-numeric" are temporary files, thus we make patterns for these pathnames. First, we need to consider what patterns to use. In these examples, numeric seems decimal digits. Thus, we use \$ pattern which matches one or more repetitions of decimal digits.
Append patterns to the exception policy.
|
[root@tomoyo ~]# echo 'file_pattern /etc/mtab~\$' | /usr/sbin/ccs-loadpolicy -e [root@tomoyo ~]# echo 'file_pattern /tmp/sh-thd-\$' | /usr/sbin/ccs-loadpolicy -e |
Replace "/etc/mtab~numeric" and "/tmp/sh-thd-numeric" in the domain policy with '/etc/mtab~\$' and '/tmp/sh-thd-\$'
| [root@tomoyo ~]# /usr/sbin/ccs-savepolicy -d | /usr/sbin/ccs-patternize '/etc/mtab~\$' '/tmp/sh-thd-\$' | /usr/sbin/ccs-loadpolicy -d |
Make patterns for numeric parameters such as file's create mode and network's port numbers.
The following example permits /usr/sbin/httpd to accept connections from client's port 1024-65535.
| Before | After |
|
<kernel> /usr/sbin/httpd allow_network TCP accept 0:0:0:0:0:ffff:c0a8:801 3810 allow_network TCP accept 0:0:0:0:0:ffff:c0a8:801 3829 allow_network TCP accept 0:0:0:0:0:ffff:c0a8:801 3829 |
<kernel> /usr/sbin/httpd allow_network TCP accept 0:0:0:0:0:ffff:c0a8:801 1024-65535 |
If you define
| number_group WEB-CLIENT-PORTS 1024-65535 |
in the exception policy, you can simplify like
|
<kernel> /usr/sbin/httpd allow_network TCP accept 0:0:0:0:0:ffff:c0a8:801 @WEB-CLIENT-PORTS |
in the domain policy.
Similarly, make patterns for IP addresses. Don't copy the following permissions.
| Before | After |
|
<kernel> /usr/sbin/httpd allow_network TCP accept 0:0:0:0:0:0:0:1 @WEB-CLIENT-PORTS allow_network TCP accept 0:0:0:0:0:ffff:a00:1 @WEB-CLIENT-PORTS allow_network TCP accept 0:0:0:0:0:ffff:a00:a1 @WEB-CLIENT-PORTS allow_network TCP accept 10.0.0.10 @WEB-CLIENT-PORTS allow_network TCP accept 10.0.0.200 @WEB-CLIENT-PORTS |
<kernel> /usr/sbin/httpd allow_network TCP accept 0:0:0:0:0:0:0:1 @WEB-CLIENT-PORTS allow_network TCP accept 0:0:0:0:0:ffff:a00:1-0:0:0:0:0:ffff:a00:ff @WEB-CLIENT-PORTS allow_network TCP accept 10.0.0.1-10.0.0.255 @WEB-CLIENT-PORTS |
If you define
|
address_group WEB-CLIENT-ADDRESS 0:0:0:0:0:0:0:1 address_group WEB-CLIENT-ADDRESS 0:0:0:0:0:ffff:a00:1-0:0:0:0:0:ffff:a00:ff address_group WEB-CLIENT-ADDRESS 10.0.0.1-10.0.0.255 |
in the exception policy, you can simplify like
|
<kernel> /usr/sbin/httpd allow_network TCP accept @WEB-CLIENT-ADDRESS @WEB-CLIENT-PORTS |
in the domain policy.
You can add conditions to individual ACLs if necessary. By using this feature, you can enforce 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 allow_read/write @HOME-FTP-FILE allow_mkdir @HOME-FTP-DIR 0755 allow_rmdir @HOME-FTP-DIR allow_create @HOME-FTP-FILE 0644 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 allow_read/write @HOME-FTP-FILE if task.uid=path1.uid allow_mkdir @HOME-FTP-DIR 0755 if task.uid=path1.parent.uid allow_rmdir @HOME-FTP-DIR if task.uid=path1.uid allow_create @HOME-FTP-FILE 0644 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 allow_read/write @HOME-SMB-FILE allow_mkdir @HOME-SMB-DIR 0755 allow_rmdir @HOME-SMB-DIR allow_create @HOME-SMB-FILE 0644 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 allow_read/write @HOME-SMB-FILE if task.euid=path1.uid allow_mkdir @HOME-SMB-DIR 0755 if task.euid=path1.parent.uid allow_rmdir @HOME-SMB-DIR if task.euid=path1.uid allow_create @HOME-SMB-FILE 0644 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 allow_execute /bin/bash if exec.realpath="/bin/bash" exec.argv[0]="-bash" |
<kernel> /usr/sbin/sshd allow_execute /bin/bash if exec.realpath="/bin/bash" exec.argv[0]="-bash" task.uid!=0 task.euid!=0 |
Various conditions are supported. Please see Using conditional ACL. for details.
If you have configured audit logs at Phase 2: Initializing TOMOYO Linux., you can generate conditional ACL from audit logs by applying convert-audit-log before applying ccs-sortpolicy . But please be aware that conditional ACL automatically generated in this way is too restricted to apply for actual system. For example, you should not check process ID and inode numbers because they change every time. Please relax conditions as you need before applying automatically generated conditional ACL.
|
# grep -A 3 -F 'profile=2 mode=permissive' /var/log/tomoyo/reject_log.conf | /usr/lib/ccs/convert-audit-log | /usr/sbin/ccs-sortpolicy <kernel> /usr/sbin/httpd allow_network TCP accept 0:0:0:0:0:ffff:c0a8:801 1507 if task.pid=3039 task.ppid=3034 task.uid=48 task.gid=48 task.euid=48 task.egid=48 task.suid=48 task.sgid=48 task.fsuid=48 task.fsgid=48 task.state[0]=0 task.state[1]=0 task.state[2]=0 task.type!=execute_handler <kernel> /usr/sbin/httpd /bin/sh allow_execute /usr/bin/id if task.pid=4641 task.ppid=4637 task.uid=48 task.gid=48 task.euid=48 task.egid=48 task.suid=48 task.sgid=48 task.fsuid=48 task.fsgid=48 task.state[0]=0 task.state[1]=0 task.state[2]=0 task.type!=execute_handler path1.uid=0 path1.gid=0 path1.ino=603159 path1.major=8 path1.minor=1 path1.perm=0755 path1.type=file path1.parent.uid=0 path1.parent.gid=0 path1.parent.ino=589834 path1.parent.perm=0755 exec.realpath="/usr/bin/id" exec.argc=1 exec.envc=7 exec.argv[0]="id" exec.envp["TERM"]="linux" exec.envp["PATH"]="/sbin:/usr/sbin:/bin:/usr/bin" exec.envp["PWD"]="/usr/share/horde/admin" exec.envp["LANG"]="en_US.UTF-8" exec.envp["SHLVL"]="3" exec.envp["LANGUAGE"]="en_US.UTF-8" exec.envp["_"]="/usr/bin/id" <kernel> /usr/sbin/httpd /bin/sh /usr/bin/id allow_env LANG if task.pid=4641 task.ppid=4637 task.uid=48 task.gid=48 task.euid=48 task.egid=48 task.suid=48 task.sgid=48 task.fsuid=48 task.fsgid=48 task.state[0]=0 task.state[1]=0 task.state[2]=0 task.type!=execute_handler path1.uid=0 path1.gid=0 path1.ino=603159 path1.major=8 path1.minor=1 path1.perm=0755 path1.type=file path1.parent.uid=0 path1.parent.gid=0 path1.parent.ino=589834 path1.parent.perm=0755 exec.realpath="/usr/bin/id" exec.argc=1 exec.envc=7 exec.argv[0]="id" exec.envp["TERM"]="linux" exec.envp["PATH"]="/sbin:/usr/sbin:/bin:/usr/bin" exec.envp["PWD"]="/usr/share/horde/admin" exec.envp["LANG"]="en_US.UTF-8" exec.envp["SHLVL"]="3" exec.envp["LANGUAGE"]="en_US.UTF-8" exec.envp["_"]="/usr/bin/id" allow_env LANGUAGE if task.pid=4641 task.ppid=4637 task.uid=48 task.gid=48 task.euid=48 task.egid=48 task.suid=48 task.sgid=48 task.fsuid=48 task.fsgid=48 task.state[0]=0 task.state[1]=0 task.state[2]=0 task.type!=execute_handler path1.uid=0 path1.gid=0 path1.ino=603159 path1.major=8 path1.minor=1 path1.perm=0755 path1.type=file path1.parent.uid=0 path1.parent.gid=0 path1.parent.ino=589834 path1.parent.perm=0755 exec.realpath="/usr/bin/id" exec.argc=1 exec.envc=7 exec.argv[0]="id" exec.envp["TERM"]="linux" exec.envp["PATH"]="/sbin:/usr/sbin:/bin:/usr/bin" exec.envp["PWD"]="/usr/share/horde/admin" exec.envp["LANG"]="en_US.UTF-8" exec.envp["SHLVL"]="3" exec.envp["LANGUAGE"]="en_US.UTF-8" exec.envp["_"]="/usr/bin/id" allow_env PATH if task.pid=4641 task.ppid=4637 task.uid=48 task.gid=48 task.euid=48 task.egid=48 task.suid=48 task.sgid=48 task.fsuid=48 task.fsgid=48 task.state[0]=0 task.state[1]=0 task.state[2]=0 task.type!=execute_handler path1.uid=0 path1.gid=0 path1.ino=603159 path1.major=8 path1.minor=1 path1.perm=0755 path1.type=file path1.parent.uid=0 path1.parent.gid=0 path1.parent.ino=589834 path1.parent.perm=0755 exec.realpath="/usr/bin/id" exec.argc=1 exec.envc=7 exec.argv[0]="id" exec.envp["TERM"]="linux" exec.envp["PATH"]="/sbin:/usr/sbin:/bin:/usr/bin" exec.envp["PWD"]="/usr/share/horde/admin" exec.envp["LANG"]="en_US.UTF-8" exec.envp["SHLVL"]="3" exec.envp["LANGUAGE"]="en_US.UTF-8" exec.envp["_"]="/usr/bin/id" allow_env PWD if task.pid=4641 task.ppid=4637 task.uid=48 task.gid=48 task.euid=48 task.egid=48 task.suid=48 task.sgid=48 task.fsuid=48 task.fsgid=48 task.state[0]=0 task.state[1]=0 task.state[2]=0 task.type!=execute_handler path1.uid=0 path1.gid=0 path1.ino=603159 path1.major=8 path1.minor=1 path1.perm=0755 path1.type=file path1.parent.uid=0 path1.parent.gid=0 path1.parent.ino=589834 path1.parent.perm=0755 exec.realpath="/usr/bin/id" exec.argc=1 exec.envc=7 exec.argv[0]="id" exec.envp["TERM"]="linux" exec.envp["PATH"]="/sbin:/usr/sbin:/bin:/usr/bin" exec.envp["PWD"]="/usr/share/horde/admin" exec.envp["LANG"]="en_US.UTF-8" exec.envp["SHLVL"]="3" exec.envp["LANGUAGE"]="en_US.UTF-8" exec.envp["_"]="/usr/bin/id" allow_env SHLVL if task.pid=4641 task.ppid=4637 task.uid=48 task.gid=48 task.euid=48 task.egid=48 task.suid=48 task.sgid=48 task.fsuid=48 task.fsgid=48 task.state[0]=0 task.state[1]=0 task.state[2]=0 task.type!=execute_handler path1.uid=0 path1.gid=0 path1.ino=603159 path1.major=8 path1.minor=1 path1.perm=0755 path1.type=file path1.parent.uid=0 path1.parent.gid=0 path1.parent.ino=589834 path1.parent.perm=0755 exec.realpath="/usr/bin/id" exec.argc=1 exec.envc=7 exec.argv[0]="id" exec.envp["TERM"]="linux" exec.envp["PATH"]="/sbin:/usr/sbin:/bin:/usr/bin" exec.envp["PWD"]="/usr/share/horde/admin" exec.envp["LANG"]="en_US.UTF-8" exec.envp["SHLVL"]="3" exec.envp["LANGUAGE"]="en_US.UTF-8" exec.envp["_"]="/usr/bin/id" allow_env TERM if task.pid=4641 task.ppid=4637 task.uid=48 task.gid=48 task.euid=48 task.egid=48 task.suid=48 task.sgid=48 task.fsuid=48 task.fsgid=48 task.state[0]=0 task.state[1]=0 task.state[2]=0 task.type!=execute_handler path1.uid=0 path1.gid=0 path1.ino=603159 path1.major=8 path1.minor=1 path1.perm=0755 path1.type=file path1.parent.uid=0 path1.parent.gid=0 path1.parent.ino=589834 path1.parent.perm=0755 exec.realpath="/usr/bin/id" exec.argc=1 exec.envc=7 exec.argv[0]="id" exec.envp["TERM"]="linux" exec.envp["PATH"]="/sbin:/usr/sbin:/bin:/usr/bin" exec.envp["PWD"]="/usr/share/horde/admin" exec.envp["LANG"]="en_US.UTF-8" exec.envp["SHLVL"]="3" exec.envp["LANGUAGE"]="en_US.UTF-8" exec.envp["_"]="/usr/bin/id" allow_env _ if task.pid=4641 task.ppid=4637 task.uid=48 task.gid=48 task.euid=48 task.egid=48 task.suid=48 task.sgid=48 task.fsuid=48 task.fsgid=48 task.state[0]=0 task.state[1]=0 task.state[2]=0 task.type!=execute_handler path1.uid=0 path1.gid=0 path1.ino=603159 path1.major=8 path1.minor=1 path1.perm=0755 path1.type=file path1.parent.uid=0 path1.parent.gid=0 path1.parent.ino=589834 path1.parent.perm=0755 exec.realpath="/usr/bin/id" exec.argc=1 exec.envc=7 exec.argv[0]="id" exec.envp["TERM"]="linux" exec.envp["PATH"]="/sbin:/usr/sbin:/bin:/usr/bin" exec.envp["PWD"]="/usr/share/horde/admin" exec.envp["LANG"]="en_US.UTF-8" exec.envp["SHLVL"]="3" exec.envp["LANGUAGE"]="en_US.UTF-8" exec.envp["_"]="/usr/bin/id" allow_read /etc/group if task.pid=4641 task.ppid=4637 task.uid=48 task.gid=48 task.euid=48 task.egid=48 task.suid=48 task.sgid=48 task.fsuid=48 task.fsgid=48 task.state[0]=0 task.state[1]=0 task.state[2]=0 task.type!=execute_handler path1.uid=0 path1.gid=0 path1.ino=330196 path1.major=8 path1.minor=1 path1.perm=0644 path1.type=file path1.parent.uid=0 path1.parent.gid=0 path1.parent.ino=327681 path1.parent.perm=0755 allow_read /etc/nsswitch.conf if task.pid=4641 task.ppid=4637 task.uid=48 task.gid=48 task.euid=48 task.egid=48 task.suid=48 task.sgid=48 task.fsuid=48 task.fsgid=48 task.state[0]=0 task.state[1]=0 task.state[2]=0 task.type!=execute_handler path1.uid=0 path1.gid=0 path1.ino=329303 path1.major=8 path1.minor=1 path1.perm=0644 path1.type=file path1.parent.uid=0 path1.parent.gid=0 path1.parent.ino=327681 path1.parent.perm=0755 allow_read /etc/passwd if task.pid=4641 task.ppid=4637 task.uid=48 task.gid=48 task.euid=48 task.egid=48 task.suid=48 task.sgid=48 task.fsuid=48 task.fsgid=48 task.state[0]=0 task.state[1]=0 task.state[2]=0 task.type!=execute_handler path1.uid=0 path1.gid=0 path1.ino=330197 path1.major=8 path1.minor=1 path1.perm=0644 path1.type=file path1.parent.uid=0 path1.parent.gid=0 path1.parent.ino=327681 path1.parent.perm=0755 allow_read /etc/selinux/config if task.pid=4641 task.ppid=4637 task.uid=48 task.gid=48 task.euid=48 task.egid=48 task.suid=48 task.sgid=48 task.fsuid=48 task.fsgid=48 task.state[0]=0 task.state[1]=0 task.state[2]=0 task.type!=execute_handler path1.uid=0 path1.gid=0 path1.ino=328251 path1.major=8 path1.minor=1 path1.perm=0644 path1.type=file path1.parent.uid=0 path1.parent.gid=0 path1.parent.ino=327965 path1.parent.perm=0755 allow_read /proc/filesystems if task.pid=4641 task.ppid=4637 task.uid=48 task.gid=48 task.euid=48 task.egid=48 task.suid=48 task.sgid=48 task.fsuid=48 task.fsgid=48 task.state[0]=0 task.state[1]=0 task.state[2]=0 task.type!=execute_handler path1.uid=0 path1.gid=0 path1.ino=4026531844 path1.major=0 path1.minor=3 path1.perm=0444 path1.type=file path1.parent.uid=0 path1.parent.gid=0 path1.parent.ino=1 path1.parent.perm=0555 allow_read /selinux/mls if task.pid=4641 task.ppid=4637 task.uid=48 task.gid=48 task.euid=48 task.egid=48 task.suid=48 task.sgid=48 task.fsuid=48 task.fsgid=48 task.state[0]=0 task.state[1]=0 task.state[2]=0 task.type!=execute_handler path1.uid=0 path1.gid=0 path1.ino=12 path1.major=0 path1.minor=15 path1.perm=0444 path1.type=file path1.parent.uid=0 path1.parent.gid=0 path1.parent.ino=463 path1.parent.perm=0755 allow_read /usr/lib/locale/locale-archive if task.pid=4641 task.ppid=4637 task.uid=48 task.gid=48 task.euid=48 task.egid=48 task.suid=48 task.sgid=48 task.fsuid=48 task.fsgid=48 task.state[0]=0 task.state[1]=0 task.state[2]=0 task.type!=execute_handler path1.uid=0 path1.gid=0 path1.ino=605586 path1.major=8 path1.minor=1 path1.perm=0644 path1.type=file path1.parent.uid=0 path1.parent.gid=0 path1.parent.ino=589842 path1.parent.perm=0755 |