waffle2k dcbcff98a6
CI / Build and Test (gcc, g++, ubuntu-latest) (push) Failing after 31s
CI / Code Coverage (push) Skipped
Build and Publish Docker Image / build-and-test (push) Failing after 1m7s
Build and Publish Docker Image / build-and-push-image (push) Skipped
Build and Publish Docker Image / security-scan (push) Skipped
Add Rust port of the finger daemon
Tokio-based reimplementation in rust/, mirroring the C++ handler and
ban-tracker logic (directory-traversal checks, case-insensitive plan
lookup, rolling-window IP ban tracking, allowlist parsing) along with
its full test suite. Includes a matching multi-stage Dockerfile.
2026-07-23 21:24:55 -07:00
2025-07-02 17:11:31 -07:00
2026-07-23 21:24:55 -07:00
2025-07-02 17:11:31 -07:00
2025-06-25 17:25:50 -07:00
2025-06-25 17:37:15 -07:00

finger

CI codecov

A silly finger service written in c++20

Compiling:

meson setup builddir
meson compile -C builddir

This will create a static linked binary called builddir/finger. You can copy this to your remote server if you're going to run it via docker.

Building a Dockerfile

Create a Dockerfile with the contents:

# Use a minimal base image
FROM alpine:latest

# Copy the local binary to the container
COPY finger /usr/local/bin/finger

# Make the binary executable
RUN chmod +x /usr/local/bin/finger

# Create the directory for user data
RUN mkdir -p /var/finger/users

# Expose port 79 (finger protocol)
EXPOSE 79

# Set the binary as the default command
CMD ["finger"]

And execute docker build -t finger-app .

Running

Create a docker-compose.yml file:

version: '3.8'

services:
  finger:
    build: .
    ports:
      - "79:79"
    volumes:
      - ./users:/var/finger/users
    restart: unless-stopped

and execute docker compose up -d

Setting your status

within the ./users directory, create a file named after the user you wish to have a response. That's it!

Abuse protection

Most traffic on port 79 is not finger at all -- HTTP and SIP probes, TLS handshakes, and username-guessing scanners. None of these resolve to a plan file, so the daemon treats any request that fails to read a plan as an "offense" and timestamps it against the source IP. When an IP records more than 3 failures within a rolling 24-hour window, its connections are dropped (without being read or answered) until those failures age back out of the window. Legitimate lookups that hit a real plan never count against an IP. All state is in-memory; thresholds live in BanTracker::Config (ban.hpp).

S
Description
No description provided
Readme
98 KiB
Languages
C++ 50.2%
Rust 43.2%
Dockerfile 4.2%
Meson 2.1%
Shell 0.3%