Sunday, December 17, 2006

Using GUI Tools

Many Linux distributions provide GUI interfaces that permit configuration of basic networking features, common servers, and often other aspects of system operation. These tools vary substantially from one distribution to another, although they do share certain commonalities. They can usually be launched from a menu option in the distribution's default K Desktop Environment (KDE) or GNU Network Object Model Environment (GNOME) desktops, or they can be launched by typing their names in xterms. (You may need to be root to launch these tools, particularly in the latter way.) These tools include Linuxconf (used by Red Hat and many of its derivatives, including Mandrake), YaST and YaST2 (used by SuSE), and ksysv (a GUI variant on ntsysv, discussed earlier).

Friday, December 15, 2006

Using Local Startup Scripts

Most Linux distributions start the majority of their standard servers through either SysV startup scripts or a super server. One notable exception to this rule is the X server, which is often started through a line near the end of /etc/inittab, which launches the X server only in a particular runlevel. Slackware also does things a bit differently, using /etc/rc.d/rc.inet2 to start most of its servers. Most distributions provide a "local" startup script, which is intended to be modified by the system administrator to handle starting unusual system-specific servers, running initialization utilities, and so on. Table 4.1 lists the local startup scripts for several common Linux distributions.

The usual reason to use a local startup script is that you're adding a server that you don't want to run via a super server and that doesn't come with an appropriate SysV startup script. Because SysV startup scripts are closely tied to specific distributions, you might not have an appropriate SysV startup script if you obtained a server from a source other than your own distribution. For instance, if you're running Mandrake but install a server intended for SuSE, the SuSE SysV startup script may not work on your Mandrake system. You may also run into this problem if you obtain the server in source code form from the server's author; an original source such as this is unlikely to include customizations for specific Linux distributions. The code may compile and run just fine, but you'll need to start the server yourself.

Of course, it's possible to write your own SysV startup scripts for such servers. You can do this by modifying a working SysV startup script. You might try modifying the startup script for an equivalent tool (such as an earlier version of the server you're installing, if you've resorted to a third-party source because your distribution's official tool is out of date), or some randomly selected startup script. This process can be tricky, though, particularly if you're not familiar with your distribution's startup script format or with shell scripting in general. (SysV startup scripts are written in the bash shell scripting language.) If you run into problems, or if you're in a hurry and don't want to put forth the effort to create or modify a SysV startup script, you can start it in the local startup script.

You can modify the local startup script using your favorite text editor. To start a server, simply include lines in the file that are the same as the commands you'd type at a command prompt to launch the program. For instance, the following line starts a Telnet server:

/usr/sbin/in.telnetd

If the server doesn't start up in daemon mode by default (that is, if it doesn't run in the background, relinquishing control of your shell if you launch it directly), you should use an ampersand (&) at the end of the command line to tell the server to run in the background. Failure to do this will cause the execution of the startup script to halt at the call to the server. This may be acceptable if it's the last line in the script, but if you want to start additional servers, the subsequent servers won't start if you omit the ampersand.

You may, of course, do something more complex than launching a server using a single line. You could use the bash shell's conditional expressions to test that the server file exists, or launch it only under certain circumstances. These are the sorts of tasks that are usually performed in SysV startup scripts, though, so if you want to go to that sort of effort, you might prefer writing your own SysV startup script.

One important point to keep in mind is that different distributions' local startup scripts aren't exactly equivalent to one another. For instance, SuSE runs its boot.local script earlier in the boot process than Red Hat runs its rc.local. Therefore, SuSE's local startup script is more appropriate for bringing up interfaces or doing other early startup tasks, whereas Red Hat's script is better for launching servers that rely on an already-up network connection. If the tasks you want to perform in the startup script are very dependent upon the presence or absence of other servers, you may be forced to create a SysV startup script with a sequence number that's appropriate for the tasks you want to perform.

The usual reason for using a local startup script is to create a quick-and-dirty method of launching a server or running some other program. Once launched, the local startup script provides no easy way to shut down the server (as does the stop parameter to most SysV startup scripts); you'll have to use kill, killall, or a similar tool to stop the server, if you need to do so.

Thursday, December 14, 2006

Setting Access Control Features

