Many systems administrators, users, engineers and the like are familar with the internet super server or inetd. Additionally, most are also quite familar with the relationship between several key files in the /etc directory and inetd. Suprisingly there is very little documentation on the internet that is easily obtainable which explains the basics of inetd and its relation to other files and the system as a whole.
In this document we will look at a simple definition of inetd, how several files that relate to inetd work (not that these files are not related to other software), how to add a service to inetd and some considerations both to use inetd for a particular service and times when a service might be better off running outside of inetd.
The internet super server listens on its own sockets, when it receives a request it then determines which server to connect the request to and starts an instance of the server program.
Following is a very simple diagram to illustrate inetd:
pop3 ------ | | ftpd ------- | INETD | ---- Internet / DMZ / Switch / Whatever . . . | cvspserver - |
In the above diagram you can see the general idea. The inetd server receives a request and then starts the appropiate server process. What inetd is doing is software multiplexing. An important note here, on many other UNIX-like systems, inetd has a package called tcpwrappers as a security enhancment, on NetBSD the secure behavoir of tcpwrappers was built in using libwrap.
The first file is the protocols name data base which is /etc/protocols. This file has the information pertaining to DARPA Internet protocols. The format of the protocols name data base is:
protocol_name number aliases
Lets look at the second entry in the /etc/protocols db as an example:
icmp 1 ICMP
Starting from the left, we see that the protocol name is icmp, the number is 1 and the only aliases listed is ICMP.
The next file to consider is the service name data base that can be found in /etc/services. This db basically contains information about services and the mappings from protocol to port number. The format of the /etc/services file is:
service_name port_number protocol_name aliases
Lets take a look at the ssh entries as an example:
ssh 22/tcp ssh 22/udp
As we can see, from the left, the service name is ssh, the port number is 22, the protocols are both tcp and udp. Notice that there is a separate entry for every protocol a service can use (even on the same port).
The rpc program number data base is kept in /etc/rpc and contains name mappings to rpc program numbers, the format of the file is:
server_name program_number aliases
For example, here is the nfs entry:
nfs 100003 nfsprog
Last and definitely not least of the files we are concerned with is the internet super-server file, /etc/inetd.conf. The inetd.conf file basically provides enabling and mapping of services the systems administrator would like to have multiplexed through inetd.
The previous files were very much informational for the system and hence their layout was also relatively simple, the inetd.conf file, however, is a little more complex (but not too much) and deserves a little deeper explanation.
The basic field layout of the inetd.conf file is:
service_name socket_type protocol wait/nowait user:group server_program arguments
The service name should match up with the /etc/services file for all standard services (it is at least highly recommended), however, non-standard services you may be running locally do not, it is important that you take care in selecting a non-standard service name so it does not clash with a standard one.
The communications socket type, the different types are stream dgram raw rdm and seqpacket. The most common socket types are stream and dgram.
The protocol used, mostly tcp, tcp6, udp and udp6. It is worth noting that tcp and udp mean they are backwards compatible with all previous versions, however, tcp4 specifically means communication via ipv4 only. This can be taken a step forward by putting ipv46. In additon to those, rpc uses rpc and tcp or rpc/tcp.
This field tells inetd if it should wait for a server program to return or to keep processing a connection steadily. Many connections to their server processes require answers after data transfers are complete, where other types can keep transmitting on a connection continously, the latter is a nowait and the former wait. In most cases, this entry corresponds to the socket-type, for example a streaming connection would (most of the time) have a nowait value in this field.
This field is pretty obvious, the user and optionally a group that runs the server process which inetd starts up.
This field is path to the program that gets started.
This field contains the program and additional arguments the systems administrator may need to specifiy for the server program that is started.
That is all a lot to digest and there are other things the systems administrator can do with some of the fields. Here is a sample line from an inetd.conf file:
ftp stream tcp nowait root /usr/libexec/ftpd ftpd -ll
From the left, the service-name is ftp, socket-type is stream, protocol is tcp, wait/nowait is set to nowait, the user is root, path is /usr/libexec/ftpd and program name and arguments is ftpd -ll. Notice in the last field, the program name is different from the service-name.
Many times a systems administrator will find that they need to add a service to their system that is not already in inetd or they may wish to move a service to it because it does not get very much traffic. This is usually pretty simple, so as an example we will look at adding a version of pop3 on a NetBSD system.
In this case we have retrieved and installed the cucipop package. This server is pretty simple to use, the only oddities are different path locations. Since it is pop3 we know it is a stream oriented connection with nowait. Using root will be fine, the only item that is different is the location of the program and the name of the program itself.
So the first half of the new entry looks like this:
pop3 stream tcp nowait root
After installation, pkgsrc deposited cucipop in /usr/pkg/sbin/cucipop. So with the next field we have:
pop3 stream tcp nowait root /usr/pkg/sbin/cucipop
Last, we want to use the Berkeley mailbox format, so our server program must be called with the -Y option. This leaves the entire entry looking like so:
pop3 stream tcp nowait root /usr/pkg/sbin/cucipop cucipop -Y
Now, to have inetd use the new entry, we simply restart it using the rc script:
# /etc/rc.d/inetd restart
All done, in most cases, the software you are using has documentation that will specify the entry, in the off case it does not, sometimes it helps to try and find something similar to the server program you will be adding. A classic example of this is a MUD server which has built-in telnet. You can pretty much borrow the telnet entry and change parts where needed.
The decision to add or move a service into or out of inetd is usually arrived at based on serverload. As an example, on most systems the telnet daemon does not require as many new connections as say a mail server. Most of the time the administrator has to feel out if a service should be moved.
A good example I have seen is mail services such as smtp and pop. I had setup a mail server in which pop3 was in inetd and exim was running in standalone, I mistakenly assumed it would run fine since there was a low amount of users, namely myself and a diagnostic account. The server was also setup to act as a backup MX and relay in case another heavily used one went down. When I ran some tests I discovered a huge time lag for pop connections remotely. This was because of my steady fetching of mail and the diagnostic user constanty mailing diagnostics back and forth. In the end I had to move the pop3 service out of inetd.
The reason for moving the service is actually quite interesting. When a particular service becomes heavily used, of course, it causes a load on the system. In the case of a service that runs within the inetd meta daemon the effects of a heavily loaded service can also harm other services that use inetd. If the multiplexor is getting too many requests for one particular service, it will begin to affect the performance of other services that use inetd. The fix, in a situation like that, is to make the offending service run outside of inetd so the response time of both the service and inetd will increase.
Following is some additional reading and information about topics covered in this document: