Setting Up a Server
This section discusses issues that are commonly
Configuration FilesServices are controlled by property list files (page 453) in /System/Library/LaunchDaemons and traditional UNIX configuration files. Examples of traditional configuration files include Apache's /etc/httpd/httpd.conf and sshd 's /etc/sshd_config . To configure services manually, you need to understand both types of configuration files. Traditional Configuration File ConventionsMost traditional configuration files, typically named *.conf , rely on the following conventions:
Configuration files that do not follow these conventions are noted in the text.
Specifying
|
|
Client name pattern |
Matches |
|---|---|
|
n.n.n.n |
One IP address. |
|
name |
One hostname, either local or remote. |
|
name that starts with . |
Matches a hostname that ends with the specified string. For example, .example.com matches the systems kudos.example.com and speedy.example.com , among others. |
|
IP address that ends with . |
Matches a host address that starts with the specified
|
|
starts with @ |
Specifies a
|
|
n.n.n.n/m.m.m.m or n.n.n.n/mm |
An IP address and subnet mask specify a subnet. |
|
starts with / |
An absolute pathname of a file containing one or more
|
|
Wildcards |
|
|
* and ? |
Matches one (
?
) or more (*)
|
|
ALL |
Always matches. |
|
LOCAL |
Matches any hostname that does not contain a period. |
|
Operator |
|
|
EXCEPT |
Matches anything in the preceding list that is not in the following list. For example, a b c d EXCEPT c matches a, b , and d . Thus you could use 192.168. EXCEPT 192.168.0.1 to match all IP addresses that start with 192.168. except 192.168.0.1. |
Examples
Each of the following examples specifies one or more systems:
|
10.10. |
Matches all systems with IP addresses that start with 10.10. |
|
.apple.com |
Matches all named hosts on the Apple network. |
|
localhost |
Matches the local system. |
|
127.0.0.1 |
The loopback address; always resolves to the local host. |
|
192.168.*.1 |
Could match all routers on a network of /24 subnets. |
When you set up a server, you frequently need to specify the clients that are allowed to connect to that server. Sometimes it is
n.n.n.n/m.m.m.m
or
n.n.n.n/mbits
where
n.n.n.n
is the base IP address and the subnet is represented by
m.m.m.m
(the subnet mask) or
mbits
(the number of bits used for the subnet mask). For example,
192.168.0.1/255.255.255.0
represents the same subnet as
192.168.0.1/24
. In binary, decimal
255.255.255.0
is represented by 24 ones followed by 8 zeros. The
/24
is shorthand for a subnet mask with 24 ones. Each line in Table 11-4
|
Bits |
Mask |
Range |
|---|---|---|
|
10.0.0.0/8 |
10.0.0.0/255.0.0.0 |
10.0.0.0 10.255.255.255 |
|
172.16.0.0/12 |
172.16.0.0/255.240.0.0 |
172.16.0.0 172.31.255.255 |
|
192.168.0.0/16 |
192.168.0.0/255.255.0.0 |
192.168.0.0 192.168.255.255 |
A
property list
is a structured data file, usually with a filename extension of
.
Mac OS X stores a property list in one of three formats: plain text, XML, or binary. The application or utility that
The plutil utility (page 815) checks the syntax of property list files and converts them from one format to another.
The original property list format was a
$
cat /System/Library/StartupItems/Samba/StartupPreferences.plist
{
Description = "SMB File Service";
Provides = ("SMB File Service");
Requires = ("Disks", "DirectoryServices");
OrderPreference = "None";
Messages =
{
start = "Starting SMB File Service";
stop = "Stopping SMB File Service";
};
}
The Description key is associated with a simple string value. The Provides and Requires keys are each associated with an array, although Provides has only one element in its array. The Messages key is associated with a dictionary that contains two name/value pairs.
The plutil utility does not generate plain-text property lists.
Many property list files are stored in XML (page 962) format. This format, which is the most commonly used under OS X, is human readable, can be edited by hand, and allows easy and reliable syntax checking.
XML uses
tags
to identify elements in a file. XML tags start with an opening angle
The
$ plutil -convert xml1 StartupParameters.plist $ cat StartupParameters.plist <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <dict> <key>Description</key> <string>SMB File Service</string> <key>Messages</key> <dict> <key>start</key> <string>Starting SMB File Service</string> <key>stop</key> <string>Stopping SMB File Service</string> </dict> <key>OrderPreference</key> <string>None</string> <key>Provides</key> <array> <string>SMB File Service</string> </array> <key>Requires</key> <array> <string>Disks</string> <string>DirectoryServices</string> </array> </dict> </plist>
The XML format is more verbose, but clearer than the plain-text format. It also supports additional data types, such as integer and Boolean, as shown in the following XML property list fragment:
<key>Display</key> <integer>0</integer> <key>DockSwitch</key> <true/>
Some XML elements do not have opening and closing tags. These elements use a trailing slash to
The binary property list file format is the most space efficient, but is not human readable. If you need to edit a binary property list file, you must convert it to XML, edit the XML, and then convert it back to binary, as in the following example:
$ plutil -convert xml1 -o copy.plist original.plist $ vim copy.plist [...] $ plutil -convert binary1 -o original.plist copy.plist
In addition to NetInfo (page 441), Mac OS X supports a number of other ways to search for information about users and hosts. With the
The /etc/lookupd directory holds files that override defaults. For example, if a users file exists in this directory, it changes the way that lookupd obtains user records. Alternatively, lookupd can get configuration information from NetInfo in the corresponding NetInfo directories /config/lookupd or /locations/lookupd . For more information refer to the lookupd man page.
The superserver is a daemon that launches, on demand, other daemons that provide services. Starting service daemons on demand, as opposed to allowing them to run constantly, conserves system resources. The superserver under OS X version 10.4 and later is launchd and under version 10.3 and earlier is xinetd .
Mac OS X 10.4
The
launchd
daemon, which was introduced in Mac OS X 10.4,
The launchd daemon is responsible for the services that have property lists in the /System/Library/LaunchDaemons and /Library/LaunchDaemons directories. Each program launchd controls is called a job . A job is defined by an XML property list (configuration) file and identified by a unique label, denoted by the Label key, in that file. Once it loads (reads) a configuration file, launchd controls the job defined by that file and launches the associated program as needed. The launchd daemon can launch a program at system startup, periodically, or on demand.
The launchd daemon controls only programs it has started; it does not control programs started in other ways. The following property list configuration file, which is associated with the sshd daemon, shows some of the keys used by launchd :
$
cat /System/Library/LaunchDaemons/ssh.plist
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN"
"http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>com.openssh.sshd</string>
<key>Program</key>
<string>/usr/libexec/sshd-keygen-wrapper</string>
<key>ProgramArguments</key>
<array>
<string>/usr/sbin/sshd</string>
<string>-i</string>
</array>
<key>SessionCreate</key>
<true/>
<key>Sockets</key>
<dict>
<key>Listeners</key>
<dict>
<key>Bonjour</key>
<array>
<string>ssh</string>
<string>sftp-ssh</string>
</array>
<key>SockServiceName</key>
<string>ssh</string>
</dict>
</dict>
<key>StandardErrorPath</key>
<string>/dev/null</string>
<key>inetdCompatibility</key>
<dict>
<key>Wait</key>
<false/>
</dict>
</dict>
</plist>
Only the Label and ProgramArguments keys are required. The Label key identifies the job. You can use the Label key as an argument to launchctl (next) to start, stop, load, or unload a job. Give the command launchctl list to display the Label key of each loaded job.
The ProgramArguments key provides launchd with the pathname of the program to run and the arguments to call it with. The preceding example instructs launchd to execute /usr/sbin/sshd with the i option, which indicates that sshd is being launched by another daemon.
Internet servers are generally run on demand, in response to incoming connections. The Sockets key, if present, indicates that launchd should listen on the specified port and launch the program whenever it detects an incoming connection. In the preceding example, the sshd daemon is run whenever a connection is received on the port associated with the ssh service, as defined in /etc/services . The Bonjour key is used with the Bonjour system for automatic service discovery.
You can use the Mac OS X graphical system administration utilities to start and stop jobs. Typically you do not need to edit the launchd configuration files.
Daemons obtain configuration information from their own configuration files. For example, the sshd daemon uses /etc/sshd_config , a standard UNIX configuration file (page 451).
The jobs specified by the property lists in the /System/Library/LaunchDaemons and /Library/LaunchDaemons directories are loaded when the system boots. The jobs specified by the property lists in /System/Library/LaunchAgents , /Library/LaunchAgents , and ~/Library/LaunchAgents are loaded when a user logs in. These directories are discussed in "Important Standard Directories and Files" on page 444.
The
launchd
daemon runs all the time. You can change the behavior of
launchd
while it is running by using
launchctl
(page 765). The first argument to
launchctl
is called a
subcommand
. For example, the
list
subcommand
#
launchctl list
com.apple.KernelEventAgent
com.apple.mDNSResponder
com.apple.nibindd
com.apple.periodic-daily
com.apple.periodic-monthly
com.apple.periodic-weekly
com.apple.portmap
com.apple.servermgrd
com.apple.syslogd
com.apple.watchdogtimerd
com.vix.cron
com.apple.ntalkd
org.postfix.master
org.xinetd.xinetd
com.openssh.sshd
com.apple.ls
com.apple.atprintd.i9900
com.apple.cups-lpd
com.apple.fingerd
The
load
subcommand of
launchctl
causes
launchd
to read a job's configuration file(s) and start the job as specified (at system startup [immediately if the system is running], periodically, or on demand). However, if the configuration file specifies a value of
<true/>
for the
Disabled
key,
launchd
does not load the job. The
unload
subcommand
The
stop
subcommand of
launchctl
causes
launchd
to stop running a (loaded) job but not to unload it. Thereafter, a periodic or demand-driven job may start up again from a
When you modify the configuration file of a loaded job, you must instruct launchd to read the new values from the file. Because a load subcommand has no effect on a loaded job, you must first unload the job and then load it again when you change a configuration file.
The
launchd
daemon
Because
launchd
provides resource management and security features in a standardized way, programs run by
launchd
should not handle their own resource management or security. For instance, a daemon being started by
launchd
should specify the user and
In some cases, such as when a daemon needs to bind to a privileged port (page 414), a daemon may need to initially run with root privileges and subsequently drop these privileges. Such a daemon would be launched once, using the RunAtLoad key, rather than run on demand.
There is always at least one launchd daemon running on a Mac OS X system, and there may be more. Non root users can start their own copies of launchd to run jobs and services they submit. If you use launchctl to start a new service and you do not have root privileges, the job will be attached to a new instance of launchd running with your privileges.
The
xinetd
daemon, which is used under OS X 10.3 and earlier, is a more secure replacement for the
inetd
superserver that originally shipped with 4.3BSD. The Internet superserver listens for network connections. When one is made, it launches a specified server daemon and forwards the data from the socket (page 101) to the daemon's standard input. The
xinetd
superserver
The version of xinetd distributed with Mac OS X is built with TCP wrappers support, so it uses the /etc/hosts.allow and /etc/hosts.deny files for access control (see the hosts_access man page for more information). Using TCP wrappers can simplify configuration but hides some of the more advanced features of xinetd .
The base configuration for xinetd is stored in the /etc/xinetd.conf file. Additional services are configured through files in /etc/xinetd.d .
The following xinetd configuration file allows telnet connections from the local system and any system with an IP address that starts with 192.168. This configuration file does not rely on TCP wrappers, so it does not depend on the hosts.allow and hosts.deny files.
$
cat /etc/xinetd.d/telnet
service telnet
{
socket_type = stream
wait = no
user = root
server = /usr/sbin/in.telnetd
only_from = 192.168.0.0/16 127.0.0.1
disable = no
}
The socket_type indicates whether the socket uses TCP or UDP. TCP-based protocols establish a connection between the client and the server and are identified by the type stream . UDP-based protocols rely on the transmission of individual datagrams and are identified by the type dgram .
When wait is set to no, xinetd handles multiple, concurrent connections to this service. Setting wait to yes causes xinetd to wait for the server process to complete before handling the next request for that service. In general, UDP services should set wait to yes and TCP services should set wait to no . If you were to set wait to yes for a service such as telnet , only one person would be able to use the service at a time.
The user specifies the user that the server runs as. If the user is a member of multiple groups, you can also specify the group on a separate line using the keyword group . The user directive is ignored if xinetd is not run as root . The server provides the pathname of the server program that xinetd runs for this service.
The only_from specifies which systems xinetd allows to use the service. Use IP addresses only because using hostnames can render the service unavailable if DNS fails. Zeros at the right of an IP address are treated as wildcards; thus 192.168.0.0 allows access from any system in the 192.168 subnet.
The disable line can disable a service without removing the configuration file. For more information see the xinetd man page.
When you
Open the local system only to systems you want to allow to access it.
Allow each remote system to access only the data you want it to access.
Allow each remote system to access data only in the manner you want it to (read only, read/write, write only).
You can restrict which remote systems have access to a given service by using the operating system's builtin firewall. Under Mac OS X you can configure the firewall using System Preferences; under Mac OS X Server you need to use Server Admin.
You can also restrict a local server's access to the local system. A server can be run with resource limits to keep it from consuming too much memory or creating files that
The launchd daemon provides control over all of these restrictions.
Resource limits can control the amount of memory and CPU time as well as the disk space used by a process. You can set both hard and soft resource limits in a launchd configuration file. Soft limits are enforced, but a program can request that the limits be raised. Soft resource limits cannot be raised above the hard resource limits, however, and hard resource limits cannot be raised at all. For example, the following resource limits from a property list file prevent a daemon from consuming more than five seconds of CPU time. (On a multitasking system, it will likely take more than five seconds of real time before a single process has used five seconds of CPU time.)
<key>HardResourceLimits</key>
<dict>
<key>CPU</key>
<integer>5</integer>
<key>Data</key>
<integer>33554432</integer>
<key>ResidentSetSize</key>
<integer>33554432</integer>
<key>NumberOfFiles</key>
<integer>16</integer>
<key>Stack</key>
<integer>33554432</integer>
<key>NumberOfProcesses</key>
<integer>96</integer>
<key>FileSize</key>
<integer>33554432</integer>
</dict>
If you specify any HardResourceLimits , any limits that you do not specify are implicitly set to 0, which will normally prevent a job from running. The NumberOfProcesses limit is not merely the number of processes that are part of a job, but includes all processes owned by the user. An idle graphical console might have 50 processes running. To limit a job's resources without impeding a user's normal tasks, it is best to create a new account with limited privileges that runs the job and does nothing else.
The
NumberOfProcesses
limit used in the preceding example is high. The default limit under Mac OS X is 100 processes per user, with a
On early UNIX systems, the root directory was a fixed point in the filesystem. On modern UNIX variants, including Mac OS X, you can define the root directory on a
The root directory is the top of the directory hierarchy and has no parents: A process cannot access files above the root directory (because they do not exist). If, for example, you run a program (process) and specify its root directory as /Users/sam/jail , the program would have no concept of any files in /Users/sam or above: jail is the program's root directory and is labeled / (not jail ).
By creating an artificial root directory, frequently called a (chroot) jail, you prevent a program from being able to access and modifypossibly maliciouslyfiles outside the directory hierarchy starting at its root. You must set up a chroot jail properly to increase security: If you do not set up a chroot jail correctly, you can actually make it easier for a malicious user to gain access to a system than if there were no chroot jail.
Creating a chroot jail is simple: Working as root , give the command /usr/sbin/chroot directory . The directory becomes the root directory and the process attempts to run the default shell. Working as root from the /Users/sam directory, the following example attempts to set up a chroot jail in the (existing) /Users/sam/jail directory:
#
/usr/sbin/chroot jail
chroot: /bin/sh: No such file or directory
In this example,
chroot
sets up the
chroot
jail, but when it attempts to run the
sh
shell, it fails. Once the jail is set up, the directory that was named
jail
takes on the name of the root directory:
/
and
chroot
cannot find the file identified by the pathname
/bin/sh
. The
chroot
jail is working
Getting a chroot jail to work the way you want is more complicated. To have the preceding example run bash in a chroot jail, you need to create a bin directory in jail ( /Users/sam/jail/bin ) and copy /bin/sh to this directory. Because the bash binary (and the copy of bash named sh ) is dynamically linked to shared libraries (page 486), you need to copy these libraries into jail as well. The libraries go in /lib . The following example creates the necessary directories, copies bash , uses otool to display the shared library dependencies of bash , and copies the necessary libraries, and the dyld dynamic linker to load them, into lib :
$ pwd /Users/sam/jail $ mkdir -p bin usr/lib $ cp /bin/sh bin $ otool -L bin/bash bin/sh: /usr/lib/libncurses.5.4.dylib (compatibility version 5.4.0, current version 5.4.0) /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 88.0.0) $ cp /usr/lib/libncurses.5.4.dylib usr/lib $ cp /usr/lib/libSystem.B.dylib usr/lib $ cp /usr/lib/dyld usr/lib
Now that everything is set up, you can try starting the chroot jail again. All of the setup can be done by an ordinary user but you have to run chroot as Superuser:
$ su Password: # /usr/sbin/chroot . dyld: Library not loaded: /usr/lib/system/libmathCommon.A.dylib Referenced from: /usr/lib/libSystem.B.dylib Reason: image not found Trace/BPT trap #
This attempt is closer, but it turns out that the
libSystem
dynamic library has additional dependencies. Creating the
usr/lib/system
subdirectory and copying
libmathCommon
into it
# mkdir usr/lib/system # cp /usr/lib/system/libmathCommon.A.dylib usr/lib/system # chroot . sh-2.05b# pwd / sh-2.05b# ls sh: ls: command not found
This time chroot finds and starts sh , which displays its default prompt ( sh-2.05b# ). The pwd command works because it is a shell builtin (page 138). However, bash cannot find the ls utility (it is not in the chroot jail). You can copy /bin/ls into the jail if you want users in the jail to be able to use ls .
To set up a useful chroot jail, you need to determine which utilities the users of the chroot jail will need. Then you can copy the necessary binaries and their libraries into the jail.
For jobs using launchd 's InetdCompatibility mode, you need the program /usr/libexec/launchproxy in the jail. This program provides an environment similar to that provided by inetd or xinetd .
Because users are looked up dynamically from a database, you do not need any password files or authentication programs in the jail unless the program you are using accesses these files or programs directly.
Tip: Keeping multiple chroot jails
If you plan to deploy multiple chroot jails, it is a good idea to keep a clean copy of the files in bin , usr/lib , and usr/lib/system somewhere other than in one of the active jails.
Running a shell inside a jail has limited use. You are more likely to need to run a specific service inside the jail. To do so, you need make sure all the files needed by that service are inside the jail. Once you have set up a functional jail, you can specify the jail as the RootDirectory of the service in the launchd configuration file.
Several servers are set up to take advantage of
chroot
jails. For example, the FTP server (
Some services need to be run as root , but they relinquish their root privileges once started (Procmail and tnftpd are examples). If you are running such a service, you do not need to specify a user for it in the launchd configuration file.
It is possible for a process run as root to escape from a chroot jail. For this reason, you should always run a service as another user before starting a program running inside the jail. Also, be careful about which setuid (page 90) binaries you allow inside a jail: A security hole in one of these can compromise the security of the jail. Also, make sure the user cannot access executable files that she uploads.
Some services can run with restricted privileges, rather than with full
root
privileges. Services should never be run with
root
privileges unless it is
Instead of having network configuration information stored in local files on each system, DHCP (Dynamic Host Configuration Protocol) enables client systems to retrieve network configuration information each time they connect to the network. A DHCP server
This technique has several advantages over storing network configuration information in local files:
DHCP enables a new user to set up an Internet connection without having to work with IP addresses,
DHCP facilitates assignment and management of IP addresses and
DHCP enables IP addresses to be used by more than one system, reducing the total number of IP addresses needed. This conservation of addresses is important given that the Internet is quickly running out of IPv4 addresses. Although one IP address can be used by only one system at a time, many end-user systems require addresses only occasionally, when they connect to the Internet. By reusing IP addresses, DHCP lengthens the life of the IPv4 protocol. DHCP applies to IPv4 only, as IPv6 forces systems to configure their IP addresses automatically (called autoconfiguration) when they connect to a network (page 400).
DHCP is particularly useful for administrators who are responsible for a large number of systems because it
You can obtain more information from the DHCP Web site (www.dhcp.org) and from the DHCP FAQ (www.dhcp-handbook.com/dhcp_faq.html).
The client system contacts the server daemon (
bootpd
on a Macintosh) to obtain the IP address,
DHCP is broadcast based, so the client and server must be on the same subnet (page 397).
A DHCP client requests network configuration parameters from the DHCP server and uses those parameters to configure the client's network interface. Under Mac OS X, DHCP setup is controlled by a setting in the Network preference pane (Figure 11-1). To enable DHCP, select the interface that you want to use DHCP for from the Network preference pane and click the TCP/IP tab. Using DHCP is the default setting.
If the local network requires a DHCP client ID (a name used to identify your computer to the server), enter it in the appropriate box. Most networks do not require a client ID.
If you run into configuration problems, try clicking Renew DHCP Lease . Clicking this button restarts the DHCP negotiation.
If no DHCP server is available, the client assigns itself an address in the 169.254.0.0169.254.255.255 block. The system does not assign itself an address when no network cable is plugged in.
The DHCP server maintains a list of IP addresses and other configuration parameters. When