sshhh-lanchat logo

granth@lan:~/sshhh-lanchat

sshhh-lanchat: ephemeral encrypted terminal chat for your LAN

ephemeral encrypted chat for everyone on your Wi-Fi, in the terminal.

No server, no accounts, nothing on disk. Same room + same passphrase = same conversation, like a walkie-talkie channel. Close the window and it never happened.

install · macOS / Linux · Windows & more below
$ curl -fsSL https://raw.githubusercontent.com/granthgg/sshhh-lanchat/main/scripts/get.sh | sh

tip: someone reading over your shoulder? press Ctrl-B. it works on this page too. any key brings you back.

granth@lan · lanchat -r team -ask

simulation: the only color on this site lives in there, because -color is where the app spends its color too.

$ man lanchat

what it is

name

lanchat, the sshhh-lanchat client: ephemeral encrypted chat for the people on your Wi-Fi. (the “sshhh” is the instruction manual.)

description

Run it, and you’re in the room called lobby with everyone else on the network who ran it too. Add -r team -k coffee123 and only people with that exact room + passphrase can read a word. Everyone else on the wire sees encrypted noise.

It looks like log output on purpose: to a glance over your shoulder you’re reading build logs, and one keystroke makes that literally true. UDP is stateless, so nothing sent before you joined is visible and nothing survives after you quit. There is no history to search, leak, or subpoena.

synopsis

lanchat [-r room] [-k pass | -ask] [-color] [-stealth]

-r teampick a room (default: lobby)
-k … / -askmake it private: same passphrase, same room
-colora stable color per speaker
-stealthprompt looks like a plain shell

read the full manual → docs · every flag, command, key, and fix.

$ lanchat --help

what it does

Truly ephemeral

No logs, no history, no database. Close the window and the conversation never happened.

saved: nothing

No server, no accounts

Every copy is a peer. Nobody hosts the room, so nothing can go down or hand over records.

peers only

Encrypted on the wire

AES-256-GCM, key derived from room + passphrase. Wireshark sees only noise.

-k <phrase>

The boss key

Ctrl-B swaps the chat for fake build output. Held messages replay when you're back.

Ctrl-B · /boss

Looks like logs

Dim timestamps, right-aligned names. A glance over your shoulder reads “logs”, not “chat”.

by design

Stealth mode

A plain shell $ prompt, flat logger-style lines, and a bell that stays silent.

-stealth

One ~3 MB binary

Go with zero runtime dependencies. The crypto is the standard library.

go build

Terminal-native comfort

Tab completion, input history, bold mentions, a Dock-badging bell with /snooze.

Tab · /snooze

Built for messy Wi-Fi

Every interface + broadcast fallback, dedup, 20 s re-scans, VPN tunnels skipped.

resilient

install

macOS / Linux
$ curl -fsSL https://raw.githubusercontent.com/granthgg/sshhh-lanchat/main/scripts/get.sh | sh
Windows · PowerShell
$ irm https://raw.githubusercontent.com/granthgg/sshhh-lanchat/main/scripts/get.ps1 | iex

One paste: it fetches the right binary from the latest release, verifies its SHA-256 checksum, and puts lanchat on your PATH. No Go, no git, no build, and no SmartScreen or Gatekeeper popups.

what the script does

simulation: checksum verification is the part browser popups never gave you.

then just: lanchat and you’re in the lobby.
private room: lanchat -r team -ask

$ less docs/ARCHITECTURE.md

how it works

There is no host and no server. Every instance sends and receives on a UDP multicast group derived from the room name, and rooms are isolated by encryption, not by address: a wrong passphrase simply fails to decrypt.

what happens when you press Enter
you press Entera line of chat is born
sanitize + clampcontrol chars stripped · JSON ≤ 1200 B · a frame never fragments
AES-256-GCM sealkey = PBKDF2(room + passphrase) · 210k rounds
multicast on every interface+ a directed-broadcast copy per subnet
peers decrypt · dedup · printwrong passphrase? the packet is just noise
every datagram on the wire
┌ magic   "TC02" · 4 bytes
├ nonce   12 B · random per message
└ seal    AES-256-GCM ciphertext + tag
          without the key: just noise
  • nothing to keep running: join or leave any time; the room can’t go down
  • truly ephemeral: you only receive while you’re listening
  • tiny footprint: idle CPU ~0; TTL 1 keeps traffic on the segment
  • privacy on the wire: without the passphrase, ciphertext is all there is
real networks are messy · it copes
machine on Ethernet and Wi-Fimulticast is sent on every usable interface
office Wi-Fi filters multicasta directed-broadcast copy per subnet, deduped
AP roam · sleep-wake · new DHCPinterfaces re-scanned every 20 s, groups re-joined
an active VPN owns the routetunnels are skipped during auto-detection
flaky gear drops fragmentsframes are capped so they never fragment

wire format, package layout, threading model: docs/ARCHITECTURE.md

security model: read this

[ what it protects against ]

  • shoulder-surfing: the log-like format and the boss key exist for exactly this
  • passive sniffing of a private room: captured packets are unreadable without the passphrase
  • terminal injection: network text is stripped of control characters

[ what it does not do ]

  • open rooms are not private: no passphrase means the key derives from the room name alone; treat it as a public channel on that LAN
  • no identity: anyone with the passphrase can use any nickname
  • no forward secrecy, no signing: it’s a lightweight LAN toy, not Signal

don’t send anything you’d be unwilling to say out loud in the office. the startup banner always tells you whether the room is OPEN or PRIVATE.

sshhh-lanchat logosshhh-lanchat
creatorGranth Gaurav · github.com/granthgg · linkedin.com/in/granth-gauravsourcegithub.com/granthgg/sshhh-lanchatlicenseMIT © 2026 Granth Gauravbuilt withGo standard-library crypto · golang.org/x/{net, term, sys} · nothing else