- parseProxyConfig handles PAC 'HTTPS host:port' (tls.connect + CONNECT inside TLS) in both the CONNECT and plain-HTTP handlers — ports live fix d8b9db2 into the repo - CONNECT: split tunnel establishment into establishDirect / sendConnectToProxy, removing the duplicate DIRECT 'connect' listener that raced onUpstreamData - env-overridable PROFILE_FILE / REMOTES_FILE / PAC_DIR (test hermeticity) - tests: +DIRECT echo exactly-once, +HTTPS upstream via local PAC dir + self-signed TLS stub (no internet needed); 8/8 pass
57 lines
3.9 KiB
Markdown
57 lines
3.9 KiB
Markdown
# Proxy Bridge — Live-State Baseline
|
|
|
|
Captured 2026-09-23 before restructuring work (canonical repo = ~/gists/scripts/proxy, deploy target = /opt/proxy-bridge). All values observed, none invented.
|
|
|
|
## Service
|
|
|
|
- systemd user service: `proxy-bridge.service`, state **active**
|
|
- Unit file: `~/.config/systemd/user/proxy-bridge.service`
|
|
- ExecStart: `/home/tke/.nvm/versions/node/v20.20.2/bin/node /opt/proxy-bridge/bridge.js`
|
|
- Restart=on-failure, RestartSec=5, WantedBy=default.target
|
|
- Last service start: 2026-09-22 13:24 (PID 4638), prior start 2026-09-16 16:05 (after the HTTPS-fix commit d8b9db2)
|
|
|
|
## Port → profile map (from startup log lines, 2026-09-22 boot)
|
|
|
|
| Port | Profile | Type |
|
|
|-------|-------------|----------|
|
|
| 8888 | dynamic | special |
|
|
| 8889 | internet | builtin |
|
|
| 8890 | direct | builtin |
|
|
| 8891 | off | builtin |
|
|
| 8892 | proxy-inet | PAC |
|
|
| 8893 | proxy-tke | PAC |
|
|
| 8894 | proxy-wan | PAC |
|
|
|
|
ss confirms 8888-8894 all listening on 127.0.0.1. Map shifts if PAC files in `~/.mozilla/*.pac` are added/removed — re-derive from startup lines on every restart.
|
|
|
|
## Live config files in /opt/proxy-bridge (runtime, not committed there — profile.json is the only dirty file)
|
|
|
|
- config.json: `{enabled: true, host: "proxy-inet.certbw.org", port: "8080"}`
|
|
- profile.json: `{profile: "proxy-tke"}` (dirty in /opt git — runtime state, fs-watched)
|
|
- user.json: `{username: "<present, redacted>"}` — password is NOT here, it's in the keyring
|
|
- overrides.json: 5 rules (turtle.ktf.ninja→internet, ai.int.auf.bundeswehr.de→proxy-wan, api.anthropic.com→off, vault.lockedshields.de→internet, irt-docker.csocbw.org→direct)
|
|
- remotes.json: 1 entry (wanbw → proxy-wan PAC URL)
|
|
|
|
## Code divergence (the reason for Task 1)
|
|
|
|
- /opt bridge.js (deployed, 19,018 B, HEAD d8b9db2): HAS PAC `HTTPS host:port` support — `const tls = require('tls')`, HTTPS branch in parseProxyConfig, TLS-wrap around CONNECT. Fixes 2026-09-16 502-on-PAC-routes (proxy-inet:8081).
|
|
- gists bridge.js (dev, 17,999 B, uncommitted +59/-10): LACKS the HTTPS fix; HAS new socket-lifecycle hardening (fragmented CONNECT header buffering, head-forward on PROXY, close/error handling, keepalive/nodelay, truncated-response propagation, large-body streaming).
|
|
- Live journal confirms active use of the HTTPS path: `connect port=8888 profile="dynamic" ... upstream="HTTPS proxy-inet.certbw.org:8081"`. Deploying the unmerged gists copy would regress this immediately.
|
|
|
|
## Known bug in the uncommitted gists copy
|
|
|
|
DIRECT-mode CONNECT establishes the tunnel twice: shared `onUpstreamData` else-branch (~lines 415-422) AND a DIRECT-only `'connect'` listener (~lines 427-435) both write `200 Connection Established` and call `pipe()`. `connected` flag prevents double-execution, but the logic races and head-forwarding differs between paths. Task 1 fixes this with a single owner.
|
|
|
|
## Credential handling today (pre-Task-2)
|
|
|
|
- Username: user.json; password: keyring via `secret-tool lookup service proxy-bridge account <user>` — never stored in JSON.
|
|
- `refreshAuth()` runs once at startup; AUTH_HEADER cached for process life.
|
|
- 407 responses pass through unexamined; no backoff, no invalidation, no re-verification, no missing-cred guard beyond `if (AUTH_HEADER)`.
|
|
- Lockout risk: if the keyring password expires, every PROXY/HTTPS request retries the stale credential indefinitely until manual intervention.
|
|
|
|
## Environment
|
|
|
|
- Node /opt runtime: v20.20.2 via nvm; `node --test` works against the gists copy (6/6 tests pass as of baseline).
|
|
- No outbound internet from this sandbox; all tests must use local stub servers (net/http/tls on 127.0.0.1).
|
|
- Legacy scripts present in gists scripts/proxy/: `install_proxy.sh`, `update_apt_proxy.sh`, `update_bashrc_proxy.sh`, `update_service_proxy.sh`, `get_proxy.sh` — all embed username+password into apt config, bashrc exports (~/.http_proxy), snap and systemd drop-ins. To be retired by Task 4/5.
|