December 15, 2006

Best practices for NIS use

Author: Evi Nemeth, Garth Snyder, and Trent Hein

Yesterday we introduced NIS, the Network Information Service. In the second and final article in this series, let's look at how to use it effectively.This article is excerpted from the newly published book Linux Administration Handbook, Second Edition.

One nice feature of NIS is that it can be understood by mere mortals. NIS is analogous to copying files around; in most cases, it's unnecessary for administrators to be aware of NIS's internal data formats. Administration is done with the same old flat files, and only one or two new procedures need to be learned.

Since NIS domains cannot be linked, NIS is not suitable for managing a large network of machines unless a single configuration is to be applied to every machine. You can divide a large network into several NIS domains, but each domain must be administered separately. Even if a large network does use a single configuration, limitations on the scaling of slave servers mean that in practice these sites usually come up with some other mechanism to keep their NIS servers in sync. They often end up rolling their own back-end databases and making their NIS servers fetch their data from this central source.

If a slave server is down or inaccessible when a map is changed, the slave's copy will not be updated. Slaves must periodically poll the master to be sure that they have the most recent version of every map. Although basic tools for polling are provided with NIS, you must implement the polling scheme you want by using cron. Even so, two different versions of a map could possibly be served simultaneously for a while, with clients randomly seeing one or the other.

NIS is minimally secure. Broadcast mode is particularly bad; any host on a network can claim to serve a particular domain and feed bogus administrative data to NIS clients. You can avoid this problem by explicitly enumerating the permissible NIS servers for each client.

You can restrict the hosts that are able to read a server's maps by explicitly listing them in /etc/ypserv.conf; however, this technique is not 100% secure. You can also improve the security of your system by distributing your shadow password file with some other technique (such as rdist or rsync); we don't recommend using NIS to serve shadow passwords.

Older versions of Linux NIS contain known security holes. If you are running an older system, make sure you get the latest upgrades before starting NIS.

Prioritizing sources of administrative information

Configuration information can be distributed in several ways. Every system understands flat files and knows how to use DNS to look up hostnames and Internet addresses. Most also understand NIS. Since a given piece of information could come from several potential sources, Linux provides a way for you to specify the sources that are to be checked and the order in which the checks are made.

In the original (pre-Linux) implementation of NIS, some configuration files (the /etc/passwd and /etc/group files in particular) had to be configured to "invite in" the contents of the corresponding NIS maps. The invitation was extended by inclusion of special incantations in the files themselves. A lone "+" at the beginning of a line would include the entire NIS map, "+@netgroup" would include only entries relevant to a given netgroup, and "+name" would include a single entry.

This approach was never very well liked, and it has been superseded by a central config file, /etc/nsswitch.conf, that allows an explicit search path to be specified for each type of administrative information. The original behavior can be emulated by use of a compatibility mode, but it's unlikely you would want to use this feature on a newly configured network. (Unfortunately, emulation is most distributions' default.)

A typical nsswitch.conf file looks something like this:

passwd:	files nis
hosts:	files dns
group:	files
...

Each line configures one type of information (usually, one flat-file equivalent). The common sources are nis, nisplus, files, dns, and compat; they refer to NIS, NIS+, vanilla flat files (ignoring tokens such as "+"), DNS, and NISified flat files (honoring "+"), respectively. DNS is a valid data source only for host and network information.

Support for each source type comes from a shared library (/lib/libnss*), so distributions vary slightly in the sources they support. Some distributions provide out-of-the-box support for LDAP (see page 520) and/or Hesiod, a directory service based on DNS. Another source commonly supported on Linux (and unfortunately not very well documented) is db, which reads a hashed version of the map from /var/db (for example, /var/db/passwd.db). If your flat files are large, the use of hashed versions can substantially increase lookup speed.

Sources are tried from left to right until one of them produces an answer for the query. In the example above, the gethostbyname routine would first check the /etc/hosts file, and if the host was not listed there, would then check DNS. Queries about Unix groups, on the other hand, would check only the /etc/group file.

If necessary, you can define the "failure" of a source more specifically by putting bracketed expressions after it. For example, the line

hosts:  dns [NOTFOUND=return] nis

