A little finger

Finger is the name of a networking protocol introduced in December of 1977 as RFC 742. The name stems from the action of using ones finger to manually scan a list of names looking for a specific username.

The protocol was originally intended use was to serve a list of online users on a server, along with related user information; however, the specification architecture effectively just exchanges a query string provided by a client with a response string over TCP port 79. As a result, it is a very simple protocol to implement and generalize (even compared to other small net protocol). In addition, the original use case is generally ill-advised in the modern world as it provides the ability of anyone to perform username enumeration of internet-accessible servers.

Following my recent deployment of a Gemini server using systemd (a common utility that I have mostly avoided in the past), I was inspired to leverage the (arguably bloated) capabilities of the widespread service manager to create a little finger server, which I am dubbing my "pinkie finger server".

Three files and a dream

All that is required is three simple files, less than 30 lines total:

  1. A systemd socket unit (listens on port 79)
  2. A systemd service unit (hands connection to a binary)
  3. An executable server (reads query, writes response)

/etc/systemd/system/finger.socket (systemd socket):

[Unit]
Description=pinkie finger socket

[Socket]
ListenStream=79
Accept=yes

[Install]
WantedBy=sockets.target

/etc/systemd/system/finger@.service (systemd service):

[Unit]
Description=pinkie finger handler

[Service]
ExecStart=/opt/pinkie
StandardInput=socket
StandardOutput=socket
StandardError=journal
User=nobody

To build the executable at /opt/pinkie, we can first write the C code to ./main.c in any directory:

#include <stdio.h>

int main(void) {
  char query[512];
  fgets(query, sizeof(query), stdin);

  printf("Hello, World\n");
  return 0;
}

Then, we can compile it with gcc main.c -o /opt/pinkie.

To start the finger server, we just need to reload the daemon and enable the finger socket:

systemctl daemon-reload

then

systemctl enable --now finger.socket

Finally, we can use interact with the server using standard finger program:

finger [user, can be empty]@[host ip address or domain]

Or, netcat as a fallback:

printf "[user, can be empty]" | nc [host ip address or domain] 79

Installation script

To make things simpler (and easy to package for a git repository), I centralized the required files into one directory and wrote a simple installation script:

.
├── install.sh
├── README.md
├── src
│   └── main.c
└── units
    ├── finger@.service
    └── finger.socket

./install.sh:

#!/bin/bash
set -e

gcc src/main.c -o pinkie

install -m 755 pinkie /opt/pinkie
install -m 644 units/finger.socket /etc/systemd/system/
install -m 644 units/finger@.service /etc/systemd/system/

systemctl daemon-reload
systemctl enable --now finger.socket

echo "The \`pinkie\` finger server is now installed."

Making something interesting

With the framing provided by systemd, the executable server is provided the query string which can be read using fgets and is simply tasked with producing an output string to stdout; the only activity here is mapping the client's input to output.

The extreme simplicity of the finger protocol provides a sufficiently constrained environment to force creativity. Here are some of my favorite examples that I stumbled across:

Name Note Address
SDF Well known pubnix @sdf.org
Epoch's finger ring Small finger site aggregator ring@thebackupbox.net
fab's finger server Personal, yet detailed @redterminal.org
Happy Net Box Public finger server @happynetbox.com

Also, I would highly recommended reading about the (now defunct) CMU Coke Machine which was accessible with finger.


Last updated May 17, 2026