fix: add dsh-web restart-persistent authentication
- Add capture-dsh-token.sh script that captures the dsh-web launch token - Add login endpoint (/dsh-web-login on :8081) that mints 30-day auth cookie - Document the authentication flow in zulip-health.prose.md (Platform B4) - Cookie is authority-bound to 127.0.0.1:3080 with 30-day expiry - After first login, subsequent requests use the cookie — no token required
This commit is contained in:
Executable
+77
@@ -0,0 +1,77 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# capture-dsh-token.sh — start dsh-web, capture its token, update nginx
|
||||||
|
# Run on CT112 (tankodhs.sysloggh.net)
|
||||||
|
# This script:
|
||||||
|
# 1. Restarts the dsh-web service
|
||||||
|
# 2. Captures the token URL from the journal
|
||||||
|
# 3. Extracts the token value
|
||||||
|
# 4. Writes the token to /etc/dsh-web/launch-token
|
||||||
|
# 5. Creates an nginx config that exposes a /dsh-web-login endpoint
|
||||||
|
# 6. Reloads nginx
|
||||||
|
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
# Kill any existing dsh-web instance first
|
||||||
|
systemctl stop dsh-web 2>/dev/null || true
|
||||||
|
sleep 2
|
||||||
|
|
||||||
|
# Record the time we started the service (for --since filter)
|
||||||
|
START_TIME="$(date -u +%Y-%m-%dT%H:%M:%SZ)"
|
||||||
|
|
||||||
|
# Start dsh-web
|
||||||
|
systemctl start dsh-web
|
||||||
|
|
||||||
|
# Wait for the token to appear in the journal (up to 30 seconds)
|
||||||
|
TOKEN=""
|
||||||
|
for i in {1..30}; do
|
||||||
|
TOKEN=$(journalctl -u dsh-web.service --since "$START_TIME" --output=cat 2>/dev/null | grep -m1 "dsh web: http://" | grep -oP "(?<=dsh web: )(https?://[^ ]+)" | head -1 || true)
|
||||||
|
if [ -n "$TOKEN" ]; then
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
sleep 1
|
||||||
|
done
|
||||||
|
|
||||||
|
if [ -z "$TOKEN" ]; then
|
||||||
|
echo "ERROR: token not captured within 30s" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Extract the token value (everything after "?token=")
|
||||||
|
TOKEN_VALUE=$(echo "$TOKEN" | grep -oP "(?<=token=)[^ ]+")
|
||||||
|
|
||||||
|
# Write the token to a file
|
||||||
|
mkdir -p /etc/dsh-web
|
||||||
|
echo "$TOKEN_VALUE" > /etc/dsh-web/launch-token
|
||||||
|
echo "Captured token: $TOKEN_VALUE"
|
||||||
|
|
||||||
|
# Create the nginx config with the token (using printf to control expansion)
|
||||||
|
{
|
||||||
|
printf "server {\n"
|
||||||
|
printf " listen 8081;\n"
|
||||||
|
printf " server_name _;\n"
|
||||||
|
printf " \n"
|
||||||
|
printf " location /dsh-web-login {\n"
|
||||||
|
printf " proxy_pass http://127.0.0.1:3080/?token=%s;\n" "$TOKEN_VALUE"
|
||||||
|
printf " proxy_http_version 1.1;\n"
|
||||||
|
printf " proxy_set_header Host 127.0.0.1:3080;\n"
|
||||||
|
printf " proxy_set_header X-Real-IP \$remote_addr;\n"
|
||||||
|
printf " proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;\n"
|
||||||
|
printf " }\n"
|
||||||
|
printf " \n"
|
||||||
|
printf " location / {\n"
|
||||||
|
printf " proxy_pass http://127.0.0.1:3080;\n"
|
||||||
|
printf " proxy_http_version 1.1;\n"
|
||||||
|
printf " proxy_set_header Host 127.0.0.1:3080;\n"
|
||||||
|
printf " proxy_set_header X-Real-IP \$remote_addr;\n"
|
||||||
|
printf " proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;\n"
|
||||||
|
printf " }\n"
|
||||||
|
printf "}\n"
|
||||||
|
} > /etc/nginx/sites-enabled/dsh.token
|
||||||
|
|
||||||
|
# Reload nginx
|
||||||
|
nginx -t && /usr/sbin/nginx -s reload || {
|
||||||
|
echo "ERROR: failed to reload nginx" >&2
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
echo "Token captured and nginx reloaded"
|
||||||
@@ -260,6 +260,43 @@ logged/reported as a warning — reported, never healed on.
|
|||||||
| `dsh-web` service not `active` | Restart Tanko via DSH service |
|
| `dsh-web` service not `active` | Restart Tanko via DSH service |
|
||||||
| HTTP `:3080` connection refused/timeout (`000`) | Same as above |
|
| HTTP `:3080` connection refused/timeout (`000`) | Same as above |
|
||||||
| HTTP status outside the expected set | Log/report as a warning — reported, never healed on |
|
| HTTP status outside the expected set | Log/report as a warning — reported, never healed on |
|
||||||
|
**B4: dsh-web Authentication (Tanko — restart-persistent login)**
|
||||||
|
|
||||||
|
The dsh-web UI is token-gated. Each dsh-web process generates a unique
|
||||||
|
launch token printed to the journal at startup. The token is used to mint
|
||||||
|
a 30-day authentication cookie. After the first authenticated login,
|
||||||
|
subsequent requests use the cookie — no token required.
|
||||||
|
|
||||||
|
**Login endpoint**: `http://127.0.0.1:8081/dsh-web-login` (inside CT 112)
|
||||||
|
|
||||||
|
**Token capture script**: `/opt/deepseek-harness/capture-dsh-token.sh` (CT 112)
|
||||||
|
|
||||||
|
The script:
|
||||||
|
1. Restarts the dsh-web service
|
||||||
|
2. Captures the token URL from the journal
|
||||||
|
3. Extracts the token value
|
||||||
|
4. Writes the token to `/etc/dsh-web/launch-token`
|
||||||
|
5. Creates an nginx config that exposes the `/dsh-web-login` endpoint on port 8081
|
||||||
|
6. Reloads nginx
|
||||||
|
|
||||||
|
**Authentication flow**:
|
||||||
|
1. Access `http://127.0.0.1:8081/dsh-web-login` → 303 redirect
|
||||||
|
2. The redirect includes a `Set-Cookie` header with the `dsh-auth-*` cookie
|
||||||
|
3. The cookie has a 30-day expiry and is authority-bound to `127.0.0.1:3080`
|
||||||
|
4. Subsequent requests to `http://127.0.0.1:3080/` use the cookie for authentication
|
||||||
|
5. After 30 days, the cookie expires and a new token exchange is required
|
||||||
|
|
||||||
|
**Verification**:
|
||||||
|
```bash
|
||||||
|
# Check if the login endpoint is working:
|
||||||
|
ssh root@192.168.68.15 "pct exec 112 -- curl -s -o /dev/null -w '%{http_code}' http://127.0.0.1:8081/dsh-web-login"
|
||||||
|
# Expected: 303
|
||||||
|
|
||||||
|
# Check if the cookie works:
|
||||||
|
ssh root@192.168.68.15 "pct exec 112 -- curl -s -o /dev/null -w '%{http_code}' -b 'dsh-auth-*' http://127.0.0.1:3080/"
|
||||||
|
# Expected: 200 (after the cookie has been set)
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
### Step 4: Platform C — Agent Zero (kagentz, CT 105 via Docker host .14)
|
### Step 4: Platform C — Agent Zero (kagentz, CT 105 via Docker host .14)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user