![]() | ![]() |
[22]For brevity, we don't describe how a secret key and a message are combined, nor how the one-way hash function is applied. Unless you are a skilled cryptographer, you should not attempt to invent your own scheme. Instead, use the algorithm described in RFC2104.Even though your message and MAC are sent in the clear to the server, an attacker in the middle cannot change the message without the server knowing it because this would change the result of the MAC computation on the server. The attacker can't change the MAC to match a tampered message because he doesn't know the secret key that only the server and you know. An example of a one-way hash function is MD5. An example of a MAC algorithm is HMAC-MD5. Note that when you add a MAC to a message you are enabling the security service of integrity.
or:IP: Hardware address '%s' trying to be our address %s!
on the legitimate client's console. Once the legitimate client is disabled, the attacker then changes the IP address on a machine that he controls to that of the legitimate client and can then access the victim.IP: Proxy ARP problem? Hardware address '%s' thinks it is %s
Let PRIV_S be the private key of the server. Then the public key of the server is:(1) PUBLIC_C = ( 3 PRIV_C ) mod AUTH_DH_MOD
The client computes a common key between the client and server as:(2) PUBLIC_S = ( 3 PRIV_S ) mod AUTH_DH_MOD
The server computes the common key between the server and client as:(3) COMMON_C_S = ( PUBLIC_S PRIV_C ) mod AUTH_DH_MOD
To prove that COMMON_C_S equals COMMON_S_C, we replace PUBLIC_S in statement (3) with the expression it was derived from in statement (2) and drop the MOD part of the expression. We do the same for PUBLIC_C in statement (4) with the expression from statement (2):(4) COMMON_S_C = ( PUBLIC_C PRIV_S ) mod AUTH_DH_MOD
Because multiplication is a commutative operation, it is obvious that COMMON_C_S_PRIME equals COMMON_S_C_PRIME. Therefore, COMMON_C_S equals COMMON_S_C.(3.1) COMMON_C_S_PRIME = ( 3 PRIV_S )PRIV_C = 3 PRIV_S * PRIV_C (4.1) COMMON_S_C_PRIME = ( 3 PRIV_C )PRIV_S = 3 PRIV_C * PRIV_S
When a filesystem is exported with the sec=dh option, clients using NFS Version 2 must mount it with the sec=dh option if they are to enjoy normal user access privileges in the filesystem. On the NFS client, add the sec=dh option in the automounter map entry, or the /etc/vfstab entry for the filesystem:share -o sec=dh,rw /export/home/thud
If the client is using NFS Version 3, it will use Version 3 of the MOUNT protocol. MOUNT Version 3 will return the RPC security flavor that the directory is exported with, along with the filehandle of the directory. Thus, with NFS Version 3, the sec=dh mountoption is not necessary. If a user accessing the filesystem can generate a session key with the NFS server, it is used to encrypt the timestamps sent with that user's NFS requests. If the server decrypts the timestamps successfully, the netname presented by the user is trusted and is used to derive normal Unix-style credentials for the purpose of file access. It's possible, though, that the user can't exchange a session key with the server. This will be the case if the user doesn't have a public key defined, or if the user cannot supply the proper private key to generate a common key using Diffie-Hellman key exchange. When there is no valid common key, some NFS servers remap the user to nobody. However, by default, Solaris 8 rejects such users. If you want to give such users anonymous access you can export the filesystem with the following line in /etc/dfs/dfstab :automounter auto_home entry: thud -sec=dh bonk:/export/home/thud vfstab entry: bonk:/export/home/thud - /thud nfs - no sec=dh,rw
Within the NFS/dh system, a user without a valid public/private key pair becomes an anonymous user on the NFS server and is subject to the same access restrictions (discussed earlier in this chapter) that apply to the anonymous user nobody. To utilize NFS/dh without impairing a user's ability to do work, you must define public and private key pairs for trusted users and trusted hosts.share -o sec=dh:none,rw /export/home/thud
[23]If you are not running NIS or NIS+, you can still create keys, and use NFS/dh with the publickey entry in nsswitch.conf set to files. You will need to set up an NIS domain name on each NFS client and server (see Section 3.2.4, "Enabling NIS on client hosts" for how to set up a domain name on a host). You will also have to devise a means for keeping all the /etc/publickey files on each client and server synchronized, since the encrypted private key field must change every time the user's password changes.
The keys are long strings of hexadecimal digits, representing the encrypted key values. Obviously, the NIS map cannot contain the actual private keys, or the entire encryption mechanism would be baseless. Instead, the /etc/publickey file's private key field contains the user's private key, encrypted with the user's login password. For host entries, the private key is encrypted using the root password. The private keys themselves are large random numbers, just like the session key that is used by RPC/DH. Identifiers in /etc/publickey are called netnames and take one of two forms:unix.10461@nesales publickey:privatekey
The first form is used for user keys; it defines a key valid in the current NIS domain. The host key is used to create a RPC/DH key for the superuser on the named host. No user key is required for root -- only a host key. The /etc/publickey file is changed by the RPC/DH utilities that create and manage key values. Because it contains encrypted key strings, it is not easily edited by the superuser, just as the password fields in /etc/passwd cannot be hand-edited. The publickey file should exist only on the NIS master server, or else users' private keys will become out of date when they change their passwords (and therefore change the encryption key used to store their private keys).unix.uid@NISdomain unix.host@NISdomain
The password is used to encrypt the private key so that it can be safely placed in the publickey maps. Unfortunately, the user's existing password in the NIS passwd maps must be supplied, requiring you to know the user's password. This is fine if you are adding the user to passwd map anyway; he is therefore a new user. However, it is very inconvenient if you are adding NFS/dh security and have a large pool of existing users because:nismaster# newkey -u stern Adding new key for unix.1461@nesales.East.Sun.COM. Enter stern's login password:
If you look at the /etc/publickey on host nismaster you should see something like:nismaster# newkey -u template Adding new key for unix.66666@nesales.East.Sun.COM. Enter template's login password:
The netname of template is unix.66666@nesales.East.Sun.COM. Each of your users will have a similar netname, except for the number between the unix prefix, and the @nesale.East.Sun.COM suffix. The last long hexadecimal number after the colon (:) is user template 's private key, encrypted with template 's login password. Now for each user, make a copy of template 's entry in the /etc/publickey file, but change the netname to match the user. Let's say that your set of users is stern, labiaga, and mre, with UIDs of 1461, 15124, and 23154, respectively. You then edit the /etc/publickey file to look like:unix.66666@nesales.East.Sun.COM 74365f4e03701cf96de938a59baa39f1039ada407b4ab3a3:9b7130a3f38c6e86f431f81ce1cf64b5e59991d3d5d1ce0596fd5167cb878b51
You now want to push the publickey file changes into the publickey NIS maps:unix.66666@nesales.East.Sun.COM 74365f4e03701cf96de938a59baa39f1039ada407b4ab3a3:9b7130a3f38c6e86f431f81ce1cf64b5e59991d3d5d1ce0596fd5167cb878b51 unix.1461@nesales.East.Sun.COM 74365f4e03701cf96de938a59baa39f1039ada407b4ab3a3:9b7130a3f38c6e86f431f81ce1cf64b5e59991d3d5d1ce0596fd5167cb878b51 unix.15124@nesales.East.Sun.COM 74365f4e03701cf96de938a59baa39f1039ada407b4ab3a3:9b7130a3f38c6e86f431f81ce1cf64b5e59991d3d5d1ce0596fd5167cb878b51 unix.23514@nesales.East.Sun.COM 74365f4e03701cf96de938a59baa39f1039ada407b4ab3a3:9b7130a3f38c6e86f431f81ce1cf64b5e59991d3d5d1ce0596fd5167cb878b51
You have now almost effortlessly fully populated the publickey maps, but each entry has the same public key, same private key, and the same password. This is not what you want for the long term. So now you tell your users to expend some effort. Each user should be told to:nismaster# cd /var/yp nismaster# make publickey updated publickey pushed publickey
The first chkey command invocation reencrypts his private key with his login password. The second chkey invocation generates a brand new and unique private key and public key pair. If the user supplies an invalid password, no password or key will be created. If the user's password is valid, and the NIS master server is receiving key updates, the key will be added to, or modified in, the NIS publickey maps. Both the chkey and newkey utilities update the /etc/publickey file on the NIS master server. To ensure that your users are following the chkey instructions, you can check the publickey.byname map to see if both the private key and the public key fields of each user have changed, by comparing them to that of the user template. The only way to create host keys (for superuser verification) is to use newkey -h as root :client% chkey -p Updating nis publickey database. Reencrypting key for 'unix.1461@nesales.East.Sun.COM'. Please enter the Secure-RPC password for stern: Please enter the login password for stern: Sending key change request to nismaster ... client% chkey Updating nis publickey database. Generating new key for 'unix.1461@nesales.East.Sun.COM'. Please enter the Secure-RPC password for stern: Sending key change request to nismaster ...
You must create a host key for every NFS client (so that the client can mount filesystems shared with sec=dh) and NFS server (so that the server can generate the common key). To receive NIS map updates from newkey or chkey, the master NIS server must be able to run rpc.ypupdated. On Solaris 8, this daemon is started as part of the /usr/lib/netsvc/yp/ypstart script, which in turn is started by the /etc/init.d/rpc boot script. On every machine that will be using NFS/dh, make sure you are running the keyserv daemon. This process is used to cache private and common keys, and is also started out of /etc/init.d/rpc with lines of the form:# newkey -h bitatron Adding new key for unix.bitatron@nesales.East.Sun.COM. New password:
As you can see, keyserv will not start if there is no domain name established. Make sure keyserv can start, or you will not be able to create session keys, even if you have a valid public and private key pair in the publickey NIS maps.if [ -x /usr/sbin/keyserv -a \ -n "'/usr/bin/domainname 2>/dev/null'" ]; then /usr/sbin/keyserv >/dev/msglog 2>&1 echo " keyserv\c" fi
The private key is given to the keyserv daemon, which caches it for generating common keys. The common keys are used to exchange session keys with NFS servers, as described earlier in this section. Therefore, the entire session key generation procedure goes like this:Password does not decrypt secret key (type = 192-0) for 'unix.23514@nesales.East.Sun.COM'. Password does not decrypt any secret keys for unix.23514@nesales.East.Sun.COM.
Note that if your login and RPC/DH passwords are different, whether you use rlogin or not, you must use keylogin to allow keyserv to see your private key. Or else you can use chkey -p to change your RPC/DH password to your login password. Keys that are decrypted via keylogin are also passed to keyserv, where they remain until the user executes a keylogout. If you are going to be logging into nontrusted hosts, use keylogin to decrypt your key, and add keylogout to your .logout file (in your home directory) so that your key is destroyed when you log out. You must reference the NIS passwd map in order for the automatic private key caching to occur. For proper operation of NFS/dh, do not put users in the local file /etc/passwd, or their encrypted private keys may become out-of-date when they change their local passwords but do not change the NIS-managed password used to encrypt the private key in the publickey map. On the NIS master server, make sure you use an alternate password source file, instead of the default /etc/passwd. There's one thing missing: how does the root, or host, private key get decrypted? You establish a session key using the host key for the NFS server. In order for the server to exchange keys with you, it must be able to decrypt the host's private key, and this requires the root password or a "hidden" copy of the root key. One obvious approach is to force someone to supply the root password when the machine boots, so that the host private key in the publickey map can be decrypted and given to the keyserv daemon. However, this is often too restrictive: if an NFS server boots and no system administrator is present to supply the root password, no NFS/dh services will be available. You can solve this dilemma by using the -r option to keylogin to store the host's private key in the protected /etc/.rootkey file of the NFS server. Note that this is not the root password; it's the large, random number used as the host's private key. When the keyserv daemon starts up, it reads the host's key out of this file so that clients of the host can establish session keys with it. A similar issue applies to the NFS client when you are using the automounter to access NFS mounted filesystems. Unless the superuser has logged into the system, and thus manually established his private key into keyserv, users will not be able use the automounter to access filesystems exported with sec=dh. Once again, you use keylogin -r, this time running it on the NFS client. When the keyserv daemon starts up, it reads the host's key out of this file so that the automounter can establish session keys on NFS servers.remote% keylogin Password:
You can also set it on a live system without rebooting by:* 10 minutes set rpcsec:authdes_win = 600
The shorter the window, the less time a would-be network spoofer has to attempt to replay any request, but on the other hand, the less clock drift you can tolerate.# echo authdes_win/W 0t600 | adb -k -w authdes_win: 0x12c = 0x258
[24]This appraisal is the opinion of one of the co-authors of this book, Mike Eisler, who was the project lead for SEAM while employed by Sun Microsystems, Inc.However, the rest of this section collects some practical overview information on SEAM that you might find useful as you approach the issue of deploying Kerberos V5. SEAM 1.0 is available for Solaris 2.6 and Solaris 7, and is packaged with the Solaris Easy Access Server (SEAS) 3.0 product, which is unbundled from Solaris 2.6 and Solaris 7. If you bought a server from Sun, you might find SEAS 3.0 preinstalled. At the time this book was written, SEAM 1.0.1 was available for Solaris 8 as a free download from Sun's website. Look for the product called Solaris 8 Admin Pack. Do not attempt to run SEAM 1.0 on Solaris 8. If you upgrade to Solaris 8 from a Solaris 2.6 or Solaris 7 system that has SEAM 1.0 installed, then you should immediately install SEAM 1.0.1. SEAM 1.0 and SEAM 1.0.1 rely on a GUI-based installation technology that is similar to Installshield for Windows systems. What you do not want to do is go ahead and install SEAM without reading the documentation. A couple of notes:
Solaris Release | Unbundled Product | SEAM Version | Features Integrated with Solaris | Features Integrated in Unbundled Product |
---|---|---|---|---|
Solaris 2.6 | SEAS 3.0 | SEAM 1.0 | RPCSEC_GSS hooks | KDC, Remote KDC administration, Kerberized networking utilities, Kerberos client utilities, RPCSEC_GSS, GSS-API, Kerberos V5 GSS provider, Kerberos V5 PAM module |
Solaris 7 | SEAS 3.0 | SEAM 1.0 | RPCSEC_GSS, GSS-API | KDC, Remote KDC administration, Kerberized networking utilities, Kerberos client utilities, Kerberos V5 GSS provider, Kerberos V5 PAM module |
Solaris 8 | Solaris 8 Admin Pack | SEAM 1.0.1 | RPCSEC_GSS, GSS-API, Kerberos client utilities, Kerberos V5 GSS provider, Kerberos V5 PAM module | KDC, Remote KDC administration, Kerberized networking utilities |
Presumably the progression in Table 12-1 will continue with future versions of Solaris and other operating systems.
The fifth column of Table 12-1 consistently lists "Kerberized networking utilities." These are utilities like rlogin, rsh, rcp, ftp, and telnet (and their server daemons) that have been modified to understand Kerberos V5 security. The reason they are there is that they facilitate the deployment of an Intranet that sends no passwords in the clear over the wire, and indeed, via forwardable TGTs, enables you to send no passwords at all. Without these utilities, there would be less point in having strong NFS security, since passwords would often appear on your network. This is another drawback of RPC/DH: it does not add strong security to the basic networking utilities. By now, we've mentioned PAM several times without explaining it. Recall that your RPC/DH password is used to decrypt your private key. If your RPC/DH password is the same as your Unix login password, then you don't need to provide your RPC/DH password separately. How does this happen? The Solaris login command has code in it to try to decrypt the user's private key with the Unix login password. Now suppose you've installed Kerberos V5 and would like the system to attempt to use the Unix login password as the key that decrypts your TGT from the KDC. One way would be for your operating system vendor to change the login command to do so. But then, you decide you'd like the su command and the desktop lock screen feature to do the same. After a while, it gets to be a lot of utilities to maintain. A better way is to have pluggable framework that calls security mechanism specific code in shared objects and has them take care of acquiring credentials. This is what PAM does. SEAM provides a Kerberos V5 PAM module. Check out your system's documentation for information on PAM; PAM is common to many Unix systems. Here are some final recommendations for and observations about SEAM installation:When a filesystem is exported with the sec=krb5 option, clients using NFS Version 2 must mount it with the sec=krb5 option if they are to enjoy normal user access privileges in the filesystem. On the NFS client, add the sec=krb5 option in the automounter map entry or the /etc/vfstab entry for the filesystem:share -o sec=krb5,rw /export/home/thud
As was the case for enabling NFS/dh (see Section 12.5.4.5, "Enabling NFS/dh") with NFS Version 3, the sec=krb5 option is not necessary in the automounter map or vfstab entries. The krb5 option uses a combination of DES symmetric key encryption and the MD5 one-way hash function to produce the RPC credentials that are sent to, and authenticated by, the NFS server. Not only is there a krb5 option to sec=, but there are krbi and krbp as well. Like the krb5 option, krb5i uses Kerberos V5 to authenticate users to NFS servers when the filesystem is exported with sec=krb5i. Unlike krb5, it also computes an MD5-based MAC on every remote procedure call request to the server, and every response to the client. The MAC is computed on an entire message: RPC header, plus NFS arguments or results. Thus krb5i provides integrity protection, hence the trailing i in krb5i. Like krb5 and krb5i, krb5p uses Kerberos V5 to authenticate. Like krb5i it uses Kerberos V5 to provide integrity. Unlike krb5 and krb5i, krb5p uses Kerberos V5's DES encryption to provide privacy. Note that only the NFS arguments and results are encrypted; the RPC headers go in the clear. So an attacker could deduce which NFS operation is being performed, but not on what file, nor what the file or directory content is.automounter auto_home entry: thud -sec=krb5 bonk:/export/home/thud vfstab entry: bonk:/export/home/thud - /thud nfs - no sec=krb5
sec= value | Throughput in MB/sec | Throughput Degradation Relative to sec=sys | Percent CPU Utilization on Server |
---|---|---|---|
sys | 5.40 | N/A | 69% |
krb5 | 5.26 | 2.6% | 70% |
krb5i | 4.44 | 17.7% | 77% |
krb5p | 1.45 | 73.1% | 99% |
This means the clients pick any of the three flavors of krb5 when they mount the NFS filesystem. Note that this is one instance where even if the client is using NFS Version 3, that the administrator on the client may want to specify a sec= option in their automounter maps or vfstab or on their mount command line. The reason is that the client (at least the Solaris 8 client) will pick from the array of security flavors that mountd returns the first security flavor that the client supports. So if a client prefers krb5 but krb5p is first, sec= is needed for the mount command to override the automatic choice. Given the results in Table 12-2, you might want to be careful about exporting filesystems with krb5i or krb5p security enabled. If you have data that can go in the clear on the network, then never export it with krb5p. If your users are writing data over the network, and very bad things could happen if an attacker spliced the RPC header from a sec=krb5 NFS request onto a forged set of destructive arguments, then enable krb5i. Otherwise krb5 should be sufficient. Indeed, for certain kinds of read-only data, sec=sys or sec=none are fine.share -o sec=krb5p:krb5i:krb5,rw /export/home
to:share -o rw /export/home
and not expect some chaos. That you can combine any two or more sec= options on the same dfstab entry allows you to stage some graceful transitions. For example, suppose you've decided to use NFS/dh. You may have some legacy software running on some NFS clients that is stuck on older systems. Thus you can't upgrade the client systems to an operating system that can support stronger NFS security. You can do the following:share -o sec=krb5,rw /export/home
such that the legacy machines and upgrade machines are each placed in their own netgroup.share -o sec=sys,rw=legacy-group,sec=dh,rw=upgrade-group /export/home