Tool · Free download

webtarpit

Point a tunnel at this listener. When a scanner throws a dictionary of URIs at the host, webtarpit asks an OpenAI-compatible model to invent a matching static HTML page, stores it, and serves it again next time. Several Host names on one listener. Optional per-device sites follow a client across IP changes without JavaScript. Generation is rate-capped; auto-update is off unless you opt in.

SHA-256  1a4ed604ea21b2e6063e513da0b56b90b16579a1d3ecad91f1c7eec737dd67ca · checksum file

Static pages only

Markup is sanitized before it is stored. Scripts, event handlers, forms, and iframes are stripped. A Content-Security-Policy header blocks scripts on the response. Each URI gets its own document (About is not the home page at a new path). Decoy mailto: addresses are planted for harvesters.

Vhosts and devices

One process, many Host names — each with its own topic and mode. per-device keys the invented site on a passive HTTP fingerprint (header order, User-Agent, Accept*, Client Hints) plus optional HttpOnly cookie and ETag. Same device, new IP, same fiction. No JavaScript on generated pages.

Your model

Talks to any OpenAI-compatible chat API: Ollama, Open WebUI, LiteLLM. LiteLLM (and other keyed proxies) take api_key, api_key_file, or WEBTARPIT_API_KEY / LITELLM_API_KEY. Set a topic string if you want the fiction to stay on-theme.

Auto-update (opt-in)

Off by default. Pin this tarball in production. Opt in with --auto-update or auto_update: true: then serve fetches version.json over HTTPS, verifies SHA-256, pip-installs, and restarts. --no-auto-update is the explicit default-safe flag. One-shot: webtarpit update.

Install

One-liner (asks where to install, systemd/cron/none, which user, config now vs later, auto-update on/off). Prompts use the terminal even under curl | bash. If the install path is not writable (for example /opt/webtarpit) it asks to continue with sudo instead of dying on mkdir: Permission denied. After sudo, the default run-as user is you (the sudo invoker), not a new webtarpit system account — creating that account is what hung on some Debian hosts. Kill any stopped webtarpit-install process (Ctrl-Z / T+ in ps) before re-running; those hold the passwd lock.

curl -fsSL https://tacticaldataconcepts.com/tools/webtarpit/install.sh | bash

Manual venv — activate it (or call .venv/bin/webtarpit) so the command is on PATH. The tarball includes a sample YAML; after install, webtarpit sample-config writes it.

python3 -m venv .venv
.venv/bin/pip install webtarpit-0.7.1.tar.gz
source .venv/bin/activate
webtarpit sample-config --out webtarpit.yaml
# edit webtarpit.yaml (bind, port, openai_base, model, api_key, topic)
webtarpit --config webtarpit.yaml serve
webtarpit report

Bind 0.0.0.0 so a Cloudflare Tunnel (or other proxy on the LAN) can reach the origin. Access log lives under the config data: directory (installer default /opt/webtarpit/data/access.jsonl). Run webtarpit report from the install prefix or pass --config /opt/webtarpit/webtarpit.yaml. Caps: max_gens_per_min, max_pages_per_tenant. Per-domain extra instructions: prompt: under domains:.

# one-time dictionary
webtarpit pregenerate --paths-file paths.txt --mode shared

MIT license. Operate webtarpit only on hosts you own or are authorized to run.