|Copyright © 2002 Paul Sheer. Click here for copying permissions.
There are some hundred odd services that a common LINUX distribution supports. For all of these to be running simultaneously would be a strain. Hence, a special daemon process watches for incoming TCP connections and then starts the relevant executable, saving that executable from having to run all the time. This is used only for sparsely used services--that is, not web, mail, or DNS.
The daemon that performs this function is traditionally called inetd: the subject of this chapter.
(Section 36.1 contains an example of writing your own network service in shell script to run under inetd.)
Which package contains inetd depends on the taste of your distribution. Indeed, under RedHat, version 7.0 switched to xinetd, a move that departs radically from the traditional UNIX inetd. xinetd is discussed below. The important inetd files are the configuration file /etc/inetd.conf, the executable /usr/sbin/inetd, the inetd and inetd.conf man pages, and the startup script /etc/init.d/inet (or /etc/rc.d/init.d/inetd or /etc/init.d/inetd). Another important file is /etc/services, discussed in Section 26.4.
Most services can be started in one of three ways: first as a standalone (resource hungry, as discussed) daemon; second, under inetd; or third as an inetd service which is ``TCP wrapper''-moderated. However, some services will run using only one method. Here, we will give an example showing all three methods. You will need to have an ftp package installed for this example (either wuftpd on RedHat or ftpd on Debian).
Try the following (alternative commands in parentheses):
( /usr/sbin/in.wuftpd -s )
The -D option instructs the service to start in Daemon mode (or standalone mode). This represents the first way of running an Internet service.
With this method we can let inetd run the service for us. Edit your /etc/inetd.conf file and add or edit the line (alternatives in parentheses):
ftp stream tcp nowait root /usr/sbin/in.ftpd in.ftpd
( ftp stream tcp nowait root /usr/sbin/in.wuftpd in.wuftpd )
Then, restart the inetd service with
( killall -1 inetd )
( /etc/rc.d/init.d/inet restart )
and test with
ps awx | grep ftp
The fields in the /etc/inetd.conf file have the following meanings:
With this last method we let inetd run the service for us under the tcpd wrapper command. This is almost the same as before, but with a slight change in the /etc/inetd.conf entry:
ftp stream tcp nowait root /usr/sbin/tcpd /usr/sbin/in.ftpd
( ftp stream tcp nowait root /usr/sbin/tcpd /usr/sbin/in.wuftpd )
Then, restart the inetd service as before. These alternative lines allow tcpd to invoke in.ftpd (or in.wuftpd) on inetd's behalf. The tcpd command does various tests on the incoming connection to decide whether it should be trusted. tcpd checks what host the connection originates from and compares that host against entries in the file /etc/hosts.allow and /etc/hosts.deny. It can refuse connections from selected hosts, thus giving you finer access control to services.
Consider the preceding /etc/inetd.conf entry against the following line in your /etc/hosts.allow file:
in.ftpd: LOCAL, .my.domain
( in.wuftpd: LOCAL, .my.domain )
as well as the following line in the file /etc/hosts.deny:
( in.wuftpd: ALL )
This example will deny connections from all machines with host names not ending in .my.domain but allow connections from the local [The same machine on which inetd is running] machine. It is useful at this point to try make an ftp connection from different machines to test access control. A complete explanation of the /etc/hosts.allow and /etc/hosts.deny file format can be obtained from hosts_access(5). Another example is ( /etc/hosts.deny):
ALL: .snake.oil.com, 22.214.171.124/255.255.240.0
which would deny access for ALL services to all machines inside the 126.96.36.199 (first 20 bits) network, as well as all machines under the snake.oil.com domain.
Note that the above methods cannot be used simultaneously. If a service is already running one way, trying to start it another way will fail, possibly with a ``port in use'' error message. Your distribution would have already decided whether to make the service an inetd entry or a standalone daemon. In the former case, a line in /etc/inetd.conf will be present; in the latter case, a script /etc/init.d/<service> (or /etc/rc.d/init.d/<service>) will be present to start or stop the daemon. Typically, there will be no /etc/init.d/ftpd script, but there will be /etc/init.d/httpd and /etc/init.d/named scripts. Note that there will always be a /etc/init.d/inet script.
|All these services are potential security holes. Don't take chances: disable them all by commenting out all lines in /etc/inetd.conf.
A typical /etc/inetd.conf file (without the comment lines) looks something like:
ftp stream tcp nowait root /usr/sbin/tcpd in.ftpd -l -a
telnet stream tcp nowait root /usr/sbin/tcpd in.telnetd
shell stream tcp nowait root /usr/sbin/tcpd in.rshd
login stream tcp nowait root /usr/sbin/tcpd in.rlogind
talk dgram udp wait nobody.tty /usr/sbin/tcpd in.talkd
ntalk dgram udp wait nobody.tty /usr/sbin/tcpd in.ntalkd
pop-3 stream tcp nowait root /usr/sbin/tcpd ipop3d
imap stream tcp nowait root /usr/sbin/tcpd imapd
uucp stream tcp nowait uucp /usr/sbin/tcpd /usr/sbin/uucico -l
tftp dgram udp wait root /usr/sbin/tcpd in.tftpd
bootps dgram udp wait root /usr/sbin/tcpd bootpd
finger stream tcp nowait nobody /usr/sbin/tcpd in.fingerd
auth stream tcp wait root /usr/sbin/in.identd in.identd -e -o
The above services have the following purposes (port numbers in parentheses):
Instead of the usual inetd + tcpd combination, RedHat switched to the xinetd package as of version 7.0. The xinetd package combines the features of tcpd and inetd into one neat package. The xinetd package consists of a top-level config file, /etc/xinetd.conf; an executable /usr/sbin/xinetd; and then a config file for each service under the directory /etc/xinetd.d/. This arrangement allows a package like ftpd control over its own configuration through its own separate file.
The default top-level config file, /etc/xinetd.conf, looks simply like this:
instances = 60
log_type = SYSLOG authpriv
log_on_success = HOST PID
log_on_failure = HOST RECORD
The file dictates, respectively, that xinetd does the following: limits the number of simultaneous connections of each service to 60; logs to the syslog facility, using syslog's authpriv channel; logs the HOST and Process ID for each successful connection; and logs the HOST (and also RECORD information about the connection attempt) for each failed connection. In other words, /etc/xinetd.conf really says nothing interesting at all.
The last line says to look in /etc/xinetd.d/ for more (service-specific) files. Our FTP service would have the file /etc/xinetd.d/wu-ftpd containing:
socket_type = stream
server = /usr/sbin/in.ftpd
server_args = -l -a
wait = no
user = root
log_on_success += DURATION USERID
log_on_failure += USERID
nice = 10
This file is similar to our /etc/inetd.conf line above, albeit more verbose. Respectively, this file dictates these actions: listen with a stream TCP socket; run the executable /usr/sbin/in.ftpd on a successful incoming connection; pass the arguments -l -a on the command-line to in.ftpd (see ftpd(8)); never wait for in.ftpd to exit before accepting the next incoming connection; run in.ftpd as user root; additionally log the DURATION and USERID of successful connections; additionally log the USERID of failed connections; and be nice to the CPU by running in.ftpd at a priority of 10.
The security options of xinetd allow much flexibility. Most important is the only_from option to limit the remote hosts allowed to use a service. The most extreme use is to add only_from 127.0.0.1 to the top-level config file:
only_from = 127.0.0.1 mymachine.local.domain
which allows no remote machines to use any xinetd service at all. Alternatively, you can add an only_from line to any of the files in /etc/xinetd.d/ to restrict access on a per-service basis.
only_from can also take IP address ranges of the form nnn .nnn .nnn .nnn /bits, as well as domain names. For example,
only_from = 127.0.0.1 192.168.128.0/17 .somewhere.friendly.com
which in the last case allows access from all machines with host names ending in .somewhere.friendly.com.
Finally there is the no_access option that works identically to only_from, dictating hosts and IP ranges from which connections are not allowed:
no_access = .snake.oil.net
It may be thought that using /etc/hosts.deny ( or only_from = ) to deny access to all remote machines should be enough to secure a system. This is not true: even a local user being able to access a local service is a potential security hole, since the service usually has higher privileges than the user. It is best to remove all services that are not absolutely necessary. For Internet machines, do not hesitate to hash out every last service or even uninstall inetd ( or xinetd ) entirely.
See also Chapter 44.