This chapter describes mechanisms for tightening access restrictions to machines and filesystems. It is not intended to be a complete list of security loopholes and their fixes. The facilities and administrative techniques covered are meant to complement the network transparency provided by NFS and NIS while still enforcing local security measures. For a more detailed treatment of security issues, refer to Practical Unix Security, by Garfinkel and Spafford (O'Reilly & Associates, 1996).
The relationships between hosts often define the realm of trusted users and trusted hosts. Two NIS or NFS clients, for example, may trust all users and all other client hosts. On the NFS server, only other servers may be trusted hosts and only the system administration staff may be trusted users.
WARNING: The following trusted user and trusted host descriptions apply in an environment in which you do not have to be wary of users or outsiders who will attempt to compromise security. These are basic security measures that fit in with the other network management strategies discussed in this book. If you need to secure your systems against all attacks, then you must consider the effects of having security compromised on any machine in your network. Again, these extensive security mechanisms are discussed in Practical Unix Security.Some of the common patterns of trusting hosts and users are:
The rhost parameter is the name of the remote host from where the remote user is. The ruser parameter is the login name of the remote user. The luser parameter is the name of local login name that the remote user wants transparent access to. Often luser and ruser are the same, but not always. The suser parameter is set to 1 if the UID of luser is 0, i.e., superuser. Otherwise, suser is set to 0.int ruserok(const char *rhost, int suser, const char *ruser, const char *luser);
ruserok( ) checks first if luser exists; i.e., does getpwnam( ) return success for luser ? It then determines if the remote user and hostname given are trusted on the local host; it is usually called by the remote daemon for these utilities during its startup. If the user or host are not trusted, then the user must supply a password to log in or get "Permission denied" errors when attempting to use rsh. If the remote host trusts the user and host, execution (or login) proceeds without any other verification of the user's identity.
The hosts.equiv file contains either hostnames or host-user pairs:
If a username follows the hostname, only that combination of user and hostnames is trusted. Netgroup names, in the form +@group, may be substituted for either hostnames or usernames. As with the password file, using a plus sign (+) for an entry includes the appropriate NIS map: in the first column, the hosts map is included, and in the second column, the password map is included. Entries that grant permission contain the hostname, a host and username, or a netgroup inclusion.hostname [username]
The following is /etc/hosts.equiv on host mahimahi:
The first example trusts all users on host wahoo. Users on wahoo can rlogin to mahimahi without a password, but only if the ruser and luser strings are equal.The second example is similar to the first, except that any remote user from bitatron can claim to be any local user and get access as the local user; i.e., luser and ruser do not have to be equal. This is certainly useful to the users who have access to bitatron, but it is very relaxed (or lax) security on mahimahi. The third example is the most restrictive. Only user johnc is trusted on host corvette, and of course luser and ruser (both "johnc") must be the same. Other users on host corvette are not trusted and must supply a password when logging in to mahimahi.wahoo bitatron + corvette johnc +@source-hosts +@sysadm-hosts +@sysadm-users
The last two entries use netgroups to define lists of hosts and users. The +@source-hosts entry trusts all hosts whose names appear in the source-hosts netgroup. If usernames are given as part of the netgroup triples, they are ignored. This means that hostname wildcards grant overly generous permissions. If the source-hosts netgroup contained (,stern,), then using this netgroup in the first column of hosts.equiv effectively opens up the machine to all hosts on the network. If you need to restrict logins to specific users from specific machines, you must use either explicit names or netgroups in both the first and second column of hosts.equiv.
The last example does exactly this. Instead of trusting one host-username combination, it trusts all combinations of hostnames in sysadm-hosts and the usernames in sysadm-users. Note that the usernames in the sysadm-hosts netgroup and the hostnames in the sysadm-users netgroup are completely ignored.
Permission may be revoked by preceding the host or user specification with a minus sign (-):
The first entry denies permission to all users on host wahoo. The second example negates all users in the netgroup dangerous-users regardless of what machine they originate from (the plus sign (+) makes the remote machine irrelevant in this entry).-wahoo + -@dangerous-users
If you want to deny permission to everything in both the hosts and password NIS maps, leave hosts.equiv empty.
The .rhosts file uses the same syntax as the hosts.equiv file, but it is parsed after hosts.equiv. The sole exception to this rule is when granting remote permission to root. When the superuser attempts to access a remote host, the hosts.equiv file is ignored and only the /.rhosts file is read. For all other users, the ruserok( ) routine first reads hosts.equiv. If it finds a positive match, then transparent access is granted. If it finds a negative match, and there is no .rhosts file for luser, then transparent access is denied. Otherwise, the luser 's .rhosts file is parsed until a match, either positive or negative, is found. If an entry in either file denies permission to a remote user, the file parsing stops at that point, even if an entry further down in the file grants permission to that user and host combination.
Usernames that are not the same on all systems are handled through the user's .rhosts file. If you are user julie on your desktop machine vacation, but have username juliec on host starter, you can still get to that remote host transparently by adding a line to your .rhosts file on starter. Assuming a standard home directory scheme, your .rhosts file would be /home/juliec/.rhosts and should contain the name of the machine you are logging in from and your username on the originating machine:
From vacation, you can execute commands on starter using:vacation julie
or:% rsh starter -l juliec "ls -l"
On starter, the ruserok( ) routine looks for a .rhosts file for user juliec, your username on that system. If no entry in hosts.equiv grants you permission (probably the case because you have a different username on that system), then your .rhosts file entry maps your local username into its remote equivalent. You can also use netgroups in .rhosts files, with the same warnings that apply to using them in /etc/hosts.equiv.% rlogin starter -l juliec
As a network manager, watch for overly permissive .rhosts files. Users may accidentally grant password-free access to any user on the network, or map a foreign username to their own Unix username. If you have many password files with private, non-NIS managed entries, watch the use of .rhosts files. Merging password files to eliminate non-uniform usernames may be easier than maintaining a constant lookout for unrestricted access granted through a .rhosts file.
Because of the variety of ways in which netgroups are applied, their use and administration are sometimes counterintuitive. Perhaps the most common mistake is defining a netgroup with host or usernames not present in the NIS maps or local host and password files. Consider a netgroup that includes a hostname in another NIS domain:
When a user attempts to rlogin from host poi, the local server-side daemon attempts to find the hostname corresponding to the IP address of the originating host. If poi cannot be found in the NIS hosts.byaddr map, then an IP address, instead of a hostname, is passed to ruserok( ). The verification process fails to match the hostname, even though it appears in the netgroup. Any time information is shared between NIS domains, the appropriate entries must appear in both NIS maps for the netgroup construction to function as expected.remote-hosts (poi,-,-), (muban,-,-)
Even though netgroups are specified as host and user pairs, no utility uses both names together. There is no difference between the following two netgroups:
Things that need hostnames -- the first column of hosts.equiv or NFS export lists -- produce the set of hosts {los, bitatron} from both netgroups. Similarly, anything that takes a username, such as the password file or the second column of hosts.equiv, always finds the set {mikel, stern}. You can even mix-and-match these two groups in hosts.equiv. All four of the combinations of the two netgroups, when used in both columns of hosts.equiv, produce the same net effect: users stern and mikel are trusted on hosts bitatron and los.group-a (los, mikel,) (bitatron, stern, ) group-b (los, -,) (bitatron, -,) (-, mikel, ) (-, stern, )
The triple-based format of the netgroups map clouds the real function of the netgroups. Because all utilities parse either host or usernames, you will find it helpful to define netgroups that contain only host or usernames. It's easier to remember what each group is supposed to do, and the time required to administer a few extra netgroups will be more than made up by time not wasted chasing down strange permission problems that arise from the way the netgroups map is used.
An example here helps to show how the netgroup map can produce unexpected results. We'll build a netgroup containing a list of users and hosts that we trust on a server named gate. Users in the netgroup will be able to log in to gate, and hosts in the netgroup will be able to mount filesystems from it. The netgroup definition looks like this:
In the /etc/dfs/dfstab file on gate, we'll add a host access restriction:gate-group (,stern,), (,johnc,), (bitatron, -,), (corvette, -,)
No at-sign (@) is needed to include the netgroup name in the /etc/dfs/dfstab file. The netgroup map is searched first for the names in the rw= list, followed by the hosts map.share -o rw=gate-group /export/home/gate
In /etc/hosts.equiv on gate, we'll include the gate-group netgroup:
To test our access controls, we go to a machine not in the netgroup -- NFS client vacation -- and attempt to mount /export/home/gate. We expect that the mount will fail with a "Permission denied" error:+ +@gate-group
The mount completes without any errors. Why doesn't this netgroup work as expected?vacation# mount gate:/home/gate/home/gate /mnt vacation#
The answer is in the wildcards left in the host fields in the netgroup entries for users stern and johnc. Because a wildcard was used in the host field of the netgroup, all hosts in the NIS map became part of gate-group and were added to the access list for /export/home/gate. When creating this netgroup, our intention was probably to allow users stern and johnc to log in to gate from any host on the network, but instead we gave away access rights.
A better way to manage this problem is to define two netgroups, one for the users and one for the hosts, so that wildcards in one definition do not have strange effects on the other. The modified /etc/netgroup file looks like this:
In the /etc/dfs/dfstab file on gate, we use the gate-hosts netgroup:gate-users: (,stern,), (,johnc,) gate-hosts: (bitatron,,), (corvette,,)
and in /etc/hosts.equiv, we use the netgroup gate-users. When host information is used, the gate-hosts group explicitly defines those hosts in the group; when usernames are needed, the gate-users map lists just those users. Even though there are wildcards in each group, those wildcards are in fields that are not referenced when the maps are used in these function-specific ways.share -o rw=gate-hosts /export/home/gate
11.3. Troubleshooting locking problems | 12.2. How secure are NIS and NFS? |
Copyright © 2002 O'Reilly & Associates. All rights reserved.