pmb 54650af252 Only track bannable (globally-routable) source IPs
The ban logic is per source IP, so it only works where the daemon can see
the real client. Behind Docker's default bridge networking every client is
SNAT'd to the bridge gateway (a 172.16/12 address), so a single IP would
stand in for the whole internet -- counting offenses against it would block
everyone at once.

Add is_bannable_address(): only globally-routable unicast addresses are
tracked. Loopback, RFC1918 private, CGNAT (100.64/10), link-local, IPv6
unique-local, and multicast all return false. main.cpp decides trackability
from the accepted endpoint and skips both the block check and offense
recording for non-global sources. Net effect: banning works where the real
IP is visible (FreeBSD jail via pf rdr; Docker with host networking) and is
inert -- not catastrophic -- where it is not (Docker bridge).

Document the Docker client-IP caveat: docker-compose.yml now defaults to
host networking, with the rationale and alternatives in DOCKER.md.
2026-06-15 16:38:07 -07:00
2025-07-02 17:11:31 -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%