Part of the appeal of xinetd is that it combines access control features that closely resemble those of TCP Wrappers in the super server itself. This can simplify configuration. The TCP Wrappers and xinetd access control features aren't exactly identical, though, so there are situations in which one tool or the other is superior. Like other xinetd configuration options, you can set access control features either globally or for specific servers. Major access control options include the following:
  • Host-based restrictions— The only_from and no_access options are conceptually very similar to the contents of the /etc/hosts.allow and /etc/hosts.deny files for TCP Wrappers, but xinetd sets these features in its main configuration file or server-specific configuration file. Specifically, only_from sets a list of computers that are explicitly allowed access (with all others denied access), whereas no_access specifies computers that are to be blacklisted. If both are set for an address, the one with a more specific rule takes precedence. For both options, addresses may be specified by IP address (for instance, 172.23.45.67), by network address using a trailing .0 (for instance, 172.23.0.0 for 172.23.0.0/16) or with an explicit netmask (as in 127.23.0.0/16), a network name listed in /etc/networks, or a hostname (such as badguy.threeroomco.com). If a hostname is used, xinetd does a single lookup on that hostname at the time the server starts, so if the hostname-to-IP address mapping changes, a hostname may not be very effective.
  • Temporal restrictions— You can specify a range of times during which the server is available by using the access_times option. This option requires an access time specified as hour:minute-hour:minute, such as 08:00-18:00, which restricts access to the server to the hours of 8:00 AM to 6:00 PM. Times are specified in a 24-hour format. Note that this restricts only the initial access to the server. For instance, if the Telnet server is restricted to 8:00 AM to 6:00 PM, somebody could log in at 5:58 PM and stay on indefinitely.
  • Interface restrictions— You can bind a server to just one network interface using the bind or interface options (they're synonyms), which take the IP address associated with an interface. For instance, if eth1 is linked to 172.19.28.37, bind = 172.19.28.37 links a server only to eth1. Any attempt to access the server from eth0 is met with silence, as if the server weren't running at all. This feature is most useful on routers and other computers linked to more than one network, but it's also of interest to those with small internal networks and dial-up links. For instance, you can bind servers like Telnet or FTP to your local Ethernet interface, and they won't be available to the Internet at large via your PPP connection.
Although this and the preceding section outline the most useful xinetd options, there are some less often used options that aren't described here. You should consult the xinetd man page for further information on additional options

Wednesday, December 13, 2006

The /etc/xinetd.conf File Format

As a new super server with expanded capabilities, xinetd requires a new file format. The /etc/xinetd.conf file controls xinetd, but both Red Hat and Mandrake provide only a minimal xinetd.conf file. This file includes default settings for all servers and a line that causes xinetd to read all the files in /etc/xinetd.d and treat them as supplementary configuration files. Thus, xinetd configuration is something like SysV configuration, in that each server has its own control file named after the server, such as /etc/xinetd.d/telnet to control the Telnet server. You can configure xinetd using just its main xinetd.conf file if you prefer, but server packages for Red Hat and Mandrake often drop their startup files in /etc/xinetd.d.

Whether it's located in /etc/xinetd.conf or a file in /etc/xinetd.d, a xinetd server definition spans several lines; however, a basic definition includes the same information as an inetd.conf entry. For instance, the following xinetd definition is mostly equivalent to the inetd.conf entry presented earlier for a Telnet server:

service telnet
{
socket_type = stream
protocol = tcp
wait = no
user = root
server = /usr/sbin/in.telnetd
}

This entry provides the same information as an inetd.conf entry. The xinetd configuration file format, however, explicitly labels each entry and splits them across multiple lines. Although this example presents data in the same order as does the inetd configuration, this order isn't required. Also, the xinetd definition doesn't call TCP Wrappers, although it could (you'd list /usr/sbin/tcpd on the server line, then add a server_args line that would list /usr/sbin/in.telnetd to pass the name of the Telnet server to TCP Wrappers).

In addition to the standard inetd features, xinetd provides many configuration options to expand its capabilities. Most of these are items that appear on their own lines between the curly braces in the service definition. The most important of these options include the following:
  • Security features— As noted earlier, xinetd provides numerous security options, many of which are roughly equivalent to those provided by TCP Wrappers. These are discussed in greater depth in the upcoming section "Setting Access Control Features."
  • Disabling a server— You can disable an inetd server by commenting out its configuration line. You can accomplish the same goal by adding the disable = yes line to a xinetd server definition. The same effect can be achieved in the main /etc/xinetd.conf file by using the disabled = server_list option in the defaults section, where server_list is a space-delimited list of server names. Various configuration tools use one of these methods to disable servers, and in fact a disable = no line may be present for servers that are active.
  • Redirection— If you want to pass a request to another computer, you can use the redirect = target option, where target is the hostname or IP address of the computer that should receive the request. For instance, if you include the redirect = 192.168.3.78 line in the /etc/xinetd.d/telnet file of dummy.threeroomco.com, attempts to access the Telnet server on dummy.threeroomco.com will be redirected to the internal computer on 192.168.3.78. You might want to use this feature on a NAT router to allow an internal computer to function as a server for the outside world. The iptables utility can accomplish the same goal at a somewhat lower level, but doing it in xinetd allows you to apply xinetd's access control features.
  • Logging— You can fine-tune xinetd's logging of access attempts using the log_on_success and log_on_failure options, which determine what information xinetd logs on successful and unsuccessful attempts to access a server. These options take values such as PID (the server's process ID, or PID), HOST (the client's address), USERID (the user ID on the client system associated with the access attempt), EXIT (the time and exit status of the access termination), and DURATION (how long the session lasted). When setting these values, you can use a += or -= symbol, rather than =, to add or subtract the features you want to log from the default.
  • Connection load limits— You can limit the number of connections that xinetd will handle in several ways. One is the per_source option, which specifies how many connections xinetd will accept from any given source at any one time. (UNLIMITED sets xinetd to accept an unlimited number of connections.) The instances option specifies the maximum number of processes xinetd will spawn (this value may be larger than the per_source value). The cps option takes two space- separated values: the number of connections xinetd accepts per second and the number of seconds to pause after this limit is reached before enabling access again. You can adjust the scheduling priority of the servers that xinetd runs using the nice option, which sets a value in much the same way as the nice program. Finally, max_load takes a floating-point value that represents the system load average above which xinetd refuses further connections. Taken together, these options can reduce the chance that your system will experience difficulties because of certain types of denial of service (DoS) attacks or because of a spike in the popularity of your servers.
You can use most of these options directly in the server definition or in the defaults section in the main /etc/xinetd.conf file. If placed in the latter location, the feature applies to all servers handled through xinetd, unless overridden by a competing option in the server definition area.

If you make changes to the /etc/xinetd.conf file or its included files in /etc/xinetd.d, you must restart the xinetd server program. Because xinetd itself is usually started through a SysV startup script, you can do this by typing a command such as /etc/rc.d/init.d/xinetd restart, although the startup script may be located somewhere else on some distributions. Alter natively, you can pass xinetd the SIGUSR1 or SIGUSR2 signals via kill. The former tells xinetd to reload its configuration file and begin responding as indicated in the new file. The latter does the same, but also terminates any servers that have been inactivated by changes to the configuration file.

Tuesday, December 12, 2006

Using xinetd

Traditionally, inetd has been the super server used on Linux systems. Since 2000, however, a shift has begun toward the use of an alternative, xinetd (pronounced "zi-net-dee"). As a first approximation, you can think of xinetd as being a combination of inetd and TCP Wrappers. This is only a rough analogy, though; there are things that xinetd can do that inetd with TCP Wrappers can't do, and things that inetd with TCP Wrappers can do that xinetd alone can't do. In the end, though, xinetd is more flexible because it can be combined with TCP Wrappers, if required, to extend its flexibility. In early 2002, Red Hat and Mandrake are the two major distributions that use xinetd by default, but you can add xinetd to other distributions if you like.

Monday, December 11, 2006

Using TCP Wrappers

As mentioned earlier, TCP Wrappers functions as an intermediary between inetd and the ultimate target server. The reason for doing this is security: TCP Wrappers can apply rules to determine whether or not a given connection should be allowed, thus protecting the server from unwanted accesses. For instance, suppose you want to allow only people on your own local network to access your computer's Telnet server. If you were running the Telnet server directly, it would have to be programmed to reject unwanted accesses, but not all servers include such code. Placing the responsibility for limiting access in TCP Wrappers extends the flexibility of the system without requiring extensive rewriting of all your server programs.

TCP Wrappers is controlled through two files: /etc/hosts.allow and /etc/hosts.deny. These files have identical formats, but they have opposite actions—hosts.allow specifies computers that are to be allowed access to the computer, with all others denied access; hosts.deny specifies computers that are to be denied access, with all others allowed access. When a server is listed in both files, hosts.allow takes precedence. This allows you to set a restrictive policy in hosts.deny but override it to grant access to specific computers. For instance, you could disallow access to all computers in hosts.deny, then loosen that restriction in hosts.allow. If a server isn't specified in either file (either explicitly or through a wildcard, as discussed shortly), TCP Wrappers grants access to that server to all systems.

As with many other configuration files, a pound sign (#) at the start of a line indicates a comment. Other lines take the following form:

daemon-list : client-list

The daemon-list is a list of one or more servers to which the rule applies. If the list contains more than one server, commas or spaces may separate the server names. The names are those listed in /etc/services. The ALL wildcard is also accepted; if the daemon-list is ALL, then the rule applies to all servers controlled by TCP Wrappers.

The client-list is a list of computers that are to be allowed or denied. As with the daemon-list, the client-list can consist of just one entry or a list separated by commas or spaces. You can specify computers in any of several ways:
  • IP addresses— You can list complete IP addresses, such as 10.102.201.23. Such an entry will match that IP address and that IP address only.
  • IP address range— There are several ways to specify ranges of IP addresses. The simplest is to provide fewer than four complete bytes followed by a period. For instance, 10.102.201. matches the 10.102.201.0/24 network. You can also use an IP address/netmask pair, such as 10.102.201.0/24. IPv6 addresses are also supported, by a specification of the form [n:n:n:n:n:n:n:n]/len, where the n values are the IPv6 address and len is the length in bits of the range to be matched.
  • Hostname— You can provide a complete hostname for the computer, such as badcracker.threeroomco.com. This will match that computer only. Because this method relies upon a hostname lookup, though, it's subject to problems if your DNS servers go down or if the person who controls the domain modifies its entries.
  • Domain— You can match an entire domain or subdomain much as you can match a single hostname. The difference is that you must precede the domain name with a period, as in .threeroomco.com—this example matches all the computers in the threeroomco.com domain.
  • NIS netgroup name— If a string is preceded by an at symbol (@), the string is treated as a Network Information Services (NIS) netgroup name. This method relies upon your network having a functioning NIS configuration.

In addition, the client-list specification supports more wildcards than does the daemon-list specification. Specific wildcards you may use include the following:

  • ALL— This wildcard matches all computers.
  • LOCAL— This wildcard is intended to match all local computers, based on hostname. If the computer's hostname lacks a period, it's considered local.
  • UNKNOWN— This wildcard matches computers whose hostnames aren't known by your name resolution system.
  • KNOWN— This wildcard matches computers whose hostname and IP addresses are both known to the system.
  • PARANOID— This wildcard matches computers whose names and IP addresses don't match.

These last three options should be used with care, since they usually depend upon proper functioning of DNS, and DNS can be unreliable because of transient network problems. For instance, if a client's own DNS system is down or inaccessible, you might be unable to verify its hostname. As an example of a short but complete /etc/hosts.allow file, consider the following:

telnet,ftp : 192.168.34. dino.pangaea.edu

ssh : LOCAL .pangaea.edu

The first line specifies identical restrictions for the Telnet and FTP servers, allowing access only to the 192.168.34.0/24 network and the host called dino.pangaea.edu. The second line applies to SSH and restricts access to local computers and all those in the pangaea.edu domain. Because no other servers are listed in the daemon-list fields, TCP Wrappers doesn't block access to any other server. For instance, if you were to run Apache through inetd and TCP Wrappers, everybody would be granted access to Apache with this configuration.

In addition to matching entire computers, you can use the user@computer form to match individual users of the remote system. This form, however, requires that the client computer run an ident (aka auth) server, which returns the name of the user who is using a given network port. Your own server can query the client's ident server about the connection attempt, thus getting the username associated with that attempt. This may cause additional delays, however, and the information often isn't particularly trustworthy, especially from random hosts on the Internet. (You're more likely to want to use this feature to control access from specific users of systems that you control.)

The EXCEPT operator is another special keyword; it specifies exceptions to the rules just laid out. For instance, consider the following /etc/hosts.deny entry:

www : badcracker.org EXCEPT goodguy@exception.badcracker.org

This example denies access to the Web server to all the computers in the badcracker.org domain, unless the connection is coming from goodguy@exception.badcracker.org. (Because /etc/hosts.allow takes precedence over /etc/hosts.deny, entries in the former can also override those in the latter.)

If your goal is to run a very secure system, you may want to begin with the following /etc/hosts.deny file:

ALL : ALL

This blocks access to all computers for all servers handled by TCP Wrappers. You must then explicitly open access to other servers in /etc/hosts.allow. You should open access as little as possible. For instance, you might only give access to computers in a specific network block or domain for sensitive servers like Telnet. (Telnet passes all data in an unencrypted form, so it's a poor choice for logins over the Internet as a whole. See Chapter 13, Maintaining Remote Login Servers, for a discussion of this issue.)

Sunday, December 10, 2006

The /etc/inetd.conf File Format

You can configure inetd through the /etc/inetd.conf file. Aside from comments (lines that begin with a pound sign, #, that inetd ignores), inetd.conf consists of a series of lines, each of which defines a single server. A sample line resembles the following:

telnet stream tcp nowait root /usr/sbin/tcpd in.telnetd

Each line consists of a series of fields, which are separated by spaces or tabs. The meaning of each field is as follows:
  • Server name— The first field is the name of the server protocol, as recorded in /etc/services. In the case of the preceding example, the server protocol name is telnet, and if you check /etc/services, you'll see that this name is associated with 23/tcp—in other words, TCP port 23. There must be an entry in /etc/services in order for inetd to handle a server. For this reason, you may need to edit /etc/services if you want inetd to handle some unusual server. In most cases, though, /etc/services has the appropriate entries already.
  • Socket type— The second field relates the network socket type used by the protocol. Possible values are stream, dgram, raw, rdm, and seqpacket.
  • Protocol type— The third field is the name of the protocol type, which in this context means a low-level network stack protocol such as TCP or UDP. Possible protocol values appear in /etc/protocols, but the most common values are tcp and udp.
  • Wait/Nowait— The fourth field takes just one of two values, wait or nowait, and is meaningful only for datagram (dgram) socket types (other socket types conventionally use a nowait value). Most datagram servers connect to a socket and free up inetd to handle subsequent connection attempts. These servers are called multi-threaded, and they require a nowait entry. Servers that connect to a socket, process all input, and then time out are said to be single-threaded, and they require wait entries. You may optionally add a number to these values, separated by a period, as in wait.60. This specifies the maximum number of servers of the given type that inetd may launch in one minute. The default value is 40.
  • Username— You can tell inetd to launch a server with a specific user's privileges. This can be an important security feature, because restricting privileges for servers that don't require extensive access to the system can prevent a bug from causing a security breach. For instance, the Apache Web server usually doesn't need unusual privileges, so you could launch it as nobody or as some special account intended only for Apache. The preceding example shows the username as root because root privileges are needed to launch the login processes required by a Telnet server. If you add a period and a group name, the specified group name is used for the server's group privileges. For instance, nobody.nogroup launches a server with the username nobody and the group nogroup.
  • Server program— The sixth field specifies the name of the server program that inetd launches when it detects an incoming connection. The preceding example gives /usr/sbin/tcpd as this program name. In reality, tcpd is not a server; it's the program file for the TCP Wrappers program, which is described shortly. Most Linux distributions that use inetd also use TCP Wrappers, and so launch most inetd-mediated servers through tcpd. You can bypass TCP Wrappers for any server you like, although it's generally best to use TCP Wrappers for reasons that are described shortly.
  • Server program arguments— The final field is optional. When present, it contains any arguments that are to be passed to the server program. These arguments might modify the server's behavior, tell it where its configuration files are, and so on. In the case of servers launched through TCP Wrappers, the argument is the name of the ultimate target server, such as in.telnetd in the preceding example. (You may add the ultimate server's arguments to this list, if it needs any.)

You can edit /etc/inetd.conf using any text editor you like. Be sure that any new entries you create, or existing ones you modify, span a single line. (Long filenames, server arguments, and the like sometimes produce lines long enough that some editors will try to wrap the line onto two lines, which will cause problems.) If you need to add an entry for a server you've installed, consult the server's documentation to learn what its inetd.conf entry should look like. In some cases, you can model an entry after an existing one, but without knowing what values to enter for the server name, socket type, and so on, such an entry might not work.

Most distributions that use inetd ship with an /etc/inetd.conf file that contains entries for many different servers. Many of these entries are commented out, so they're inactive. You can activate a server by uncommenting such a line, if the matching server is installed. Some inetd.conf files include multiple entries for any given service; for instance, a file might have two or three different entries for different FTP servers. If yours is like this, be sure you uncomment only the line corresponding to the specific server you've installed, such as ProFTPd or WU-FTPD.

Thursday, December 7, 2006

Using inetd

Normally, a server runs and ties itself to a specific port (a resource identified by protocol type and a number between 1 and 65,535). Incoming requests are directed to specific ports associated with particular server types. For instance, Simple Mail Transfer Protocol (SMTP) mail servers conventionally use TCP port 25, and Hypertext Transfer Protocol (HTTP) servers (Web servers) normally use TCP port 80.

The inetd program is one of two common super servers for Linux. These are servers that function as intermediaries; instead of running the target server itself, the computer runs the super server, which links itself to the ports used by all of the servers it needs to handle. Then, when a connection is made to one of those ports, the super server launches the target server and lets it handle the data transfer. This has two advantages over running a server directly. First, the memory load is reduced; a super server consumes little RAM compared to the servers it handles, particularly if it handles many servers. Second, the super server can filter incoming requests based on various criteria, which can improve your system's security. The drawback is that it takes time for the super server to launch the target server, so the time to connect to a server may be increased, although usually only by a second or two. As a general rule, it's good to use super servers for small or seldom-used servers, whereas big and frequently used servers should be run directly.

Wednesday, December 6, 2006

Setting and Changing the Runlevel

The preceding discussion has referred to the runlevel, but with only a minimal description of what it is. The runlevel and SysV startup scripts are tied together quite intimately. When the computer boots, it enters a specific runlevel. Ultimately, what this means is that the computer executes the startup scripts to which the links in the SysV script link directories point. More specifically, Linux passes the start parameter to the scripts whose links start with S, and passes the stop parameter to those whose links begin with K.

How does Linux know what runlevel to enter when it boots, though? That's set in the /etc/inittab file, which is the configuration file for init, which is the first process that Linux runs and the progenitor of all other processes. Specifically, /etc/inittab contains a line such as the following:

id:5:initdefault:

The leading id is the key to identifying this line, but the following number (5 in this example) is what you'll use to permanently set the runlevel. If you change this value and reboot, the computer will come up in a different runlevel. Runlevels 0, 1, and 6 have special meanings—they correspond to a system shutdown, a single-user mode, and a system reboot, respectively. Runlevels 2 through 5 are normal runlevels, but their precise meanings vary from one distribution to another. For Caldera, Red Hat, Mandrake, SuSE 7.3, and TurboLinux, runlevel 3 is a normal text-mode startup (X is not started), and runlevel 5 is a GUI login mode (X is started, and a GUI login program is run). Earlier versions of SuSE use runlevels 2 and 3 instead of 3 and 5, and Slackware uses 3 and 4 for text-mode and GUI logins. By default, Debian doesn't run any SysV scripts differently in different normal operational runlevels, although it runs fewer text-mode login tools in runlevels above 3 (this detail is handled by subsequent lines of /etc/inittab). Most distributions include a series of comments in their /etc/inittab files describing the function of each runlevel, so look for that if you need more information or are using a distribution I don't discuss in this book.

If you want to change the runlevel temporarily, you can do so with the telinit command (init also works on most systems). The syntax for this command is as follows:

telinit [-t seconds] [runlevel]

When you change runlevels, it's possible that certain processes will have to be killed. Linux can do this through either a SIGTERM or a SIGKILL signal. The former is a more polite way of doing the job; it lets the program close its own files and so on. SIGKILL, by contrast, unceremoniously kills the program, which can lead to file corruption. When you change runlevels, telinit first tries to use a SIGTERM. Five seconds later, if a process hasn't quit, telinit sends a SIGKILL. If specified, the -t seconds parameter changes this interval. In most cases, the default five seconds is adequate.

The runlevel specification is a single-character code for the runlevel. Most obviously, you can provide a runlevel number. There are certain other characters you can pass that have special meaning, however:
  • a, b, or c— Some entries in /etc/inittab use runlevels of a, b, or c for special purposes. If you specify this option to telinit, the program only handles those /etc/inittab entries; the system's runlevel is not changed.
  • Q or q— If you pass one of these values as the runlevel, telinit reexamines the /etc/inittab file and initiates any changes.
  • S or s— This option causes the system to change into a single-user mode.
  • U or u— This option causes the init process to restart itself, without reexamining the /etc/inittab file.

Why would you want to change the runlevel? Changing the default runlevel allows you to control which servers start up by default. On most distributions, the most important of these is the X server. This is usually started by a special line towards the end of /etc/inittab, not through a SysV startup script, although some use a SysV startup script for XDM to do the job. Changing the runlevel while the computer is running allows you to quickly enable or disable a set of servers, or change out of GUI mode if you want to temporarily shut down X when your system is configured to start it automatically.

Tuesday, December 5, 2006

Using Startup Script Utilities

Some distributions include utilities that help you control startup scripts. These tools can be very useful because they reduce the chance of misnaming a script. For instance, an automated tool won't mistype S80postfix as s80postfix (using a lowercase s instead of an uppercase S). Unfortunately, not all distributions support these tools—they're most common on Red Hat and its derivatives, such as Mandrake. Installing one of these tools from one distribution for use on another is unlikely to work because of the differences in SysV script locations and startup sequence numbers.
Using chkconfig
The SysV startup script tool with the crudest user interface is chkconfig. This program is a non-interactive command—you must provide it with the information it needs to do its job on a single command line. The syntax for the command is as follows:
chkconfig <—list—add—del> [name]
chkconfig [—level levels] name [onoffreset]

The first format of this command is used to obtain information on the current configuration (using —list) or to add or delete links in the SysV link script directory (using —add or —del, respectively). The second format is used to enable or disable a script in some or all runlevels by changing the name of the SysV link, as described earlier. Some examples will help clarify the use of this command.

Suppose you want to know how Postfix is configured. If you know the Postfix startup script is called postfix, you could enter the following command to check its configuration:

# chkconfig —list postfix
postfix 0:off 1:off 2:on 3:on 4:on 5:on 6:off

This output shows the status of Postfix in each of the seven runlevels. You can verify this by using the find command described earlier. When chkconfig shows an on value, the startup link filename should start with S, and when chkconfig shows an off value, the startup link filename should start with K.

If you type chkconfig —list without specifying a particular startup script filename, chkconfig shows the status for all the startup scripts, and possibly for servers started through xinetd as well, if your system uses xinetd.

The —add and —del options add links if they don't exist or delete them if they do exist, respectively. Both these options require that you specify the name of the original startup script. For instance, chkconfig —del postfix removes all the Postfix SysV startup script links. The result is that Linux won't start the server through a SysV startup script, or attempt to change a server's status when changing runlevels. You might do this if you wanted to start a server through a super server or local configuration script. You might use the —add parameter to reverse this change.

You'll probably make most chkconfig changes with the on, off, or reset options. These enable a server, disable a server, or return the server to its default setting for a specified runlevel. (If you omit the —level option, the change applies to all runlevels.) For instance, suppose you want to disable Postfix in runlevel 3. You could do so by typing the following command:

# chkconfig —level 3 postfix off

This command won't return any output, so if you feel the need to verify that it's worked, you should use the —list option or look for a changed filename in the startup script link directory. You can enable a server by using on rather than off. If you want to affect more than one runlevel, you can do so by listing all the runlevels in a single string, as in 345 for runlevels 3, 4, and 5. If you've experimented with settings and want to return them to their defaults, you can use the reset option:

# chkconfig postfix reset

This command will reset the SysV startup script links for Postfix to their default values. You can reset the default for just one runlevel by including the —level levels option as the first parameter to the command

Although chkconfig is generally thought of as a way to manage SysV startup scripts, it can also work on xinetd configurations on many systems. If chkconfig is configured to treat, say, your FTP server as one that's launched via a super server, you can use it to manipulate this configuration much as if the FTP server were launched through SysV startup scripts. The difference is that the —level levels parameter won't work, and the —list option doesn't show runlevel information. Instead, any server started through a super server will run in those runlevels in which xinetd runs. Furthermore, the —add and —del options work just like on and off, respectively; the /etc/xinetd.d configuration files aren't deleted, only disabled, as described in the upcoming section, "Using xinetd."

When you change the SysV configuration with chkconfig, it does not automatically alter the servers that are running. For instance, if you reconfigure your system to disable sshd, that server will not be immediately shut down without manual intervention of some sort, such as running the SysV startup script with the stop option to stop the server.

Using ntsysv
The ntsysv program provides a text-based menu environment for manipulating server startup. To run the program, type its name, optionally followed by —level levels, where levels is one or more runlevels you want to modify. If you omit this parameter, ntsysv modifies the configuration only for the current runlevel. Either way, the result should resemble Figure.


Figure The ntsysv program provides an easy-to-use interface for SysV configuration.

The ntsysv display shows all the servers that have SysV startup scripts. Some versions also display servers started through xinetd. To enable or disable a server, use the arrow keys on your keyboard to move the cursor to the server you want to adjust, then press the spacebar to toggle the server on or off. An asterisk (*) in the box to the left of the server name indicates that the server is active; an empty box indicates that the server is disabled. When you're done making changes, use the Tab key to highlight the OK button, then press the Enter key to exit from the program and save your changes.

As with chkconfig, you can't adjust the specific runlevels in which servers mediated by a super server are run, except by changing the runlevels for the super server itself. Also, disabling a server won't cause it to shut down immediately; you must do that by manually shutting the server down, as described earlier, or by restarting the super server, if your target server is handled by the super server.

Monday, December 4, 2006

Manually Enabling or Disabling Startup Scripts

If you find that you need to enable or disable a server that's started through a SysV startup script, one way to proceed is to adjust the startup scripts or the links to them. One approach to disabling a server is to remove the startup script from the SysV script directory. This is a quick fix that affects all runlevels, but it's rather inelegant. It also doesn't help you if you want to start a server rather than disable one.

A more elegant solution is to rename the link to the startup script in the SysV link directory that corresponds to your current runlevel. For instance, to disable a server, rename it so that it starts with K rather than S; to enable it, reverse this process. The difficulty with this procedure is that the sequence number isn't likely to be the same when killing the server as when starting it. One way around this potential pitfall is to locate all the links to the script in all the runlevels. If any of the other runlevels sport the configuration you want, you've found the sequence number. For instance, the following command finds all the links for the Postfix mail server startup scripts on a Mandrake system:

$ find /etc/rc.d -name "*postfix"
/etc/rc.d/rc0.d/K30postfix
/etc/rc.d/rc1.d/K30postfix
/etc/rc.d/rc2.d/S80postfix
/etc/rc.d/rc3.d/S80postfix
/etc/rc.d/rc4.d/S80postfix
/etc/rc.d/rc5.d/S80postfix
/etc/rc.d/rc6.d/K30postfix
/etc/rc.d/init.d/postfix

This sequence shows that Postfix is started with a sequence number of 80 in runlevels 2 through 5, and shut down with a sequence number of 30 in runlevels 0, 1, and 6. If you wanted to disable Postfix in runlevel 3, you could do so by renaming S80postfix to K30postfix in that runlevel's directory.

If you want to temporarily start or stop a server, or if you want to initiate a change immediately without restarting the computer or adjusting the runlevel, you can do so by running the startup script along with the start or stop parameters. For instance, to stop Postfix immediately, you could type the following command on a Mandrake system:

# /etc/rc.d/init.d/postfix stop

Most Linux distributions display a message reporting the attempt to shut down the server, and the success of the operation. When starting a SysV script, a message about the startup success appears. (In fact, you may see these messages scroll across your screen after the kernel startup messages when you boot your computer.)

In the case of Slackware, instead of renaming, adding, or deleting startup scripts or their links, you should edit the single startup script file for the runlevel in question. For instance, if you want to change the behavior of runlevel 4, you'd edit /etc/rc.d/rc.4. Most servers, though, aren't started in these runlevel-specific scripts; they're started in /etc/rc.d/rc.inet2, with very basic network tools started in /etc/rc.d/rc.inet1. To change your configuration, you'll have to manually modify these scripts as if they were local startup scripts, as described in the section "Using Local Startup Scripts."

Sunday, December 3, 2006

Startup Script Locations and Naming Conventions

Although the basic outline of SysV startup scripts is the same across most distributions, there are differences in many details. Most importantly, different distributions place the startup scripts in different locations. They may also call scripts by different names, although these differences are usually not too extreme. Table summarizes these SysV layout differences for several major Linux distributions. Note that distributions differ in where they place the actual scripts, where they place the links to the scripts that are associated with specific runlevels, and where they place local startup scripts (which are discussed in more detail shortly, in the section "Using Local Startup Scripts"). In the case of script links, a ? in the directory name refers to a number from 0 to 6 corresponding to the runlevel.


Several distributions (notably Red Hat, Mandrake, TurboLinux, and to a lesser extent Caldera) are quite similar to each other, particularly in their placement of SysV scripts (/etc/rc.d/init.d) and the links to those scripts (/etc/rc.d/rc?.d). Others place the scripts in slightly different locations. Slackware is the most unusual in this respect. Rather than running individual scripts in a directory named after a runlevel, Slackware uses a single script for each runlevel. For instance, the /etc/rc.d/rc.4 script controls the startup of runlevel 4.

For most Linux distributions (Slackware being the major exception), the links in the SysV startup script link directories are named in a very particular way. Specifically, the filename takes the form C##name, where C is a character (S or K), ## is a two-digit number, and name is a name that's traditionally the same as the corresponding script in the SysV script directory. For instance, the link filename might be S10network or K20nfs—filenames that correspond to the network and nfs scripts, respectively. As you might guess, this naming scheme isn't random. The name portion of the link filename helps you determine what the script does; it's usually named after the original script. The leading character indicates whether the computer will start or kill (for S and K, respectively) the script upon entering the specified runlevel. Thus, S10network indicates that the system will start whatever the network script starts (basic networking features, in fact), and K20nfs shuts down whatever the nfs script controls (the NFS server, in reality). The numbers indicate the sequence in which these actions are to be performed. Thus, S10network starts networking before S55sshd starts the secure shell (SSH) server. Similar rules apply for shutdown (K) links.

The names and numbers of the startup and shutdown links vary from one distribution to another. For instance, Mandrake uses S10network to start its basic networking features, but Debian uses S35networking for this function. Similar differences may exist for the scripts that launch specific servers. What's important is that all the necessary servers and processes are started in the correct order. Many networking tools must be started after basic networking features are started, for instance. It's generally not wise to change the order in which startup and shutdown scripts execute, unless you understand this sequence and the consequences of your changes.

One additional wrinkle requires mention: SuSE uses the /etc/rc.config file to control the SysV startup process. This file contains sections pertaining to major servers that can be started via the SysV process, and if a server is not listed for startup (via a line of the form START_SERVERNAME="yes"), SuSE doesn't start that server, even if its link name begins with S. Caldera uses a similar scheme for a few servers, but uses files in /etc/sysconfig/daemons named after the servers in question. The ONBOOT line in each of these files determines whether the system starts the server. Many startup scripts ignore this option in Caldera, though.

Saturday, December 2, 2006

Using SysV Startup Scripts

AT&T's System V, or SysV, UNIX set many of the standards used on today's UNIX and Linux systems. One of these was a method of starting system services, including servers. In the SysV scheme, each service comes with a script that can be used to start or stop the service by passing the script the start or stop parameter, respectively. Many of these startup scripts support additional parameters, such as restart to shut down the server and start it up again (say, to implement a changed configuration).

The SysV startup scheme is closely tied to the runlevel of the computer. Each runlevel is associated with a specific set of startup scripts, and hence with a specific set of services that the system runs. (SysV scripts can start more than just network servers; they can start system loggers, filesystem handlers, and so on.) Thus, configuring servers to start via SysV scripts is closely related to configuring these runlevels. This is done by altering the names of links to the startup scripts, as stored in directories associated with each runlevel.

Starting Servers

The bulk of this book deals with the operation of a wide variety of servers. These programs should normally be accessible at all times once a computer has booted, aside from any scheduled downtime or restrictions you might impose for security reasons. It's therefore important that you understand how servers are started. Without this knowledge, you might find yourself unable to start a server once you've installed it, or unable to restart a server after making changes to its configuration.

Fortunately, in many cases Linux configures things so that a server starts automatically after it's installed, or at least once you reboot the computer after installing the server. There are three major methods you can use to start a server on a regular basis: via System V (SysV) startup scripts; via a super server, such as inetd or xinetd; or via a local startup script. You can always configure any of these methods by manually editing the appropriate configuration files or scripts. With most distributions, you can also accomplish the task through the use of GUI tools. This chapter covers all these methods of starting servers. Subsequent chapters refer back to this one to convey how a specific server is most commonly started.

Friday, December 1, 2006

Using Linux NetBEUI Software

The NetBEUI stack includes a README file with complete installation and use instructions. This file outlines two methods of installation. One requires you to edit the Makefile to point to your Linux kernel and Samba source code trees and set a few other system-specific options. You can then recompile both Linux and Samba with a single command, install your new kernel, and reboot the system. The second procedure also requires you to edit the Makefile, but proceeds to give instructions on performing individual steps in a piecemeal fashion. This second approach is likely to be superior if you run into any difficulties, because you'll be better able to isolate and correct the problem.

Whichever way you do it, you'll need the source code to both the Linux kernel and Samba. You can obtain these from http://www.kernel.org and http://www.samba.org, respectively, or from many common Linux download sites, like ftp://sunsite.unc.edu. Both packages can take several minutes to compile and install, so even if you don't run into problems, installing NetBEUI support is likely to take several minutes.

Once you've installed NetBEUI support, you can use several commands to enable or manipulate this support. These commands, included with the NetBEUI stack, are as follows:
  • netb— Type this command followed by start to start NetBEUI on Linux. To stop NetBEUI, type netb stop. You must use this utility before you can use NetBEUI on Linux.
  • nbview— Use this command if you want to check on the status of the local NetBEUI stack. This command reads the /proc/sys/netbeui file, which contains this information, and formats and parses the information for easier human consumption.
  • nbstatus— This command displays information on the specified machine or workgroup; for instance, nbstatus SERVER displays information on the computer called SERVER.
  • nbadmin— This command allows you to bind NetBEUI to a specific network interface, unbind NetBEUI from a specific interface, or drop a specific NetBEUI session. It does this using the bind, unbind, and drop commands, respectively, as in nbadmin bind eth0 or nbadmin drop 102. (You can obtain NetBEUI session numbers from nbview.)

For the most part, you'll only need to issue a netb start command, then start Samba. The NetBEUI stack adds a parameter to nmbd (the NetBIOS name daemon), smbd (the SMB daemon), and smbclient (the text-mode Samba client) to specify whether to use TCP/IP or NetBEUI. This parameter is -Z . For instance, to launch smbd to use NetBEUI, you'd type smbd -Z NETBEUI. You can also use the new -S NAME parameter to smbd to set the system's NetBEUI name to NAME.

To sum up, you can turn Linux into a NetBEUI SMB/CIFS server called NAME by recompiling the kernel and Samba with the Procom NetBEUI stack, rebooting, shutting down Samba (if necessary), and typing the following commands

# netb start

# nmbd -Z NETBEUI

# smbd -Z NETBEUI -S NAME

You can place these commands in a startup script, or modify your regular Samba startup script to incorporate these changes. Other Samba features, such as the definitions of shares, all function as described in Chapter 7. The advantage of this procedure boils down to two factors. First, it can be used with some older clients that support NetBEUI but not TCP/IP, and it reduces the chance of malicious outside access to the computer via Samba, because NetBEUI isn't normally routed over the Internet. On the downside, NetBEUI support is duplicated in NetBIOS over TCP/IP, which works with all recent Linux kernels and versions of Samba, and doesn't require patching or recompiling the kernel or Samba.