Access Control Lists (ACLs)
ACLs (pronounced ackls) can provide greater control over file permissions when the traditional Unix file protection in the Solaris operating system is not enough. The traditional Unix file protection provides read, write, and execute permissions for the three user classes: owner, group, and other. An ACL provides better file security by allowing you to define file permissions for the owner, owner's group, others, and specific users and groups, and allows you to set default permissions for each of these categories.
For example, assume you have a file you want everyone in a group to be able to read. To give everyone access, you would give "group" read permissions on that file. Now, assume you want only one person in the group to be able to write to that file. Standard Unix doesn't let you set that up; however, you can set up an ACL to give only one person in the group write permissions on the file. Think of ACL entries as an extension to regular Unix permissions.
ACL entries are the way to define an ACL on a file, and they are set through the ACL commands. ACL entries consist of the following fields, separated by colons:
ACL entries are defined in Table 4.22.
Setting ACL Entries
$ setfacl -s user::perms,group::perms,other:perms,mask:perms,\ acl_entry_list filename ...
Setting Versus Modifying an ACL The -s option sets a new ACL, but also replaces an entire existing ACL with the new ACL entries. You should read any exam questions on this topic very carefully, as it can be easily confused with the -m option to modify an existing ACL.
The ACL entries that can be specified with the setfacl command are described in Table 4.23.
ACL Entries Make sure you understand the ACL entries and how they work. It is quite common to get a question on the exam that gives you the ACL for a number of users/groups, such as Bill, Emily, and the "Accounts" group, and then asks which permissions does "Bill" have? Additionally, make sure you take into account the ACL mask.
The following example sets the user permissions to read/write, sets the group permissions to read-only, and other permissions to none on the txt1.doc file. In addition, the user bill is given read/write permissions on the file, and the ACL mask permissions are set to read/write, which means that no user or group can have execute permissions.
$ setfacl -s user::rw-,group::r--,other:---,mask:rw-,user:bill:rw-\txt1.doc
In addition to the ACL entries for files, you can set default ACL entries on a directory that apply to files created within the directory. For example, I'll use the setfacl command to add execute privileges on the /export/home/bholzgen directory for user bcalkins. This privilege on a directory allows the user bcalkins to change to that directory and do a long listing with the ls -l command to display the files in the directory. Before I set the ACL on this directory, let's look at the default permission that currently exists on this directory:
drwxr-xr-x 2 bholzgen staff 512 Jul 30 12:41 bholzgen
Now, issue the command to set the default ACL privileges:
setfacl -s user::rwx,g::r--,o:---,d:user::rwx,d:group::r--,d:o:---\ ,d:m:r-x,d:user:bcalkins:r-x /export/home/bholzgen
Default ACL Entries When you set default ACL entries for specific users and groups on a directory for the first time, you must also set default ACL entries for the file owner, file group, others, and the ACL mask.
getfacl -d /export/home/bholzgen
The system responds with the following:
# file: /export/home/bholzgen # owner: bholzgen # group: staff default:user::rwx default:user:bcalkins:rwx #effective:rwx default:group::r-- #effective:r-- default:mask:rwx default:other:---
Now, the only people allowed to change into the /export/home/bholzgen directory are bholzgen and bcalkins. No other members, except root, will be able to access this directorynot even members of the same group.
Checking the New File Permissions
$ ls -l total 210 -rw-r-----+ 1 mike sysadmin 32100 Sep 11 13:11 txt1.doc -rw-r--r-- 1 mike sysadmin 1410 Sep 11 13:11 txt2.doc -rw-r--r-- 1 mike sysadmin 1700 Sep 11 13:11 labnotes
Verifying ACL Entries
$ getfacl txt1.doc
# file: txt1.doc # owner: mike # group: sysadmin user::rw- user:bill:rw- #effective:rw- group::r-- #effective:r-- mask:rw- other:---
Copying a File's ACL to Another File
getfacl <filename1> | setfacl -f - <filename2>
The following example copies the ACL from file1 to file2:
getfacl file1 | setfacl -f - file2
getfacl file* # file: file1 # owner: root # group: other user::rw- user:bcalkins:rw- #effective:rw- group::r-- #effective:r-- mask:rw- other:--- # file: file2 # owner: root # group: other user::rw- user:bcalkins:rw- #effective:rw- group::r-- #effective:r-- mask:rw- other:---
Modifying ACL Entries on a File
setfacl -m <acl_entry_list> <filename1> [filename2 ...]
The arguments for the setfacl command are described in Table 4.24.
Deleting ACL Entries from a File
setfacl -d u:bcalkins file1 file2
Setting the Correct Path
Setting your path variable ($PATH) correctly is important; if you do not set it correctly, you might accidentally run a program introduced by someone else that harms the data or your system. That kind of program, which creates a security hazard, is called a Trojan horse. For example, a substitute su program could be placed in a public directory where you, as system administrator, might run it. Such a script would look just like the regular su command. The script would remove itself after execution, and you would have trouble knowing that you actually ran a Trojan horse.
The path variable is automatically set at login time through the /etc/default/login file and the shell initialization files .login, .profile, and/or .cshrc. Setting up the user search path so that the current directory (.) comes last prevents you and your users from running a Trojan horse. The path variable for superuser should not include the current directory (.).
Checking Root's Path Solaris provides a utility called the Automated Security Enhancement Tool (ASET) that examines the startup files to ensure that the path variable is set up correctly and does not contain a dot (.) entry for the current directory. ASET is discussed later in this chapter.
The setuid and setgid Programs
When set-user identification (setuid) permission is set on an executable file, a process that runs the file is granted access based on the file's owner (usually root) rather than on the user who created the process. This enables a user to access files and directories that are normally available only to the owner. For example, the setuid permission on the passwd command makes it possible for a user to modify the /etc/passwd file to change passwords. When a user executes the passwd command, that user assumes the privileges of the root ID, which is UID 0. The setuid permission can be identified by using the ls -l command. The s in the permissions field of the following example indicates the use of setuid, and the second s indicates the use of setgid:
ls -l /usr/bin/passwd -r-sr-sr-x 1 root sys 10332 May 3 08:23 /usr/bin/passwd
Many executable programs must be run by root (that is, by the superuser) in order to work properly. These executables run with the UID set to 0 (setuid=0). Anyone running these programs runs them with the root ID, which creates a potential security problem if the programs are not written with security in mind.
On the other hand, the use of setuid on an executable program presents a security risk. A determined user can usually find a way to maintain the permissions granted to him or her by the setuid process, even after the process has finished executing. For example, a particular command might grant root privileges through setuid. If a user could break out of this command, he or she could still have the root privileges granted by setuid on that file. An intruder who accesses a system will look for any files that have the setuid bit enabled.
Except for the executables shipped with Solaris that have setuid set to root, you should disallow the use of setuid programsor at least restrict and keep them to a minimum. A good alternative to using setuid on programs is to use an RBAC account, as described in Chapter 11.
# find / -user root -perm -4000 ---ls> /tmp/<filename>
The set-group identification (setgid) permission is similar to setuid, except that with setgid the process's effective GID is changed to the group owner of the file, and a user is granted access based on permissions granted to that group. By using the ls -l command, you can see that the file /usr/bin/mail has setgid permissions:
-r-x--s--x 1 bin mail 61076 Nov 8 2001 /usr/bin/mail
The following example illustrates how to set the UID on an executable file named myprog1:
chmod 4711 myprog1
ls -l myprog1
The system responds with this:
-rws--x--x 1 root other 25 Mar 6 11:52 myprog1
The following example illustrates how to set the GID on an executable file named myprog1:
chmod 2751 myprog1
ls -l myprog1
-rwxr-s--x 1 root other 25 Mar 6 11:58 myprog1
The following sections describe a few of the commands used to view information about users who have logged in to the system.
Monitoring Users and System Usage
As a system administrator, you need to monitor system resources and watch for unusual activity. Having a method to monitor the system is useful, especially when you suspect a breach in security. For example, you might want to monitor the login status of a particular user. In that case, you could use the logins command to monitor a particular user's activities, as described in Step by Step 4.6.
You should monitor user logins to ensure that their users' passwords are secure. A potential security problem is for users to use blank passwords (that is, users using carriage returns for passwords) or no password at all. When an account does not have a password, the password prompt will not be presented at login. Simply enter the user name, and you are in. You can periodically check user logins by using the method described in Step by Step 4.7.
Another good idea is to watch anyone who has tried to access the system but failed. You can save failed login attempts by creating the /var/adm/loginlog file with read and write permission for root only. After you create the loginlog file, all failed login activity is automatically written to this file after five failed attempts. This file does not exist by default; you, as the system administrator, must create it. To enable logging to this file as root, you can create the file as follows:
Then set the permission on the file to 600:
chmod 600 /var/adm/loginlog
The loginlog file contains one entry for each failed attempt. Each entry contains the user's login name, the tty device, and the time of the failed attempt. If a person makes fewer than five unsuccessful attempts, none of the attempts is logged.
# more /var/adm/loginlog root:/dev/pts/5:Wed Apr 11 11:36:40 2002 root:/dev/pts/5:Wed Apr 11 11:36:47 2002 root:/dev/pts/5:Wed Apr 11 11:36:54 2002 root:/dev/pts/5:Wed Apr 11 11:37:02 2002
The loginlog file might grow quickly. To use the information in this file and to prevent the file from getting too large, you must check it and clear its contents occasionally. If this file shows a lot of activity, someone might be attempting to break in to the computer system.
Checking Who Is Logged In
You use the Solaris who command to find out who is logged in to a system. To obtain the information it gives you, the who command examines the /var/adm/utmpx and /var/adm/wtmpx files. The utmpx file contains user access and accounting information for the who command (as well as for the write and login commands). The wtmpx file contains the history of user access and accounting information for the utmpx file.
Without arguments, the who command lists the login account name, terminal device, login date and time, and where the user logged in. Here is an example:
# who root pts/3 May 11 14:47 (10.64.178.2) root pts/1 May 10 15:42 (sparc1.PDESIGNINC.COM) root pts/2 May 10 15:53 (sparc1.PDESIGNINC.COM) root pts/4 May 11 14:48 (pluto)
Table 4.25 lists some of the most common options used with the who command.
The rusers command is similar to the who command, but it can be used to list users logged in on a remote host. To use rusers, the rpc.rusers daemon must be running. Check whether the rpc.rusers daemon is running by typing
For more information on the svcs command, refer to Chapter 3.
# rusers -l Sending broadcast for rusersd protocol version 3... root smokey:pts/1 Aug 12 10:07 29 (192.168.1.87) root ultra5:pts/1 Aug 12 17:33 (billsgateway.wca) Sending broadcast for rusersd protocol version 2... #
The whoami Command
The command whoami displays the effective current username. It is a lot like the who command used with the am and i options. These two options to the who command limit the output to describing the invoking user, which is equivalent to the -m option. am and i must be separate arguments.
whoami is a carryover from Berkeley Software Distribution (BSD) Unix. This old BSD command is found under the /usr/ucb directory with other BSD commands. /usr/ucb/whoami displays the login name that corresponds to the current effective UID. If you have used su to temporarily change to another user, /usr/ucb/whoami reports the login name associated with that user ID. For example, suppose you are logged in as root and issue the following su command to become wcalkins:
su - wcalkins
Now issue the who am i command:
who am i
root pts/7 Oct 18 19:08
Next, you can issue the /usr/ucb/whoami command:
The system reports your current effective UID as follows:
The whodo Command
The whodo command produces formatted and dated output from information in the /var/adm/utmpx, /tmp/ps_data, and /proc/pid files. It displays each user logged in and the active processes owned by that user. The output of the whodo command shows the date, time, and machine name. For each user who is logged in, the system displays the device name, UID, and login time, followed by a list of active processes associated with the UID. The process list includes the device name, process ID, CPU minutes and seconds used, and process name. You issue the whodo command as follows:
Thu May 11 15:16:56 EDT 2001 holl300s pts/3 root 14:47 pts/3 505 0:00 sh pts/3 536 0:00 whodo pts/1 root 15:42 pts/1 366 0:00 sh pts/1 514 0:00 rlogin pts/1 516 0:00 rlogin pts/2 root 15:53 pts/2 378 0:00 sh pts/4 root 14:48 pts/4 518 0:00 sh
You use the -l option with the whodo command to get a long listing:
1:11pm up 4 day(s), 18 hr(s), 20 min(s) 3 user(s) User tty login@ idle JCPU PCPU what root console Mon 9am 22:00 /usr/dt/bin/sdt_shell -c u root pts/4 Mon 9am 22:00 4 -ksh
The fields displayed are the user's login name; the name of the tty the user is on; the time of day the user logged in; the idle time (which is the time since the user last typed anything in hours:minutes); the CPU time used by all processes and their children on that terminal (in minutes:seconds); the CPU time used by the currently active processes (in minutes:seconds); and the name and arguments of the current process.
The last Command
The Solaris last command looks in the /var/adm/wtmpx file for information about users who have logged in to the system. The last command displays the sessions of the specified users and terminals in reverse chronological order, displaying the most recent login first. For each user, last displays the time when the session began, the duration of the session, and the terminal where the session took place. The last command also indicates whether the session is still active or was terminated by a reboot.
For example, the command last root console lists all of root's sessions, as well as all sessions on the console terminal:
# last root console |more
root pts/2 10.64.178.2 Tue May 30 11:24 still logged in root pts/1 10.64.178.2 Fri May 26 14:26 - 15:47 (01:20) root pts/1 10.64.178.2 Fri May 26 11:07 - 13:37 (02:29) root pts/1 10.64.178.2 Fri May 26 10:12 - 10:23 (00:11) root pts/1 10.64.178.2 Fri May 26 09:40 - 09:42 (00:02) root console :0 Wed May 24 16:36 - 16:38 (00:01) root console :0 Wed May 24 16:20 - 16:36 (00:15) root pts/3 10.64.178.2 Wed May 24 13:52 - 14:22 (1+00:30) root pts/1 ultra5.PDESIGNINC Mon May 22 15:14 - 15:15 (00:00) root pts/2 sparc21.PDESIGNINC Wed May 10 15:53 - 15:47 (23:53)
Controlling Network Security
Control system security through restricting FTP access and using /etc/hosts.equiv and $HOME/.rhosts files, and SSH fundamentals.
The most difficult system administration issue to address is network security. When you connect your computer to the rest of the world via a network such as the Internet, someone can find an opening and breach your security. The following sections describe a few fundamental recommendations for tightening up a system in a networked environment.
Securing Network Services
Solaris is a powerful operating system that executes many useful services such as FTP and HTTP services. However, some of the services aren't needed and can pose potential security risks, especially for a system that is connected to the Internet. The first place to start tightening up a system is by disabling unneeded network services.
In past releases of Solaris, these services were managed by inetd, which obtained its instructions from the /etc/inetd.conf file. In Solaris 10, you'll notice that this file is substantially smaller because inetd is now started by the SMF, which is described in Chapter 3. The inetd daemon is configured using the inetadm command, which is described in Chapter 8.
By default, inetd is configured for 40 or more services, but you probably need only some of them. You can list all of the network services and view their state with the inetadm command as follows:
# inetadm ENABLED STATE FMRI enabled online svc:/network/rpc/gss:default enabled online svc:/network/rpc/mdcomm:default enabled online svc:/network/rpc/meta:default enabled online svc:/network/rpc/metamed:default enabled online svc:/network/rpc/metamh:default disabled disabled svc:/network/rpc/rex:default enabled online svc:/network/rpc/rstat:default enabled online svc:/network/rpc/rusers:default disabled disabled svc:/network/rpc/spray:default disabled disabled svc:/network/rpc/wall:default <output is truncated> . . .
You can deactivate unnecessary services by disabling them. For example, to disallow Telnet connections to the system, you would disable it as follows:
inetadm -d telnet
To disable FTP, type
inetadm -d ftp
You can verify that the FTP service has been disabled by typing
The system responds with
disabled disabled svc:/network/ftp:default
You also can type
The system responds with
STATE STIME FMRI disabled 9:02:23 svc:/network/ftp:default
It is critical that you turn off all unneeded network services because many of the services that are run by inetd, such as rexd, pose serious security vulnerabilities. rexd is a daemon that is responsible for remote program execution. On a system that is connected to the rest of the world via the Internet, this could create a potential entry point for a hacker. You should absolutely disable TFTP unless it's required, as with a JumpStart server. TFTP is managed by the SMF, under the service identifier svc:/network/tftp/udp6:default. Administrative actions on this service, such as enabling, disabling, or requesting restart, can be performed using svcadm. Responsibility for initiating and restarting this service is delegated to inetd. Use inetadm to make configuration changes and to view configuration information for this service. The service status can be queried using the svcs command.
You might also want to disable finger so that external users can't figure out the usernames of your internal userswhich would make breaking in much easier. Whether you keep the other services much depends on the needs of your site. Disable finger as follows:
inetadm -d finger
Other services that you may want to consider disabling are
The /etc/default/login File
With this entry, root is allowed to log in only from the secure system console and not via the network by using telnet or rlogin. However, this entry does not disallow a user from using the su command to switch to root after logging in as a regular user if he or she knows the root password.
Modems are always a potential point of entry for intruders. Anyone who discovers the phone number to which a modem is attached can attempt to log in. Low-cost computers can be turned into automatic calling devices that search for modem lines and then try endlessly to guess passwords and break in. If you must use a modem, you should use it for outgoing calls only. An outgoing modem will not answer the phone. If you allow calling in, you should implement a callback system. A callback system guarantees that only authorized phone numbers can connect to the system. Another option is to have two modems that establish a security key between them. This way, only modems with the security key can connect with the system modem and gain access to the computer.
Along with protecting passwords, you need to protect your system from a root user coming in from across the network. For example, say systemA is a trusted host from which a user can log in without being required to enter a password. A user who has root access on systemA could access the root login on systemB simply by logging in across the network, if systemA is set up as a trusted host on systemB. When systemB attempts to authenticate root from systemA, it relies on information in its local filesspecifically, /etc/hosts.equiv and /.rhosts. Because of the many risks posed by rlogin and other r commands, you should not use them. Instead, you should use the Secure Shell (SSH) commands, which are described in the section "The Secure Shell (ssh)," later in this chapter.
The /etc/hosts.equiv File
system1 system2 user_a
If a user attempts to log in remotely by using rlogin from one of the hosts listed in this file, and if the remote system can access the user's password entry, the remote system enables the user to log in without a password.
When an entry for a host is made in /etc/hosts.equiv (for example, the sample entry for system1 shown earlier), the host is trusted and so is any user at that machine. If the username is also mentioned, as in the second entry shown in the previous example, the host is trusted only if the specified user is attempting access. A single line of + in the /etc/hosts.equiv file indicates that any host is trusted.
Don't Trust Everyone Using a + in the hosts.equiv or .rhosts file is very bad practice and could pose a serious security problem because it specifies that all systems are trusted. You should get into the habit of listing the trusted systems and not using the + sign. Better yet, you should use a more secure alternative to rlogin, such as the Secure Shell (ssh).
Security and the /etc/hosts.equiv File The /etc/hosts.equiv file presents a security risk. If you maintain an /etc/hosts.equiv file on your system, this file should include only trusted hosts in your network. The file should not include any host that belongs to a different network or any machines that are in public areas. Also, you should never put a system name into the /etc/hosts.equiv file without a username or several names after it.
The .rhosts File
The .rhosts file is the user equivalent of the /etc/hosts.equiv file. It contains a list of hosts and users. If a host/user combination is listed in this file, the specified user is granted permission to log in remotely from the specified host without having to supply a password. Note that an .rhosts file must reside at the top level of a user's home directory because .rhosts files located in subdirectories are not consulted. Users can create .rhosts files in their home directories; this is another way to allow trusted access between their own accounts on different systems without using the /etc/hosts.equiv file.
The .rhosts file presents a major security problem. Although the /etc/hosts.equiv file is under the system administrator's control and can be managed effectively, any user can create an .rhosts file that grants access to whomever the user chooseswithout the system administrator's knowledge.
Disabling .rhosts and hosts.equiv Files To disable .rhosts and /etc/hosts.equiv access altogether while still allowing the rlogin protocol, you comment the lines that reference pam_rhosts_auth.so.1 from /etc/pam.conf. This forces rlogin to use a password during authentication and effectively disables in.rshd and in.rexecd.
File Transfer Protocol (FTP) is a common tool for transferring files across a network. Although most sites leave FTP enabled, you need to limit who can use it. Solaris contains various configuration files in the /etc/ftpd directory to control access to the FTP server. One of these files is a file named /etc/ftpd/ftpusers, which is used to restrict access via FTP. The /etc/ftpd/ftpusers file contains a list of login names that are prohibited from running an FTP login on the system. The following is an example of a default /etc/ftpd/ftpusers file:
# more /etc/ftpd/ftpusers # ident "@(#)ftpusers 1.5 04/02/20 SMI" # # List of users denied access to the FTP server, see ftpusers(4). # root daemon bin sys adm lp uucp nuucp smmsp listen gdm webservd nobody noaccess nobody4
Root Access to FTP The default in Solaris 10 is to not allow FTP logins by root. It is dangerous to allow root access via FTP because that would allow anyone who knows the root password to have access to the entire system.
The FTP server in.ftpd reads the /etc/ftpd/ftpusers file each time an FTP session is invoked. If the login name of the user trying to gain access matches a name in the /etc/ftpd/ftpusers file, access is denied.
The /etc/ftpd/ftphosts file is used to allow or deny access to accounts from specified hosts. The following example allows the user ftpadmin to connect via FTP from the explicitly listed addresses 18.104.22.168, 22.214.171.124, and 126.96.36.199; and deny the specified ftpadmin user to connect from the site 188.8.131.52:
# Example host access file # # Everything after a '#' is treated as comment, # empty lines are ignored allow ftpadmin 184.108.40.206 220.127.116.11 18.104.22.168 deny ftpadmin 22.214.171.124
The file /etc/shells contains a list of the shells on a system. Whereas the /etc/ftpd/ftpusers file contains a list of users not allowed to use FTP, the /etc/shells file enables FTP connections only to those users running shells that are defined in this file. If this file exists and an entry for a shell does not exist in this file, any user running the undefined shell is not allowed FTP connections to this system.
# more /etc/shells /sbin/sh /bin/sh /bin/ksh
Securing Superuser Access
The Unix superuser (root) is immune from restrictions placed on other users of the system. Any Unix account with a UID of 0 is the superuser. All Unix systems have a default superuser login named root. The user of this account can access any file and run any command. This login is valuable because any user who might have gotten himself or herself into trouble by removing access permissions, forgetting his or her password, or simply needing a file from an area to which he or she doesn't have access can be helped by root.
However, root access can be dangerous. Root can delete anything, including the operating system. The root login is both dangerous and necessary. System administrators must not give the root password to anyone and should use it themselves only when required. If it becomes necessary to grant superuser privileges to non-root users, you should utilize roles, as described in Chapter 11.
Restricting Root Access
Root access needs to be safeguarded against unauthorized use. You should assume that any intruder is looking for root access. You can protect the superuser account on a system by restricting access to a specific device through the /etc/default/login file. For example, if superuser access is restricted to the console, the superuser can log in only at the console, which should be in a locked room. Anybody who remotely logs in to the system to perform an administrative function must first log in with his or her login and then use the su command to become superuser.
Step by Step 4.8 describes the procedure for restricting root from logging in to the system console from a remote system.
In Step by Step 4.8, you set the variable CONSOLE to /dev/console. If the variable CONSOLE were set as follows with no value defined, root could not log in from anywhere, not even from the console:
With the CONSOLE value set to nothing, the only way to get into the system as root is to first log in as a regular user and then become root by issuing the su command. If the system console is not in a controlled environment, the option of not being able to log in to the console as root might be useful.
Monitoring Superuser Access
Solaris can be set up to log all attempts to become superuser. The logs that contain this information are useful when you're trying to track down unauthorized activity. Whenever someone issues the su command to switch from being a user to being root, this activity is logged in the file /var/adm/sulog. The sulog file lists all uses of the su commandnot only those used to switch from being a user to being superuser. The entries in the sulog file show the date and time the command was entered, whether the command was successful, the port from which the command was issued, and the name of the user and the switched identity.
To monitor who is using the su command, the sulog logging utility must be turned on in the /etc/default/su file. By default, su logging is enabled. Step by Step 4.9 describes how to turn on logging of the su command if it has been disabled.
Through the /etc/default/su file, you can also set up the system to display a message on the console each time an attempt is made to use the su command to gain superuser access from a remote system. This is a good way to immediately detect when someone is trying to gain superuser access to the system on which you are working. Step by Step 4.10 describes how to display root access attempts to the console.