Info: Version 1.8.x is available.
Last modified: $Date: 2024-03-30 11:25:00 +0000 (Sat, 30 Mar 2024) $
In this installment, I explain steps for restricting operations after logging into a Linux system.
SELinux is currently migrating to reference policy. Before reference policy is provided, two types of policy configurations were provided as default policy configuration. One is called "strict policy" which applies mandatory access control to all processes including login sessions. The other is called "targeted policy" which applies mandatory access control to frequently attacked services. From the point of view of "improving security", literally strict "strict policy" is more effective. But if "strict policy" is not properly configured, it even happens that nobody can login to a SELinux enabled system. Therefore, many users who are using SELinux enabled are probably customizing policy configuration based on "targeted policy". According to opinions from Russell Coker and SELinux developers in LKML, they SELinux developers consider that "System administrators who can't figure out SELinux's policy should not modify SELinux's policy configuration. Use default policy configuration without modification provided by us because we are SELinux's professional." On the contrary, TOMOYO Linux developers consider that "System administrators creates policy configuration by themselves." What do you think about this?
By the way, this series explains TOMOYO Linux. Thus, let's restrict operations in login sessions using "do it yourself" TOMOYO Linux.
When you use Linux as a server, you might want to restrict operations of users who logged into the system. For example, "I want to prevent administrator from getting out database files which contain customer's information", "I want to allow logged in users nothing but to change password", "I want to delegate tasks for restarting WWW servers and updating WWW contents while forbidding all other operations", "I want to prevent logged in users from installing backdoors for sniffing passwords", "I want to use Linux as a gateway server for accessing corporate networks from Internet". You can easily handle such demands by using TOMOYO Linux because TOMOYO Linux manages domains for per process's invocation history basis.
There are 4 general phases for protecting login sessions.
Keywords which appear in above steps are listed in Fig. 1.
♦ Fig. 1 Keywords
|
To prevent users who logged in the system from executing malicious programs, it is an effective solution to forbid execution of programs which are not installed in the system beforehand. In this series, I assume commands listed in Fig. 2 (from commands installed in the system beforehand) are permitted in the login session.
♦ Fig. 2 Programs permitted in login session
|
Let's group these commands using "path_group" keyword in exception policy. (Fig. 3) But do not use "path_group" keyword for programs which behaves differently depending on invocation name (a.k.a. argv[0]). Instead, specify such programs individually (e.g. allow_execute /usr/bin/passwd if exec.argv[0]="passwd") using "if exec.argv[0]" conditions.
♦ Fig. 3 Grouping commands
path_group COMMANDS_FOR_LOGIN_SESSION /bin/basename path_group COMMANDS_FOR_LOGIN_SESSION /bin/bash (...snipped...) path_group COMMANDS_FOR_LOGIN_SESSION /usr/bin/wget path_group COMMANDS_FOR_LOGIN_SESSION /usr/bin/which |
You can use "which" command or "type" command for finding the location of commands. (Fig. 4)
♦ Fig. 4 Finding the location of commands
# which perl sed grep /usr/bin/perl /bin/sed /bin/grep |
You might wonder that "Do I need to allow execution of programs like /sbin/consoletype and /usr/bin/dircolors ?" But many commands are automatically executed by scripts (e.g. ~/.bashrc for /bin/bash ) where users are not aware. To know what operations are done by such commands, login to the system running with TOMOYO Linux kernels and then logout. And you can learn what commands are automatically executed by scripts as a child domain of login shell. Moreover, if you do so with a profile with "CONFIG::file={ mode=learning }" (i.e. learning mode) assigned to the domain for login shell, you can learn not only programs executed but also files accessed.
As I explained in this series by now, as a rule, TOMOYO Linux performs domain transition whenever a program is executed. Therefore, /bin/cat command will belong to a child domain of shell programs in Fig. 5 and /bin/cat command will belong to a child domain of /usr/bin/xargs command in Fig. 6.
♦ Fig. 5 Executing /bin/cat command from shell
# /bin/cat /etc/*.conf |
♦ Fig. 6 Executing /bin/cat command from xargs command
# echo /etc/*.conf | xargs /bin/cat -- |
But, there would be no difference from the point of view of security and it would be convenient for users that /bin/cat belongs to the same domain in both cases. Since it is difficult to predict what commands do users executes in what order in login session, as a rule you can suppress domain transitions in login session. If login shell is /bin/bash , the domain which login shell executed from /usr/sbin/sshd belongs to is "<kernel> /usr/sbin/sshd /bin/bash". Thus, you can specify "keep_domain <kernel> /usr/sbin/sshd /bin/bash" in exception policy in order to suppress domain transition. However, you want to allow accessing /etc/shadow (i.e. password file) by /usr/bin/passwd command for changing password but you don't want to allow accessing /etc/shadow using /bin/cat command for browsing password. In that case, you can specify "no_keep_domain /usr/bin/passwd from <kernel> /usr/sbin/sshd /bin/bash" in exception policy in order to let /usr/bin/passwd command run in "<kernel> /usr/sbin/sshd /bin/bash /usr/bin/passwd" domain. Similarly, you can specify "no_keep_domain /usr/bin/ssh from <kernel> /usr/sbin/sshd /bin/bash" in order to let /usr/bin/ssh command run in a different domain because you want to allow /usr/bin/ssh command to access ~/.ssh/ directory (where files like SSH secret key are stored) but you don't want to allow /bin/cat command to access ~/.ssh/ directory.
In TOMOYO Linux, both source and destination pathnames are checked when creating hard links, both old and new pathnames are checked when renaming. I explain the reason why TOMOYO Linux does so. Login to a system (no need to be running with TOMOYO Linux kernels) and do commands listed in Fig. 7. (The command will fail if /etc/ directory and /tmp/ directory are on different partitions. In that case, use a directory which is on the same partition (e.g. /root/ directory) instead of /tmp/ directory.)
♦ Fig. 7 Accessing password files via hard link
# ln /etc/shadow /tmp/shadow # cat /tmp/shadow |
This means that by creating hard link of /etc/shadow (which contains login passwords) under /tmp/ directory, you can access the login passwords via /tmp/shadow . You might think that "No administrators will create hard link of /etc/shadow as /tmp/shadow .", but creation of hard link of /etc/shadow is permitted for non "root" users. A non "root" user might create hard link of /etc/shadow into /tmp/ directory (where non "root" users can write) and access the password file (i.e. /tmp/shadow ) by gaining "root" privileges via permitted commands (e.g. /usr/bin/sudo command). Therefore, TOMOYO Linux checks both source and destination pathnames in order to minimize the risk of creating such hard links. (If you actually created /tmp/shadow , be sure to delete /tmp/shadow before reading on! If the link count of /etc/shadow is larger than 1, hard links remain somewhere on the same partition. (Fig. 8))
♦ Fig. 8 Delete hard link of /etc/shadow
# ls -l /etc/shadow -r-------- 2 root root 946 May 29 18:14 /etc/shadow # unlink /tmp/shadow # ls -l /etc/shadow -r-------- 1 root root 946 May 29 18:14 /etc/shadow |
Same for renaming operation. You can strictly restrict reading and/or writing /etc/shadow , but you cannot strictly restrict reading and/or writing files under /tmp/ directory. But, it is not desirable for you that users can do operations like Fig. 9. (If /etc/ directory and /tmp/ directory are on different partition, you can prevent moving from /etc/shadow to /tmp/shadow by forbidding reading and writing /etc/shadow because rename operations which cross mount point are not supported.)
♦ Fig. 9 Accessing password files after renaming
# mv /etc/shadow /tmp/shadow # cat /tmp/shadow # mv /tmp/shadow /etc/shadow |
Therefore, TOMOYO Linux checks both old and new pathnames in order to minimize the risk of such renaming. Access restrictions based on pathnames will allow unexpected access if you are not careful. Thus, be careful when giving permissions for creating hard links or renaming using TOMOYO Linux in order to minimize accessible ranges. (Although this characteristic is a disadvantage of pathname based access control when dealing "whether one can read and/or write and/or execute the file", this characteristic is an advantage of pathname based access control when dealing "how one uses the file if one can read and/or write and/or execute the file".)
Domain transition is used for switching permissions. Not doing domain transition for login sessions as a rule means we don't distinguish files which are permitted to read and/or write in login session. Basically, you don't need to create or rewrite programs in login session. Thus, you will give permissions for mainly reading and writing files under user's home directory. In order to group files under user's home directory, specify groups listed in Fig. 10 in exception policy.
♦ Fig. 10 Grouping files under home directory
path_group HOME_FILE /home/\{\*\}/\* path_group HOME_DIR /home/\{\*\}/\*/ |
By grouping like Fig. 10, you can treat files under user's home directory equally.
But you have files you want to forbid browsing via e.g. /bin/cat command (e.g. files under ~/.ssh/ directory) within files in user's home directory. Therefore, you can exclude pathnames in .ssh directory by specifying "\*\-.ssh". Namely, modify groups like Fig. 11.
♦ Fig. 11 Exclude .ssh directory from home directory
path_group HOME_FILE /home/\{\*\-.ssh\}/\* path_group HOME_DIR /home/\{\*\-.ssh\}/ |
Now, users can no longer access /home/\*/.ssh/\* via /bin/cat command or rename /home/\*/.ssh/ to /home/\*/ssh/ via /bin/mv command.
Give permissions listed in Fig. 12 to the domain for login session (i.e. "<kernel> /usr/sbin/sshd /bin/bash" domain)
♦ Fig. 12 Give permissions beforehand
allow_execute @COMMANDS_FOR_LOGIN allow_read/write @HOME_FILE allow_create @HOME_FILE 00-0666 allow_unlink @HOME_FILE allow_symlink @HOME_FILE allow_link @HOME_FILE @HOME_FILE allow_rename @HOME_FILE @HOME_FILE allow_truncate @HOME_FILE allow_rewrite @HOME_FILE allow_mkdir @HOME_DIR 00-0777 allow_rmdir @HOME_DIR allow_rename @HOME_DIR @HOME_DIR |
Sequentially from the top, they mean
Note that by modification in Fig. 11, "user's home directory" does not include ~/.ssh/ and ~/.ssh/\* . Above example does not check symbolic link's targets when creating symbolic links. TOMOYO Linux restricts reading and/or writing files based on dereferenced pathnames. Thus, the symbolic link's pathname does not matter. When executing programs, users can set arbitrary values to argv[0]. But "if exec.argv[0]" should be specified if programs in COMMANDS_FOR_LOGIN group are affected by argv[0]. Thus, users cannot execute arbitrary commands by creating symbolic links of hard links of busybox command. Users can create hard links only if files are under user's home directory. Thus, users cannot create hard link of /etc/shadow in order to access password file via user's home directory. Same for rename.
By changing user's home directory's permission to 0700, you can prevent other users from accessing your home directory. But sometimes you have to loosen home directory's permission in order to allow Apache to access ~/public_html/ directory. In that case, you can forbid accesses which cannot be prevented by home directory's permissions by adding "if task.uid=path1.uid" condition to individual permissions. Namely, replace Fig. 12 by Fig. 13.
♦ Fig. 13 Allowing accessing files owned by the user
allow_execute @COMMANDS_FOR_LOGIN allow_read/write @HOME_FILE if task.uid=path1.uid allow_create @HOME_FILE 00-0666 if task.uid=path1.parent.uid allow_unlink @HOME_FILE if task.uid=path1.uid allow_symlink @HOME_FILE if task.uid=path1.parent.uid allow_link @HOME_FILE @HOME_FILE if task.uid=path1.uid task.uid=path1.parent.uid task.uid=path2.parent.uid allow_rename @HOME_FILE @HOME_FILE if task.uid=path1.uid task.uid=path1.parent.uid task.uid=path2.parent.uid allow_truncate @HOME_FILE if task.uid=path1.uid allow_rewrite @HOME_FILE if task.uid=path1.uid allow_mkdir @HOME_DIR 00-0777 if task.uid=path1.parent.uid allow_rmdir @HOME_DIR if task.uid=path1.uid allow_rename @HOME_DIR @HOME_DIR if task.uid=path1.uid task.uid=path1.parent.uid task.uid=path2.parent.uid |
"task.uid" is the user ID of the process requesting this access (i.e. the user ID of user who logged in the system), "path1.uid" is the owner ID of the first pathname (for example, /dev/null for "allow_read/write /dev/null" and /tmp/source for "allow_link /tmp/source /tmp/dest"). "path1.parent.uid" is the owner ID of the first pathname's parent directory (for example, /dev/ for "allow_read/write /dev/null"). "path2.uid" is the owner ID of the second pathname (for example, /home/ for "allow_mount /dev/sda2 /home/ ext3 0". But you cannot specify "path2.uid" for "allow_rename" keyword and "allow_link" keyword because the second pathname is not accessible as of permission checks. "path2.parent.uid" is the owner ID of the second pathname's parent directory (for example, /tmp/ for "allow_link /tmp/source /tmp/dest").
In this installment, I explained access control on files from steps for restricting operations in login sessions. In the next installment, I explain rest of steps and actual operation procedure.
Go back to the seventh installment. Proceed to the ninth installment.