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>
This commit is contained in:
Zebreus 2026-10-25 13:52:32 +01:00
commit 44a2d83ae6
5 changed files with 30 additions and 15 deletions

View file

@ -22,7 +22,8 @@ We only keep the basic user journey working.
- `cat README`, `cat README.en`, `cat CODE_OF_CONDUCT` and `cat CODE_OF_CONDUCT.en` always work. The four files
are always there and always regular text files.
- The website can log in: the key it uses is in `~/.ssh/authorized_keys`. That key gets access to the `root` user
only, never to the Administrator account, whose keys belong to the people who deploy.
only, never to the Administrator account. The keys of the people who deploy - their own key, not the key of the
website - are in the authorized_keys of both accounts.
Modifying the four files is allowed; the next cleanup undoes it. Deleting them is not permanent either.
@ -61,8 +62,9 @@ undoes that.
## This directory
- `home/` - the files that belong in the home directory of the user: `~/.zshrc`, `~/.zshenv` and the key in
`~/.ssh/authorized_keys` that the website logs in with. This is where they are edited.
- `home/` - the files that belong in the home directory of the user: `~/.zshrc`, `~/.zshenv` and the keys in
`~/.ssh/authorized_keys` - the one the website logs in with and the ones of the people who deploy. This is where
they are edited.
- `resources/` - the copies the cleanup restores from: the four text files and the files of `home/`.
- `scripts/make_files.py` - builds the resources.
- `scripts/deploy.sh` - deploys the cleanup to the server and installs it.
@ -78,10 +80,10 @@ The resources are built from the website's pages and the files of `home/`:
server/scripts/deploy.sh
The script logs in as `Administrator` - whose shell is a Windows one - copies the scripts and the resources to the
Administrator's home directory and runs the installer there. It logs in with the personal key of the deployer, from
the agent or from `-i`; the key of the website never gets administrator rights, it only logs in as the root user.
It checks the host key against the one the website pins, and checks that the key in `home/.ssh/authorized_keys` is
the one the website uses. `--uninstall` removes the task again.
Administrator's home directory and runs the installer there. It logs in with the personal key of the deployer,
`~/.ssh/id_ed25519` by default and `-i` for another one; the key of the website never gets administrator rights, it
only logs in as the root user. It checks the host key against the one the website pins, and checks that the key in
`home/.ssh/authorized_keys` is the one the website uses. `--uninstall` removes the task again.
The installer can also be run by hand, in an elevated PowerShell on the server:

View file

@ -1 +1,2 @@
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIJDweEH8bhZAHVaAedhTVDb2j/oMEn3vm97xCwCw9LC9 root@nowhere.wirs.ing cygwin-2222
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIIBTHzLm8QMhHIo7kFAvtAFnqpspeR3L3gM8kLoG1137 lennart@erms

View file

@ -1 +1,2 @@
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIJDweEH8bhZAHVaAedhTVDb2j/oMEn3vm97xCwCw9LC9 root@nowhere.wirs.ing cygwin-2222
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIIBTHzLm8QMhHIo7kFAvtAFnqpspeR3L3gM8kLoG1137 lennart@erms

View file

