Inetd, the internet
super-server
Inetd is slowly becoming one of my favorite daemons. It makes writing
programs that talk over the network super easy. Inetd handles all of the
hard socket stuff and allows admins to write simple UNIX-ey programs.
Inetd is useful because it allows us to write services that only run
when they are requested in order to reduce total system load.
How inetd works
Inetd can be conceptualized as a sort of "wrapper daemon". Inetd is
always running despite the fact that many of it's sub-services are
not always running.
Inetd listens on a specific port. When it gets a request, it handles
all of the hard socket parts. This request is then passed to one of our
inetd services
We will use a simple server that echoes the request back to the user
as an example. We will call this inetd service
echod
Inetd passes requests to echod as text.
echod will read from stdin and write to stdout. Everything
written to stdout is passed to the client. echod will then
exit.
echo server example
I use OpenBSD on my webserver. Sadly, systemd sockets have replaced
inetd on many linux systems. systemd sockets are entirely painful to
use. I can't verify that these examples will work on non-OpenBSD systems
but the openbsd-inetd package is available on a wide
variety of debianoiads.
Let's write out out echod service and the configuration
files required to get it working.
Edit /etc/inetd.conf
# port socket type protocol wait/nowait user server program server arguments(optional)
9999 stream tcp nowait daemon /opt/echod/echod.sh
And our echod service file, located at
/opt/echod/echod.sh:
#!/bin/sh
while read l; do
echo $l;
done;
exit 0;
Be sure to chmod +x echod.sh and
rcctl enable inetd && rcctl start inetd or it won't
run.
Testing
Sometimes you can use curl to test a service but I will use netcat
instead because it doesn't assume http.
$ echo "foobar" | nc -N localhost 9999
foobar
$
You can also use telnet to test the service:
$ telnet localhost 9999
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
foo
foo
foobar
foobar
echo back
echo back
^]
telnet> Connection closed.
$
Finger server example
Many months ago, I wrote a finger server to learn more about how
inetd works (and to write a finger daemon that doesn't allow for
enumerating non-regular users). You can download the source
code for my finger server from my gitlab.
This finger server only allows information from users who have a home
directory in /home/ to be displayed. It also has hard-coded
filenames it looks for. Example output looks something like:
$ finger binrc@localhost
[localhost/127.0.0.1]
https://0x19.org
Working on an HPR episode
No .pgpkey
$
Gopher server example
Currently, I am working on a gopher server that runs through inetd to
learn more about how gopher works (and to write a gopher server that
doesn't allow for path traversal). I have yet to add autoindex support
but I thought it would be good to include anyway because it really
demonstrates how simple it can be to write an inetd service. You can download the source code
for my gopher server from my gitlab.
This gopher server reads input from standard in and prints