Skip to content

LegitCoconut/screenguard

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

screenguard

Capture intruder photos on failed authentication attempts — local login, sudo, GDM lock screen, SSH — and forward them to a Telegram bot, with timestamp (IST), hostname, Wi-Fi SSID, IP address, and PAM context (which user / which service / which TTY).

At screenguard configure time the tool scans /dev/video* and asks which cameras to use. Pick one, several, or all of them; every selected camera is captured on each event and the photos are bundled into a single Telegram message.

The whole thing runs from a self-contained Python venv at /opt/screenguard/ so it doesn't touch the system Python (PEP 668 friendly).

Features

  • PAM hook via pam_exec.so placed on the failure path of /etc/pam.d/common-auth. Successful logins never trigger a capture.
  • Interactive camera picker at install: any subset of /dev/video* works, including an IR sensor (the gray-format ffmpeg fallback is auto-applied when the camera kind is detected as ir).
  • Captures run in series via ffmpeg (~1 s per camera). Two cameras → ~2 s end-to-end.
  • Photos and metadata are written to /var/lib/screenguard/captures/. After a successful Telegram upload, photos are deleted and only meta.json is kept.
  • Offline-safe: if Telegram can't be reached, the bundle is retained and screenguard flush re-uploads everything later.
  • Trigger-side throttle (5 s default) so a typo-heavy sudo session doesn't spam the bot.
  • Idempotent installer + reversible uninstaller (PAM config is backed up before patching and restored on uninstall).

Requirements

  • Linux with v4l2 (/dev/video* devices)
  • Python 3.11+
  • python3-venv, ffmpeg, v4l-utils — installer apt-gets these for you
  • A Telegram bot and your own chat ID (@BotFather + getUpdates)

Install (system-wide, as root)

git clone https://github.com/legitcoconut/screenguard.git
cd screenguard
sudo ./install.sh

What install.sh does:

Target Purpose
/opt/screenguard/venv/ Python venv with the package + requests
/opt/screenguard/{install,uninstall}.sh, /opt/screenguard/scripts/ Kept for later uninstall
/usr/local/bin/screenguard Shell wrapper that execs the venv's entry point
/usr/local/sbin/screenguard-trigger Fast PAM hook (backgrounded capture)
/usr/local/share/man/man1/screenguard.1.gz man screenguard
/etc/screenguard/ Empty dir for config.toml (root 0700)
/var/lib/screenguard/captures/ Per-event bundles (root 0700)
/etc/pam.d/common-auth Patched; original kept at common-auth.screenguard.bak

Then configure and smoke-test:

sudo screenguard configure         # bot token, chat id, pick cameras (verifies token via getMe)
sudo screenguard test              # captures from all selected cameras + posts to your bot
man screenguard                    # full docs

configure shows a numbered list of detected cameras:

Available cameras:
  [1] /dev/video0  MJPG,YUYV   kind=rgb
  [2] /dev/video1  —           kind=unknown
  [3] /dev/video2  GREY        kind=ir
  [4] /dev/video3  —           kind=unknown

Select camera(s) — e.g. "1", "1,3", "1-3", "all":

Pick any subset. Every selected camera fires on each event; the photos go out as a single Telegram media-group message.

Verifying the PAM hook is live

In a fresh terminal:

sudo -k                            # clear sudo's cached auth
sudo true                          # then enter a WRONG password once

Within ~5 s a photo bundle should arrive in your bot chat with caption like:

screenguard ALERT: failed auth attempt
time: 01:59 AM IST, 21 May 2026
host: legitbook
wifi: VITC-HOS2-4
ip:   172.16.0.2
user: intern
svc:  sudo
tty:  /dev/pts/3

(tty and rhost may be blank for some services.)

Commands

screenguard configure          # interactive setup
screenguard test               # capture both cameras, post to Telegram
screenguard list               # show all /dev/video* devices + kind
screenguard capture [...]      # one capture+upload cycle (the trigger calls this)
screenguard flush              # retry uploads that failed earlier (offline)
screenguard status             # version, install kind, paths, queue length
screenguard help               # detailed help
screenguard uninstall          # delegates to /opt/screenguard/uninstall.sh under sudo
screenguard --version

Uninstall

sudo screenguard uninstall            # keeps /etc/screenguard and /var/lib/screenguard
sudo screenguard uninstall --purge    # also removes config + captures

This restores /etc/pam.d/common-auth from the backup taken at install time (falling back to a sentinel-strip if the backup was deleted), removes all installed files, and runs mandb to refresh the man index.

Dev / no-install workflow

If you just want to iterate without touching the system:

sudo apt install python3-venv
./setup.sh
source .venv/bin/activate
screenguard configure
screenguard test

The CLI auto-detects whether /etc/screenguard/ exists and routes config + data accordingly (/etc/screenguard/ + /var/lib/screenguard/ for system, ~/.config/screenguard/ + ~/.local/share/screenguard/ for dev).

How the PAM hook works (one-paragraph version)

install.sh runs scripts/pam-patch.py install, which:

  1. Saves a copy of /etc/pam.d/common-auth to common-auth.screenguard.bak.
  2. Bumps the success=N count on each pam_unix.so / pam_sss.so line by 1, so a successful authentication still jumps past pam_deny.so without touching our new module.
  3. Inserts a sentinel-marked block immediately before pam_deny.so:
# === BEGIN screenguard (managed; do not edit) ===
auth	[default=ignore]	pam_exec.so quiet seteuid /usr/local/sbin/screenguard-trigger
# === END screenguard ===

Because the line uses [default=ignore] and the trigger always exits 0, this hook can never block or delay authentication, even if the camera, network, or Telegram is broken.

The trigger script forks a detached screenguard capture and returns immediately (sub-millisecond), so the auth path is not stalled by the ~1–2 s ffmpeg + upload work.

Status & roadmap

  • CLI: configure, list, test, capture, flush, status, help, uninstall
  • Dual capture (RGB + IR) via ffmpeg
  • Telegram upload with hostname / Wi-Fi / IP / IST time / PAM context
  • Offline queue + flush
  • System install via venv, man page, idempotent PAM patch + reversible uninstall
  • NetworkManager dispatcher to auto-flush when Wi-Fi comes back
  • IR illuminator activation (laptop-specific; see howdy for prior art)
  • Rate limit / auto-prune of old bundles in /var/lib/screenguard/captures/

About

Capture intruder photos on failed authentication attempts

Topics

Resources

Stars

Watchers

Forks

Contributors