Commit graph

42 commits

Author SHA1 Message Date
Zebreus
f4113033ac Start the server again when the cleanup job's start was dropped
The task that runs the server ignores a start while it thinks it is still
running, so the cleanup job could stop the server and then fail to start it
again: the site had no shell for forty minutes. The start is now tried three
times, with the processes of the task killed in between.

The job now only counts the established connections when it decides whether
anybody is connected - the server leaves the processes of finished sessions
behind, and they kept it from ever restarting the server. Those processes are
killed with the server, because they hold the runtime and the protected
programs open.

The pacman calls are bounded, so a database lock cannot keep the server down,
and they run before the server is stopped. The exit code of a program started
this way is only available when its handle is taken while it runs, and the
pattern for the files to overwrite has to be quoted, or the runtime expands
it.

Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-10-27 20:36:52 +01:00
Zebreus
5f9796cc11 Keep the shell server working over a deployment
The server logs to a file that was overwritten on every start, so an outage left no
trace. It is appended to now, and rotated when it grows past a megabyte.

The cleanup job restarts the server when nobody is connected and when the server does
not listen at all: it comes back by itself if it died, it takes over a server that was
left behind, and it picks up the programs that were just restored. A session that is
open keeps the port and the runtime, so the server is not restarted then.

A deployment does not restart the server. It runs in a session, and that session keeps
the port, so a server that starts during a deployment cannot bind it. The deployment
only writes the configuration; the cleanup job applies it.

The runtime of the installation is not protected any more. A program and the shell
that starts it have to use the same runtime DLL, or the program does not run at all,
so the login path now uses the one in /usr/bin, next to the user's own programs. What
is protected instead is that it is the one the package says it is: pacman checks the
files of msys2-runtime and the cleanup job puts the package back if it was changed.

Only keys may log in over SSH now, and Remote Desktop needs network level
authentication. Only the administrator may log in over it: the user of the website is
in no group that may.

Co-Authored-By: Claude Opus <noreply@anthropic.com>
2026-10-27 02:46:45 +01:00
Zebreus
b228fec07e Let the shell user install packages with pacman
The root user now owns the whole MSYS2 installation and can run pacman. The
login path the journey depends on - the sshd, the login shell zsh and cat - is
kept as a protected copy in C:\msys2\opt\kik that only SYSTEM and the
administrators may write, and the sshd runs as SYSTEM from there (the new
KiK sshd task; the msys2-sshd service is disabled). Replacing the user's own
/usr/bin/sshd therefore cannot touch the running server.

opt/kik is two levels below C:\msys2, so its runtime resolves the same
installation root and the login shell and the user's tools share one cygwin
runtime. A separate second installation does not work: two runtimes in one
process tree corrupt each other's file descriptors and pacman cannot lock its
database.