@ -6,13 +6,13 @@
# The job runs on the box as SYSTEM, never as the root user. The Administrator account sets it up; its shell is a
# Windows one, so the commands we run there are Windows commands.
#
# The Administrator logs in with the personal key of the deployer, from the agent or from -i. The key of the website
# never gets administrator rights: it only logs in as the root user.
# The Administrator logs in with the personal key of the deployer, by default ~/.ssh/id_ed25519. The key of the
# website never gets administrator rights: it only logs in as the root user.
set -euo pipefail
HOST=nowhere.wirs.ing
USER=Administrator
KEYFILE=''
KEYFILE="$HOME/.ssh/id_ed25519"
UNINSTALL=0
while [ $# -gt 0 ]; do
@ -27,9 +27,14 @@ done
repo=$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)
server="$repo/server"
remote='C:\Users\Administrator\kik' # where the installer is put, in the home of the Administrator
remotePath='/c/Users/Administrator/kik' # the same place, as the file transfer sees it
remotePath='/c/Users\Administrator\kik' # the same place, as the file transfer sees it
temporary=()
if [ ! -f "$KEYFILE" ]; then
echo "no key file for the login as $USER: $KEYFILE" >&2
exit 1
fi
# The host key is the one the website pins, so that the deployment cannot be intercepted.
expected=$(sed -n "s/.*const HOST_KEY = '\([^']*\)'.*/\1/p" "$repo/src/scripts/terminal.ts")
known=$(mktemp)
@ -49,14 +54,12 @@ temporary+=("$site")
boring=$(sed -n "s/.*const boringData = '\([^']*\)'.*/\1/p" "$repo/src/scripts/terminal.ts")
printf '%s' "$boring" | base64 -d | tr 'A-Za-z' 'N-ZA-Mn-za-m' > "$site"
public=$(ssh-keygen -y -f "$site" | awk 'NF {print $1" "$2}')
authorized=$(awk 'NF {print $1" "$2; exit}' "$server/resources/.ssh/authorized_keys")
if [ "$public" != "$authorized" ]; then
if ! awk 'NF {print $1" "$2}' "$server/resources/.ssh/authorized_keys" | grep -qxF "$public"; then
echo "the key in server/resources/.ssh/authorized_keys is not the one the website uses" >&2
exit 1
fi
options=(-o "UserKnownHostsFile=$known" -o StrictHostKeyChecking=yes)
if [ -n "$KEYFILE" ]; then options+=(-i "$KEYFILE"); fi
options=(-i "$KEYFILE" -o "UserKnownHostsFile=$known" -o StrictHostKeyChecking=yes)
ssh=(ssh "${options[@]}" "$USER@$HOST")
scp=(scp "${options[@]}")
@ -69,3 +72,9 @@ fi
"${ssh[@]}" "if not exist $remote mkdir $remote"
"${scp[@]}" -r "$server/scripts" "$server/resources" "$USER@$HOST:$remotePath/"
"${ssh[@]}" "powershell -NoProfile -ExecutionPolicy Bypass -File $remote\\scripts\\install_restore_task.ps1"
# The Administrator logs in with the key of the deployer, so that it is there after every deployment.
keyline=$(ssh-keygen -y -f "$KEYFILE")
blob=$(echo "$keyline" | awk 'NF {print $2}')
"${ssh[@]}" "if not exist C:\\Users\\Administrator\\.ssh mkdir C:\\Users\\Administrator\\.ssh"
"${ssh[@]}" "findstr /c:\"$blob\" C:\\Users\\Administrator\\.ssh\\authorized_keys >nul 2>&1 || echo $keyline >> C:\\Users\\Administrator\\.ssh\\authorized_keys"

View file

@ -4,9 +4,11 @@ REM home of the root user. Run it as Administrator on the box, for example over
REM back by itself from then on.
setlocal EnableDelayedExpansion
set KEY=ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIJDweEH8bhZAHVaAedhTVDb2j/oMEn3vm97xCwCw9LC9 root@nowhere.wirs.ing cygwin-2222
set OWN=ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIIBTHzLm8QMhHIo7kFAvtAFnqpspeR3L3gM8kLoG1137 lennart@erms
if not exist C:\msys2\home\root\.ssh mkdir C:\msys2\home\root\.ssh
> C:\msys2\home\root\.ssh\authorized_keys echo %KEY%
echo %OWN% >> C:\msys2\home\root\.ssh\authorized_keys
REM The user owns their .ssh, so that they can add keys of their own.
for /f "tokens=5" %%i in ('findstr /b "root:" C:\msys2\etc\passwd') do set SID=%%i