causes DNS to be used exclusively if it is available; a negative response from the name server makes queries return immediately (with a failure code) without checking NIS. However, NIS is used if no name server is available. The various types of failures are shown in the table below; each can be set to return or continue, signifying whether the query should be aborted or forwarded to the next source.

Failure modes recognized in /etc/nsswitch.conf

Condition

Meaning

UNAVAIL

The source doesn't exist or is down.

NOTFOUND

The source exists, but couldn't answer the query.

TRYAGAIN

The source exists but is busy.

SUCCESS

The source was able to answer the query.

By default, all Linux distributions ship with nsswitch.conf files that are reasonable for a stand-alone machine without NIS. All entries go to the flat files, with the exception of host lookups, which first consult flat files and then DNS. Most distributions default to compat mode for passwd and group, which is probably worth changing. If you really use NIS, just explicitly put it in the nsswitch.conf file.

Debian and its kissing cousin Ubuntu ship with protocols, services, ethers, and rpc going to db and then files. This is slightly odd, since Debian and Ubuntu don't, in fact, include /var/db or any mechanism to maintain it. Presumably it would be slightly more efficient to go directly to files; you can modify the settings to do that if you want.

Using netgroups

NIS introduced a popular abstraction known as netgroups. Netgroups name sets of users, machines, and nets for easy reference in other system files. They are defined in /etc/netgroup and are also shared as an NIS map.

The format of a netgroup entry is

groupnamelist-of-members

Members are separated by whitespace. A member is either a netgroup name or a triplet of the form

(hostname, username, nisdomainname)

Any empty field in a triplet is a wild card; thus the entry (boulder,,) refers to all users in all domains on the host boulder (or to the host boulder itself, depending on the context in which the netgroup is used). A dash in a field indicates negation, so the entry (boulder,-,) refers to the machine boulder and no users. Netgroup definitions can nest.

Here's a simple example of an /etc/netgroup file:

bobcats	(snake,,) (headrest,,)
servers	(anchor,,) (moet,,) (piper,,) (kirk,,)
anchorclients	(xx,,) (watneys,,) (molson,,)
beers	(anchor,,) (anchor-gateway,,) anchorclients
allhosts	beers bobcats servers

These netgroups are all defined in terms of hosts; that's typical for real-world use.

Netgroups can be used in several system files that define permissions. The most common application these days is for configuring NFS exports. Netgroups can be mentioned in the /etc/exports file to specify groups of hosts that are allowed to mount each filesystem. This feature is very handy when you are exporting to a lot of hosts, particularly on systems that require fully qualified domain names and that limit lines in the exports file to 1,024 characters.

Netgroups are a nice idea. They simplify system files, making them more understandable. They also add a layer of indirection that permits the status of a user or machine to be changed in one file rather than fifteen.

Setting up an NIS domain

You must initialize NIS on the master server, on the slave servers, and on each client. You do this in two steps. First, run ypinit on each server. Second, on every machine in the domain, set the domain name from /etc/domainname or one of the system startup files and configure /etc/nsswitch.conf to import NIS data.

The server side of NIS must usually be installed as a separate, optional package called ypserv. Debian and Ubuntu do things a little differently; their nis package includes both the client and server sides.

ypinit initializes both the master and slave servers for a domain. On the master, you use the following commands:

# cd /var/yp

/* The NIS directory, wherever it is */

# domainnamefoo

/* Name the new domain. */

# /usr/lib/yp/ypinit -m

/* Initialize as master server. */

# ypserv

/* Start the NIS server. */

 

The -m flag tells ypinit that it's configuring a master server; it prompts you to enter a list of slave servers. Once the master is up and running, prime each slave server by running ypinit with the -s (slave) flag:

# cd /var/yp
# /usr/lib/yp/ypinit -smaster  /* Argument is master's hostname. */
# ypserv

ypinit -s makes a local copy of the master's current data; the presence of the domain's data files is enough to let ypserv know that it should serve the domain.

On each slave, you should set up crontab entries to pull fresh copies of all maps from the master. The command ypxfrmap, where map is a name such as passwd.byuid, transfers the specified map from the master server. You must run the command once for each map. Maps tend to change at different rates, so you may want to transfer some maps more often than others. In most circumstances, transferring all the maps once or twice a day (perhaps late at night) is good enough. The following script transfers every map:

