The resources were copied from home/ and admin/, which held the same
files a second time. Everything that goes to the server is in resources/
now, and the generator only writes the four text files.
Co-Authored-By: Claude Code <noreply@anthropic.com>
The keys of the people who deploy are in the repository now: in home/ for
the root user and in admin/ for the Administrator. The resources mirror
both home directories, and the deploy script no longer reads any private
key.
Co-Authored-By: Claude Code <noreply@anthropic.com>
The personal key of the deployer goes into the authorized_keys of the
root user together with the key of the website, and the deployment makes
sure it is in the authorized_keys of the Administrator.
Co-Authored-By: Claude Code <noreply@anthropic.com>
The key that the website logs in with was written into the authorized_keys
of the Administrator, which would have given everyone who has the website
administrator rights on the box. It only gets access as the root user.
The deploy script logs in as Administrator with the personal key of the
deployer instead, from the agent or from -i.
Co-Authored-By: Claude Code <noreply@anthropic.com>
The key that the website logs in with lives in the home directory of the
user, so a deleted home directory took it away and the site could not
connect any more. The key is now one of the copies the cleanup restores,
and it is merged into the authorized_keys of the user, so that keys they
added stay.
The installer writes the same key for the Administrator, and the deploy
script checks that it is the key the website uses.
Co-Authored-By: Claude Code <noreply@anthropic.com>
It logs in as Administrator, whose shell is a Windows one, copies the
scripts and the resources to the server and runs the installer there. It
uses the key the website uses and checks the host key against the one
the website pins.
Co-Authored-By: Claude Code <noreply@anthropic.com>
The shell configuration was copied from the server by hand. It now has
its own directory, which make_files.py copies into the resources, so
that the resources are the whole set of files the cleanup restores and
nothing has to be copied by hand.
Co-Authored-By: Claude Code <noreply@anthropic.com>
The cleanup job now restores the whole home directory instead of only
the four text files: the directory itself, the shell configuration that
gives the prompt, and the files. Anything that is not a regular file is
replaced, so the files stay text files.
The README in server/ describes the security model: the box is a
disposable VPS that may be compromised, the root user may do whatever
they want, and only the prompt, the home directory and the four files
are kept working.
Co-Authored-By: Claude Code <noreply@anthropic.com>
The README and Code of Conduct files move to server/resources, the
scripts that build and deploy them to server/scripts. The new
install_restore_task.ps1 installs a scheduled task as SYSTEM that puts
the files back every 30 minutes, so the shell server's root user can
neither stop it nor change the copies it restores from.
Co-Authored-By: Claude Code <noreply@anthropic.com>
The terminal versions of the pages for the home directory of the shell
server's root user, so each page's top command (cat README, cat README.en,
cat CODE_OF_CONDUCT, cat CODE_OF_CONDUCT.en) works in the web terminal.
Generated by server/make_files.py.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
- OSC 8 hyperlinks and plain URLs are clickable on the screen and in the
page history. Links to a section of the current page scroll there,
others open in a new tab. Links show their target on hover and invert
in their own color, like the page's links.
- The terminal fills the page column (the fit addon kept room for a
hidden scrollbar).
- Lines in the page history sit exactly on the terminal's cell grid,
also for wide and fallback-font characters, and no longer wrap.
- The first command is sent as soon as the shell's line editor is ready,
instead of guessing from a pause in its output.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
The build is flat (pages, loader.js, terminal.js, logo.png) and only uses
relative URLs, so the site works wherever it is hosted, e.g. at
https://berlin.ccc.de/kik/.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
The glow used to be green for all text, including red or blue terminal
output. The explicit red glows are no longer needed.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Lines scrolling off the terminal screen are converted from xterm.js's
cells to styled page text: palette, 256 and true colors, background,
bold (bright), italic, dim, underline, strikethrough, inverse and
invisible, without trailing spaces and keeping empty lines.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
The key is no longer served as public/root_key. It is stored as base64
of its rot13 and decoded where the connection is made.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
The bottom prompt is now a real text input. Sending the first command
lazy-loads an xterm.js terminal that continues right below it and
connects to wss://web.nowhere.wirs.ing with a minimal in-browser SSH
client (curve25519, strict kex, pinned ed25519 host key,
chacha20-poly1305, re-keying) using public/root_key.
The page is the scrollback: lines scrolling off the window-sized
terminal screen become page text, the screen grows with the lines in
use, and the wheel scrolls the page except in full-screen apps.
Typing anywhere on the page goes to the prompt, later to the terminal.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>