fix(ssh): per-challenge SSH login + phew buffering/leak/timeout
Passwords failed on 10/16 challenges while state.json looked correct:
- only the 6 native GEMASTIK XVIII images provision 'ctfuser'; every imported
XVI/XVII image does 'echo root:${PASSWORD} | chpasswd' and logs in as root.
set_ssh_passwords() hardcoded ctfuser, so chpasswd set a password on an
account nobody uses -> 'Permission denied' everywhere.
Registry gains a per-challenge 'ssh_user'; chpasswd now targets the real
login (and ctfuser/ctf when present) and reports failures loudly.
- phew checker: chall.py block-buffers stdout through the docker exec pipe
(PYTHONUNBUFFERED now set) and leaks chall.py inside the container on
timeout (26 orphans, container saturated) -> reaps the whole exec process
group. Startup does a fresh Pailier keygen (~12 s) so crypto reads need
_CRYPTO_TIMEOUT, not the 5 s prompt default.
Adds panel/verify_ssh_creds.py (proves the state->container binding from
inside via a real login), audit_ssh_users.sh, reset_runtime.sh.
This commit is contained in:
1 parent
ef385c3397
commit
ae50acfe40
33 files changed
+1398
-289
No files matched your search
Executable
+35
@@ -0,0 +1,35 @@
|
||||
#!/usr/bin/env bash
|
||||
# Fleet health check: per-team container count vs registry enabled count,
|
||||
# per-team receiver systemd state, and host disk. Read-only, safe to run any time.
|
||||
set -uo pipefail
|
||||
cd /opt/gemastik18-final/panel
|
||||
|
||||
EXPECTED=$(python3 -c "
|
||||
import sys; sys.path.insert(0,'.')
|
||||
import teams
|
||||
print(len(teams.enabled_challenges()))
|
||||
")
|
||||
TEAMS=$(ls -d /opt/gemastik18-final/teams/team* 2>/dev/null | sed 's/.*team//' | sort -n)
|
||||
echo "enabled challenges: $EXPECTED"
|
||||
echo "teams: ${TEAMS:-none}"
|
||||
echo
|
||||
|
||||
for i in $TEAMS; do
|
||||
up=$(docker ps --format '{{.Names}}' | grep -c "_container_team${i}\$" || true)
|
||||
all=$(docker ps -a --format '{{.Names}}' | grep -c "_container_team${i}\$" || true)
|
||||
recv=$(systemctl is-active "gemastik-receiver-team${i}.service" 2>/dev/null || echo none)
|
||||
label=$(python3 -c "import json;print(json.load(open('/opt/gemastik18-final/teams/team${i}/state.json'))['label'])" 2>/dev/null)
|
||||
echo "team${i} (${label}) up=${up}/${EXPECTED} total_ctr=${all} receiver=${recv}"
|
||||
if [ "$up" != "$EXPECTED" ]; then
|
||||
echo " missing: $(python3 - <<PY
|
||||
import sys; sys.path.insert(0,'.')
|
||||
import json, subprocess, teams
|
||||
want={c['name'] for c in teams.enabled_challenges()}
|
||||
have={n.split('_container_team${i}')[0] for n in subprocess.run(['docker','ps','--format','{{.Names}}'],capture_output=True,text=True).stdout.split() if n.endswith('_container_team${i}')}
|
||||
print(' '.join(sorted(want-have)) or '-')
|
||||
PY
|
||||
)"
|
||||
fi
|
||||
done
|
||||
echo
|
||||
df -h / | tail -1
|
||||
Reference in new issue
Block a user