/etc/passwd and /etc/ssh are read-only to the user, /opt/kik is first on PATH
so cat README survives even if the user deletes their own /usr/bin/cat, and
the restore task rebuilds the protected copy and re-applies the permissions
every 30 minutes.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-10-25 21:37:55 +01:00
Zebreus
ea0d6a85fd Let the user change the texts again after they made them read-only
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-25 15:37:58 +01:00
Zebreus
49c61b6b91 Keep the shell configuration and the key out of the user's reach
The user could empty the authorized_keys and break the login of the
website, change the shell configuration to break the prompt, and write
startup files that zsh reads on every login. The shell configuration and
the key are now read-only for the user, and the shell reads its
configuration from ~/.zsh, so the files in the home directory are
ignored.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-25 15:26:01 +01:00
Zebreus
e4050cbf05 Adjust server readme 2026-10-25 15:17:31 +01:00
Zebreus
bc7cb26b61 Keep the home directory and the files in it from being deleted
The user could delete the whole home directory, which takes the website
down with it: sshd cannot log in without it. The home directory and the
files that have to stay in it now belong to the administrators, so the
user may change them but not remove them. Their own files stay theirs.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-25 15:04:48 +01:00
Zebreus
c498ce1d52 Copy MSYS2's default files into a recreated home
MSYS2 only copies /etc/skel into a home directory that does not exist yet
when the user logs in. The cleanup always creates the home first, so the
default files never arrived.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-25 14:38:35 +01:00
Zebreus
c96357c83a Drop the directory listing from the README
Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-10-25 14:06:21 +01:00
Zebreus
eec4e359ea Drop the recovery section from the README
Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-10-25 14:05:54 +01:00
Zebreus
85d345bac2 Trim the README of the shell server
Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-10-25 14:05:27 +01:00
Zebreus
a86a3c7b47 Drop the one-time recovery script
The deployment restores the keys as well, so the script is not needed
anymore.

Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-10-25 14:03:21 +01:00
Zebreus
fd1e379fcf Keep the files for the server in one directory
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>
2026-10-25 14:01:27 +01:00
Zebreus
a17b2d76dc Check in the keys for both accounts
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>
2026-10-25 13:58:05 +01:00
Zebreus
44a2d83ae6 Install the key of the deployer for both accounts
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>
2026-10-25 13:52:32 +01:00
Zebreus
fc7b75b930 Keep the key of the website away from the Administrator account
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>
2026-10-25 13:50:40 +01:00
Zebreus
ac98212fa2 Fix the parentheses in the recovery script
Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-10-25 13:42:21 +01:00
Zebreus
758fc0b828 Give the user their .ssh directory back in the recovery script
Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-10-25 13:35:29 +01:00
Zebreus
22106dcd7d Restore the SSH access in the cleanup
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>
2026-10-25 13:35:05 +01:00
Zebreus
e48e0644ba Add a deploy script for the cleanup job
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>
2026-10-25 13:17:13 +01:00
Zebreus
917e3d6089 Build the shell configuration into the resources
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>
2026-10-25 13:05:22 +01:00
Zebreus
23896bced5 Keep the shell server's basic user journey working
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>
2026-10-25 13:02:25 +01:00
Zebreus
54607982cf Sort the server directory and add the restore task installer
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>
2026-10-25 12:47:26 +01:00
Zebreus
996cc53e56 Add the shell server's README and Code of Conduct files
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>
2026-10-25 03:04:12 +01:00
Zebreus
4d6900ccf9 Ship styles.css unminified
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-25 02:44:41 +01:00
Zebreus
cfab5962e4 Put the styles in a separate styles.css
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-25 02:41:43 +01:00
Zebreus
aed4af0868 Clickable links, full-width terminal and exact page history
- 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>
2026-10-25 02:36:28 +01:00
Zebreus
f106ffe22d Use relative URLs and fixed script names
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>
2026-10-25 02:36:28 +01:00
Zebreus
986d35376e Let text glow in its own color
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>
2026-10-25 02:01:21 +02:00
Zebreus
7e1f995e7e Keep the prompt's block cursor while it is focused
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-25 02:01:21 +02:00
Zebreus
fc250b31b6 Keep colors and styles of lines moved into the page
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>
2026-10-25 02:01:21 +02:00
Zebreus
3c61a3c419 Match the page prompts to the server prompt
All of the prompt is in the normal green now, except the blue ~.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-25 01:08:58 +02:00
Zebreus
d718172c23 Embed the login key in the terminal script
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>
2026-10-25 01:08:58 +02:00
Zebreus
83e25907a8 Connect the bottom prompt to the shared SSH server
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>
2026-10-25 00:58:38 +02:00
Zebreus
a36da4af6f Add root ssh key 2026-10-24 22:37:54 +02:00
Zebreus
93ee2a943e Port to astro 2026-10-24 22:37:39 +02:00
Zebreus
a701743635 Note not accessible 2026-10-23 04:50:10 +02:00
Zebreus
46c913a614 Remove accessibility info 2026-10-23 04:42:19 +02:00
Zebreus
a922a10303 Fix links on the english version 2026-10-23 01:40:45 +02:00
Zebreus
c5f94fbcd6 Fix links on index html 2026-10-23 01:28:15 +02:00
Zebreus
ffc57a88e4 Replace weird dashes with - 2026-10-23 01:22:50 +02:00
April John
87140ccce3 first commit 2026-10-19 02:01:45 +02:00