Annotation of wikisrc/guide/inetd.mdwn, revision 1.3

1.1       jdf         1: # The Internet Super Server inetd
                      2: 
1.3     ! jdf         3: The *internet super server*, or
        !             4: [inetd(8)](http://netbsd.gw.com/cgi-bin/man-cgi?inetd+8+NetBSD-5.0.1+i386), is
        !             5: available on all Unix(like) systems, providing many of the basic network
        !             6: services available. This chapter describes the relationship between the daemon
1.1       jdf         7: and several of the config files in the `/etc/` directory.
                      8: 
                      9: ## Overview
                     10: 
1.3     ! jdf        11: In this document we will look at a simple definition of
        !            12: [inetd(8)](http://netbsd.gw.com/cgi-bin/man-cgi?inetd+8+NetBSD-5.0.1+i386), how
        !            13: several files that relate to
        !            14: [inetd(8)](http://netbsd.gw.com/cgi-bin/man-cgi?inetd+8+NetBSD-5.0.1+i386) work
        !            15: (not that these files are not related to other software), how to add a service
        !            16: to [inetd(8)](http://netbsd.gw.com/cgi-bin/man-cgi?inetd+8+NetBSD-5.0.1+i386)
        !            17: and some considerations both to use
        !            18: [inetd(8)](http://netbsd.gw.com/cgi-bin/man-cgi?inetd+8+NetBSD-5.0.1+i386) for a
        !            19: particular service and times when a service might be better off running outside
1.1       jdf        20: of [inetd(8)](http://netbsd.gw.com/cgi-bin/man-cgi?inetd+8+NetBSD-5.0.1+i386).
                     21: 
                     22: ## What is inetd?
                     23: 
1.3     ! jdf        24: In traditional Unix scenarios, one server (daemon) process watches for
        !            25: connections on a particular port, and handles incoming requests. Now if a
        !            26: machine offers many services, many daemon processes would be needed, mostly
        !            27: running idle but still wasting resources like memory. The internet super server,
        !            28: inetd, is an approach to this problem. It listens on a number of ports, and when
        !            29: it receives a request it then determines which program to run to handle the
1.1       jdf        30: request and starts an instance of that program.
                     31: 
1.3     ! jdf        32: Following is a very simple diagram to illustrate
1.1       jdf        33: [inetd(8)](http://netbsd.gw.com/cgi-bin/man-cgi?inetd+8+NetBSD-5.0.1+i386):
                     34: 
                     35:     pop3  -------|  
                     36:                  |  
                     37:     ftpd --------| INETD | ---- Internet / DMZ / Switch / Whatever . . .  
                     38:                  |  
                     39:     cvsupserver -|
                     40: 
1.3     ! jdf        41: In the above diagram you can see the general idea. The
        !            42: [inetd(8)](http://netbsd.gw.com/cgi-bin/man-cgi?inetd+8+NetBSD-5.0.1+i386)
        !            43: process receives a request and then starts the appropriate server process. What
        !            44: [inetd(8)](http://netbsd.gw.com/cgi-bin/man-cgi?inetd+8+NetBSD-5.0.1+i386) is
        !            45: doing is software multiplexing. An important note here, regarding security: On
        !            46: many other UNIX-like systems, a package called tcpwrappers is used as a security
        !            47: enhancement for
        !            48: [inetd(8)](http://netbsd.gw.com/cgi-bin/man-cgi?inetd+8+NetBSD-5.0.1+i386). On
        !            49: NetBSD the tcpwrapper functionality is built into
        !            50: [inetd(8)](http://netbsd.gw.com/cgi-bin/man-cgi?inetd+8+NetBSD-5.0.1+i386) using
1.1       jdf        51: libwrap.
                     52: 
1.2       jdf        53: ## Configuring inetd - /etc/inetd.conf
1.1       jdf        54: 
1.3     ! jdf        55: The operation of
        !            56: [inetd(8)](http://netbsd.gw.com/cgi-bin/man-cgi?inetd+8+NetBSD-5.0.1+i386) is
        !            57: controlled by its own config file, surprisingly named `/etc/inetd.conf`, see
        !            58: [inetd.conf(5)](http://netbsd.gw.com/cgi-bin/man-cgi?inetd.conf+5+NetBSD-5.0.1+i386).
        !            59: The `inetd.conf` file basically provides enabling and mapping of services the
        !            60: systems administrator would like to have multiplexed through
        !            61: [inetd(8)](http://netbsd.gw.com/cgi-bin/man-cgi?inetd+8+NetBSD-5.0.1+i386),
1.1       jdf        62: indicating which program should be started for incoming requests on which port.
                     63: 
1.3     ! jdf        64: [inetd.conf(5)](http://netbsd.gw.com/cgi-bin/man-cgi?inetd.conf+5+NetBSD-5.0.1+i386)
        !            65: is an ascii file containing one service per line, and several fields per line.
1.1       jdf        66: The basic field layout is:
                     67: 
                     68:     service-name socket-type protocol wait/nowait user:group server-program arguments
                     69: 
1.3     ! jdf        70:  * `service-name`: The service name indicates the port
        !            71:    [inetd(8)](http://netbsd.gw.com/cgi-bin/man-cgi?inetd+8+NetBSD-5.0.1+i386)
        !            72:    should listen on. It is either a decimal number, or a name matching a service
1.1       jdf        73:    name given in `/etc/services`.
                     74: 
1.3     ! jdf        75:  * `socket-type`: The communications socket type, the different types are
        !            76:    `stream` for a TCP stream, `dgram` for an UDP service, `raw` for a raw
        !            77:    socket, `rdm` for reliably delivered message and "seqpacket` for a sequenced
1.1       jdf        78:    packet socket. The most common socket types are `stream` and `dgram`.
                     79: 
1.3     ! jdf        80:  * `protocol`: The protocol used, mostly `tcp`, `tcp6`, `udp` and `udp6` for
        !            81:    stream-oriented services via the Transmission Control Protocol, or
        !            82:    datagram-oriented services via the User Datagram Protocol. It is worth noting
        !            83:    that `tcp` and `udp` mean they use the default (currently IPv4), `tcp4`
        !            84:    specifically means communication via IPv4 only, and `tcp6` and `udp6` are
        !            85:    IPv6-only. In addition to those, protocols based on Remote Procedure Calls
1.1       jdf        86:    (RPC) can be specified as either `rpc/tcp` or `rpc/udp`.
                     87: 
1.3     ! jdf        88:  * `wait/nowait`: This field tells
        !            89:    [inetd(8)](http://netbsd.gw.com/cgi-bin/man-cgi?inetd+8+NetBSD-5.0.1+i386) if
        !            90:    it should wait for a server program to return or to continue processing new
        !            91:    connections immediately. Many connections to server processes require answers
        !            92:    after data transfers are complete, where other types can keep transmitting on
        !            93:    a connection continuously, the latter is a `nowait` and the former `wait`. In
        !            94:    most cases, this entry corresponds to the socket-type, for example a
        !            95:    streaming connection would (most of the time) have a `nowait` value in this
1.1       jdf        96:    field.
                     97: 
1.3     ! jdf        98:  * `user[:group]`: This field gives the user name and optionally a group name
        !            99:    that the server process which
        !           100:    [inetd(8)](http://netbsd.gw.com/cgi-bin/man-cgi?inetd+8+NetBSD-5.0.1+i386)
1.1       jdf       101:    starts up runs as.
                    102: 
1.3     ! jdf       103:  * `server-program`: This field is the full path of the program that gets
1.1       jdf       104:    started.
                    105: 
1.3     ! jdf       106:  * `program-arguments`: This field contains the argument vector argv[] of the
        !           107:    program started, including the program name and additional arguments the
        !           108:    systems administrator may need to specify for the server program that is
1.1       jdf       109:    started.
                    110: 
1.3     ! jdf       111: That is all a lot to digest and there are other things the systems administrator
1.1       jdf       112: can do with some of the fields. Here is a sample line from an `inetd.conf` file:
                    113: 
                    114:     ftp       stream  tcp    nowait  root   /usr/libexec/ftpd    ftpd -ll
                    115: 
1.3     ! jdf       116: From the left, the service-name is `ftp`, socket-type is `stream`, protocol is
        !           117: `tcp`,
        !           118: [inetd(8)](http://netbsd.gw.com/cgi-bin/man-cgi?inetd+8+NetBSD-5.0.1+i386) won't
        !           119: wait for the server process to terminate (`nowait`), the process runs as user
1.1       jdf       120: `root`, path is `/usr/libexec/ftpd` and program name and arguments are
1.3     ! jdf       121: `ftpd -ll`. Notice in the last field, the program name is different from the
1.1       jdf       122: service-name.
                    123: 
1.2       jdf       124: ## Services - /etc/services
1.1       jdf       125: 
1.3     ! jdf       126: The next file to consider is the service name data base that can be found in
        !           127: `/etc/services`. This file basically contains information mapping a service name
1.1       jdf       128: to a port number. The format of the `/etc/services` file is:
                    129: 
                    130:     service-name port-number/protocol-name [aliases]
                    131: 
1.3     ! jdf       132: `service-name` is the name of the service, `port-number` is the port number
        !           133: assigned to the service, `protocol-name` is either `tcp` or `udp`, and if alias
        !           134: names for a port are needed, they can be added as `aliases`, separated by white
1.1       jdf       135: spaces. Comments may be added after a hash mark (`#`).
                    136: 
                    137: Let's take a look at the `ssh` entries as an example:
                    138: 
                    139:     ssh             22/tcp           # Secure Shell
                    140:     ssh             22/udp
                    141: 
1.3     ! jdf       142: As we can see, from the left, the service name is `ssh`, the port number is 22,
        !           143: the protocols are both tcp and udp. Notice that there is a separate entry for
1.1       jdf       144: every protocol a service can use (even on the same port).
                    145: 
1.2       jdf       146: ## Protocols - /etc/protocols
1.1       jdf       147: 
1.3     ! jdf       148: Another file read by
        !           149: [inetd(8)](http://netbsd.gw.com/cgi-bin/man-cgi?inetd+8+NetBSD-5.0.1+i386) is
        !           150: `/etc/protocols`. This file has the information pertaining to DARPA Internet
1.1       jdf       151: protocols. The format of the protocols name data base is:
                    152: 
                    153:     protocol-name number [aliases]
                    154: 
1.3     ! jdf       155: where `protocol-name` describes the payload of an IP packet, e.g. `tcp` or
        !           156: `udp`. `number` is the official protocol number assigned by IANA, and optional
1.1       jdf       157: alias names can be added after that.
                    158: 
                    159: Let's look at the seventh entry in the `/etc/protocols` db as an example:
                    160: 
                    161:     tcp     6       TCP             # transmission control protocol
                    162: 
1.3     ! jdf       163: Starting from the left, we see that the protocol name is tcp, the number is 6
        !           164: and the only aliases listed is TCP, belonging to the Transmission Control
1.1       jdf       165: Protocol as indicated by the comment in that line.
                    166: 
1.2       jdf       167: ## Remote Procedure Calls (RPC) - /etc/rpc
1.1       jdf       168: 
1.3     ! jdf       169: The rpc program number data base used by services with the `rpc` protocol type
        !           170: in
        !           171: [inetd.conf(5)](http://netbsd.gw.com/cgi-bin/man-cgi?inetd.conf+5+NetBSD-5.0.1+i386)
        !           172: is kept in `/etc/rpc` and contains name mappings to rpc program numbers. The
1.1       jdf       173: format of the file is:
                    174: 
                    175:     server-name program-number aliases
                    176: 
                    177: For example, here is the nfs entry:
                    178: 
                    179:     nfs             100003  nfsprog
                    180: 
1.2       jdf       181: # Allowing and denying hosts - /etc/hosts.allow, /etc/hosts.deny
1.1       jdf       182: 
1.3     ! jdf       183: As mentioned above, NetBSD's
        !           184: [inetd(8)](http://netbsd.gw.com/cgi-bin/man-cgi?inetd+8+NetBSD-5.0.1+i386) has
        !           185: the tcpwrapper package built in via the libwrap library. As such,
        !           186: [inetd(8)](http://netbsd.gw.com/cgi-bin/man-cgi?inetd+8+NetBSD-5.0.1+i386) can
        !           187: allow or deny access to each service on a more fine-grained base than just
        !           188: allowing a service to everyone, or not enabling it at all. The access control is
        !           189: defined in the files `/etc/hosts.allow` and `/etc/hosts.deny`, see the
        !           190: [hosts\_access(5)](http://netbsd.gw.com/cgi-bin/man-cgi?hosts_access+5+NetBSD-5.0.1+i386)
1.1       jdf       191: manpage.
                    192: 
1.3     ! jdf       193: Each of the two files contains several lines that describe access restrictions
        !           194: for a certain server. Access is allowed if permission is given in
1.1       jdf       195: `/etc/hosts.allow`. If the service is not listened in `/etc/hosts.allow` but in
                    196: `/etc/hosts.deny`, it is denied. If a service is listed in neither file, it is
1.3     ! jdf       197: allowed, giving standard
        !           198: [inetd(8)](http://netbsd.gw.com/cgi-bin/man-cgi?inetd+8+NetBSD-5.0.1+i386)
1.1       jdf       199: behaviour.
                    200: 
1.3     ! jdf       201: Each line in `/etc/hosts.allow` and `/etc/hosts.deny` contains a service either
        !           202: by name (as given in the field for argv[0] in `/etc/inetd.conf`, e.g. `ftpd`
        !           203: instead of `ftp`), or the special service `ALL` which obviously applies to all
        !           204: services. Following the service name is - separated by a colon - a number of
        !           205: access restrictions, which can be hostnames, domains, single IP addresses, whole
        !           206: IP subnets or some other restrictions, please check
        !           207: [hosts\_access(5)](http://netbsd.gw.com/cgi-bin/man-cgi?hosts_access+5+NetBSD-5.0.1+i386)
1.1       jdf       208: for all the details.
                    209: 
1.3     ! jdf       210: An example configuration that is mostly open but denies access to services to a
1.1       jdf       211: certain host and all machines from a certain domain would look like this:
                    212: 
                    213:     # /etc/hostname.deny:
                    214:     ALL: some.host.name, .some.domain
                    215: 
1.3     ! jdf       216: Another example that would be mostly closed, denying access to all but very few
        !           217: machines would need entries in both `/etc/hosts.allow` and `/etc/hosts.deny`.
1.1       jdf       218: The entry for `/etc/hosts.deny` would be:
                    219: 
                    220:     # /etc/hosts.deny
                    221:     ALL: ALL
                    222: 
                    223: The entry to allow a few hosts would be put into `/etc/hosts.allow`:
                    224: 
                    225:     # /etc/hosts.allow
                    226:     ALL: friend.host.domain otherfriend.otherhost.otherdomain
                    227: 
                    228: ## Adding a Service
                    229: 
1.3     ! jdf       230: Many times a systems administrator will find that they need to add a service to
        !           231: their system that is not already in
        !           232: [inetd(8)](http://netbsd.gw.com/cgi-bin/man-cgi?inetd+8+NetBSD-5.0.1+i386) or
        !           233: they may wish to move a service to it because it does not get very much traffic.
        !           234: This is usually pretty simple, so as an example we will look at adding a version
1.1       jdf       235: of POP3 on a NetBSD system.
                    236: 
1.3     ! jdf       237: In this case we have retrieved and installed the `cucipop` package, which can be
        !           238: found in `pkgsrc/mail/cucipop`. This server is pretty simple to use, the only
        !           239: oddities are different path locations. Since it is POP3 we know it is a stream
        !           240: oriented connection with `nowait`. Running as `root` will be fine, the only item
        !           241: that is different is the location of the program and the name of the program
1.1       jdf       242: itself.
                    243: 
                    244: So the first half of the new entry in `/etc/inetd.conf` looks like this:
                    245: 
                    246:     pop3   stream  tcp     nowait  root
                    247: 
1.3     ! jdf       248: After installation, pkgsrc deposited cucipop in `/usr/pkg/sbin/cucipop`. So with
1.1       jdf       249: the next field we have:
                    250: 
                    251:     pop3   stream  tcp     nowait  root /usr/pkg/sbin/cucipop
                    252: 
1.3     ! jdf       253: Last, we want to use the Berkeley mailbox format, so our server program must be
1.1       jdf       254: called with the `-Y` option. This leaves the entire entry looking like so:
                    255: 
                    256:     pop3   stream  tcp     nowait  root /usr/pkg/sbin/cucipop cucipop -Y
                    257: 
1.3     ! jdf       258: We have added the service named `pop3` to `/etc/inetd.conf`. Next item to check
1.1       jdf       259: is that the system can map the service name to a port number in `/etc/services`:
                    260: 
                    261:     # grep ^pop3 /etc/services
                    262:     pop3            110/tcp         # POP version 3
                    263:     pop3            110/udp
                    264:     pop3s           995/tcp                 # pop3 protocol over TLS/SSL (was spop3)
                    265:     pop3s           995/udp                 # pop3 protocol over TLS/SSL (was spop3)
                    266: 
1.3     ! jdf       267: The `pop3` entries here are of interest, i.e. they are already contained in the
1.1       jdf       268: `/etc/services` file shipped with NetBSD.
                    269: 
1.3     ! jdf       270: Now, to have
        !           271: [inetd(8)](http://netbsd.gw.com/cgi-bin/man-cgi?inetd+8+NetBSD-5.0.1+i386) use
1.1       jdf       272: the new entry, we simply restart it using the rc script:
                    273: 
                    274:     # sh /etc/rc.d/inetd restart
                    275: 
1.3     ! jdf       276: All done, in most cases, the software you are using has documentation that will
        !           277: specify the entry, in the off case it does not, sometimes it helps to try and
        !           278: find something similar to the server program you will be adding. A classic
        !           279: example of this is a MUD server which has built-in telnet. You can pretty much
1.1       jdf       280: borrow the telnet entry and change parts where needed.
                    281: 
                    282: ## When to use or not to use inetd
                    283: 
1.3     ! jdf       284: The decision to add or move a service into or out of
        !           285: [inetd(8)](http://netbsd.gw.com/cgi-bin/man-cgi?inetd+8+NetBSD-5.0.1+i386) is
        !           286: usually based on server load. As an example, on most systems the telnet daemon
        !           287: does not require as many new connections as say a mail server. Most of the time
1.1       jdf       288: the administrator has to feel out if a service should be moved.
                    289: 
1.3     ! jdf       290: A good example I have seen is mail services such as smtp and pop. I had setup a
        !           291: mail server in which pop3 was in
        !           292: [inetd(8)](http://netbsd.gw.com/cgi-bin/man-cgi?inetd+8+NetBSD-5.0.1+i386) and
        !           293: exim was running in standalone, I mistakenly assumed it would run fine since
        !           294: there was a low amount of users, namely myself and a diagnostic account. The
        !           295: server was also setup to act as a backup MX and relay in case another heavily
        !           296: used one went down. When I ran some tests I discovered a huge time lag for pop
        !           297: connections remotely. This was because of my steady fetching of mail and the
        !           298: diagnostic user constantly mailing diagnostics back and forth. In the end I had
        !           299: to move the pop3 service out of
1.1       jdf       300: [inetd(8)](http://netbsd.gw.com/cgi-bin/man-cgi?inetd+8+NetBSD-5.0.1+i386).
                    301: 
1.3     ! jdf       302: The reason for moving the service is actually quite interesting. When a
        !           303: particular service becomes heavily used, of course, it causes a load on the
        !           304: system. In the case of a service that runs within the
        !           305: [inetd(8)](http://netbsd.gw.com/cgi-bin/man-cgi?inetd+8+NetBSD-5.0.1+i386) meta
        !           306: daemon the effects of a heavily loaded service can also harm other services that
        !           307: use [inetd(8)](http://netbsd.gw.com/cgi-bin/man-cgi?inetd+8+NetBSD-5.0.1+i386).
        !           308: If the multiplexor is getting too many requests for one particular service, it
        !           309: will begin to affect the performance of other services that use
        !           310: [inetd(8)](http://netbsd.gw.com/cgi-bin/man-cgi?inetd+8+NetBSD-5.0.1+i386). The
        !           311: fix, in a situation like that, is to make the offending service run outside of
        !           312: [inetd(8)](http://netbsd.gw.com/cgi-bin/man-cgi?inetd+8+NetBSD-5.0.1+i386) so
        !           313: the response time of both the service and
        !           314: [inetd(8)](http://netbsd.gw.com/cgi-bin/man-cgi?inetd+8+NetBSD-5.0.1+i386) will
1.1       jdf       315: increase.
                    316: 
                    317: ## Other Resources
                    318: 
1.3     ! jdf       319: Following is some additional reading and information about topics covered in
1.1       jdf       320: this document.
                    321: 
                    322: NetBSD manual pages:
                    323: 
                    324:  * [inetd(8)](http://netbsd.gw.com/cgi-bin/man-cgi/man?inetd+8+NetBSD-current)
                    325:  * [protocols(5)](http://netbsd.gw.com/cgi-bin/man-cgi/man?protocols+5+NetBSD-current)
                    326:  * [rpc(5)](http://netbsd.gw.com/cgi-bin/man-cgi/man?rpc+5+NetBSD-current)
                    327:  * [services(5)](http://netbsd.gw.com/cgi-bin/man-cgi/man?services+5+NetBSD-current)
                    328:  * [hosts\_access(5)](http://netbsd.gw.com/cgi-bin/man-cgi/man?hosts_access+5+NetBSD-current)
                    329: 
                    330: Miscellaneous links:
                    331: 
                    332:  * [IANA: Protocol Numbers and Assignment Services](http://www.iana.org/numbers.htm)
                    333:  * [RFC1700: Assigned Numbers](http://www.isi.edu/in-notes/rfc1700.txt)
                    334: 

CVSweb for NetBSD wikisrc <wikimaster@NetBSD.org> software: FreeBSD-CVSweb