6.3 The inetd Daemon

6.3 The inetd Daemon

Implementing stand-alone servers for every single service is somewhat inefficient, because each server must know all about the network interface API, have its own port configuration system, and so on. In many respects, the API for talking to TCP is not much different than the standard I/O system. TCP servers read from network ports and return output back to those ports — this is similar to the behavior of cat with no arguments in Section 1.2 is similar.

The inetd daemon is a superserver that standardizes network port access and interfaces between regular programs and network ports. After you start inetd, it reads the inetd.conf file and then listens on the network ports defined in that file, attaching a newly started process to every new incoming connection.

Each line in inetd.conf looks something like this:

ident        stream   tcp   nowait  nobody  /usr/sbin/identd  identd -i

There are seven fields here:

  • Service name The service name from /etc/services (see Section 5.12).

  • Socket type This is usually stream for TCP and dgram for UDP.

  • Protocol The transport protocol, such as tcp or udp.

  • Datagram server behavior For UDP, this is wait or nowait. Services using any other transport protocol should use nowait.

  • User The username that should run the service. Add .group if you want to set a group.

  • Executable The program that inetd should connect to the service.

  • Arguments The arguments for the executable in the preceding field. The first argument should be the name of the program.

A # sign in inetd.conf denotes a comment. To deactivate an inetd service, place a # before its entry in /etc/inetd.conf and then run the following command to make inetd re-read its configuration file:

kill -HUP `cat /var/run/inetd.pid`

inetd has several built-in services that you might see at the beginning of your inetd.conf, including echo, chargen, discard, daytime, and time. You can use these for testing, but otherwise they aren't important.

6.3.1 TCP Wrapper: tcpd, /etc/hosts.allow, /etc/hosts.deny

Before lower-level firewalls took off in popularity, many administrators used the TCP wrapper library for host control over network services. In fact, even if you run an IP firewall, you should still use TCP wrappers on any service that does not have its own logging mechanism (and many inetd services do not have such capabilities).

The tcpd program is the TCP wrapper utility for linking inetd with a server. An administrator can modify the inetd.conf file to include tcpd, like this:

finger  stream  tcp    nowait  nobody  /usr/sbin/tcpd  /usr/sbin/in.fingerd

When someone makes a connection to the finger port, the following happens:

  1. inetd runs tcpd as the name /usr/sbin/in.fingerd.

  2. tcpd verifies the executable /usr/sbin/in.fingerd.

  3. tcpd consults /etc/hosts.allow and /etc/hosts.deny to see if the remote machine has permission to connect.

  4. tcpd logs its decision.

  5. If tcpd decides that the remote host is okay, it runs /usr/sbin/in.fingerd. Otherwise, tcpd terminates, dropping the connection.

Here is an example hosts.deny file:

ALL: .badguys.example.com
in.fingerd: nofinger.example.com
portmap: ALL

You can interpret this as follows:

  • No one in the subdomain .badguys.example.com may connect to any TCP wrapper-enabled program.

  • The host nofinger.example.com may not run in.fingerd.

  • No one may access portmap (see Section 6.6 for more information on this service).

The TCP wrapper library reads /etc/hosts.allow before /etc/hosts.deny. If a rule in /etc/hosts.allow matches an incoming connection, the TCP wrapper library allows the connection, ignoring /etc/hosts.deny. For example, the following line in /etc/hosts.allow enables portmap access to the subdomain goodguys.example.com:

portmap:  .goodguys.example.com


Using domain names in a TCP wrapper configuration has the disadvantage that it uses DNS. Forcing DNS lookups can hinder performance. It's also not extremely secure; it's possible to affect DNS lookups.

6.3.2 xinetd

Some Linux distributions come with an enhanced version of inetd named xinetd (http://www.xinetd.org/). You can read about the xinetd improvements at the Web site, but to summarize, xinetd offers built-in TCP wrapper support, better logging, and extended access control.

If you currently have inetd, should you run xinetd? If you need its features, sure. However, if you only have one local server (for example, FAM for the GNOME desktop), and you firewall the external traffic to this server anyway, there are probably better things you can do with your time. xinetd administrators should also keep careful track of security advisories, because this package has not seen as widespread use as the old inetd.

xinetd does not read inetd.conf, but if you understand the fields in inetd.conf, you won't have trouble using xinetd. If you want an alternative to /etc/xinetd.d, you can also use itox to convert your inetd.conf to a xinetd.conf file that xinetd can read.

To add a new service to xinetd, create a file in /etc/xinetd.d with the name of the service. For example, the /etc/xinetd.d/finger file might look like this:

service finger
    socket_type = stream
    protocol    = tcp
    wait        = no
    user        = nobody
    passenv     =
    server      = /usr/sbin/in.fingerd
    server_args =

To make xinetd recognize the changes, run kill -USR1 on the xinetd process ID.