#!/bin/sh
mydomain = ´/bin/domainname´
cd /var/yp/$mydomain  # the NIS directory
for map in ´/bin/ls´; do
   /usr/lib/yp/ypxfr $map
done

Additionally, prefabricated scripts in /usr/lib/yp transfer NIS maps at various frequencies (ypxfr_1perday, ypxfr_2perday, and ypxfr_1perhour).

If you want users to be able to change their passwords with yppasswd, you must run the yppasswdd daemon on the master NIS server. The Linux version of this server has been known to crash frequently, so be sure to verify that it is still running if the yppasswd command doesn't seem to be working.

Setting access control options in /etc/ypserv.conf

You can set options for the Linux version of the ypserv daemon in /etc/ypserv.conf; however, only a few options are defined, and most sites will not need to change their default values.

More importantly, ypserv looks to the ypserv.conf file for instructions about how to control access to NIS data. Rather than simply blurting out the answer to every incoming query as the traditional implementation does, the Linux ypserv checks incoming requests against an access list. Each control line is of the form

host:nisdomain:map:security

host, nisdomain, and map identify a particular subset of requests, and the security parameter tells how to handle it: deny to reject the request, port to allow the request as long as it originates at a privileged network port (< 1024), and none to always allow the request. Here is an example configuration:

128.138.24.0/255.255.252.0:atrustnis:*:none
*:*:passwd.byuid:deny
*:*:passwd.byname:deny
128.138.:atrustnis:*:port
*:*:*:deny

You can use a star in the host, nisdomain, and map fields to match any value, but partial matches are not allowed. (You can't, for example, use passwd.* to match all maps derived from the /etc/passwd file.) Control lines are checked in order until a matching line is found. If no lines match, the default is to answer the request.

The host parameter can include a netmask, as on the first line, but ypserv does not understand the more common CIDR notation. As shown on the fourth line, you can also omit trailing components of an IP address to make ypserv fill it in with zeros and supply an analogous netmask.

The rules above allow access from any host on one of the 128.138.24/22 networks. Hosts within 128.138 can access all maps in atrustnis except those derived from the /etc/passwd file, as long as the request originates at a privileged port. All other access is denied.

Never forget that this type of access control is a stopgap measure at best. It may discourage casual browsing by people outside your organization, but it won't provide a very effective deterrent to a determined attacker.

An older security mechanism, the /var/yp/securenets file, is also supported for historical reasons. New configurations should use ypserv.conf.

Configuring NIS clients

After setting up servers, inform each client machine that it is a member of the new domain. The servers of a domain are generally clients as well.

The domainname command sets a machine's NIS domain. It's usually run at boot time from one of the startup scripts. The exact contortions necessary to configure this vary by distribution; details are given below.

Each client must have at least a minimal private version of the passwd, group, and hosts files. passwd and group are needed to allow root to log in when no NIS server is available. They should contain the standard system accounts and groups: root, bin, daemon, etc. The hosts file (or DNS) must be present to answer boot-time queries that occur before NIS is up and running.

NIS details by distribution

Under Fedora and RHEL, you set the NIS domain name in /etc/sysconfig/network by setting the variable NISDOMAIN. The server side of NIS is installed as a separate package called ypserv. The ypbind, ypserv, and yppasswdd daemons are enabled and disabled with chkconfig; for example,

# chkconfig ypbind on

SUSE sets the NIS domain name at boot time from the file /etc/domainname. The server side of NIS is installed as a separate package called ypserv. Use chkconfig to force the system to automatically start ypserv and/or ypbind at boot time. You can set command-line options for ypbind in /etc/sysconfig/ypbind. You must either set YPBIND_BROADCAST to yes in this file or install an /etc/yp.conf file; otherwise, the startup scripts will refuse to start ypbind.

Debian and Ubuntu keep the name of the NIS domain in /etc/defaultdomain. The startup scripts run ypbind automatically if this file is present. To run ypserv, edit the file /etc/default/nis and set the value of NISSERVER to slave or master.

© Copyright Pearson Education. All rights reserved.

Click Here!