Files
tke 0b8c5001fc fix(proxy): port HTTPS-upstream TLS-wrap from deployed bridge; unify CONNECT establishment
- 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
2026-09-23 14:49:07 +02:00

3.9 KiB

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.