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:
- A systemd socket unit (listens on port 79)
- A systemd service unit (hands connection to a binary)
- 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