# Runbook: us4 forward proxy — client configuration ## Purpose Configure a client (curl, environment variables, browser, or a proxy-switching extension) to use the authenticated HTTPS forward proxies on `us4.wsvc.info`, and triage the three failures seen in practice: `407` responses, pages that load incompletely, and clients that cannot speak TLS to a proxy. ## Scope - Applicable: the two authenticated HTTPS forward proxies on `us4.wsvc.info` (`:6443` sing-box, `:443` nghttpx → Squid). - Applicable: curl, `https_proxy`/`HTTPS_PROXY` environment variables, browser proxy-switching extensions (Zero Omega / SwitchyOmega), and OS proxy settings. - Not applicable: server-side proxy health — use [proxy-health.md](proxy-health.md). - Not applicable: changing proxy, Traefik, or firewall configuration — use [network-change.md](network-change.md) with a change record. - Not applicable: WireGuard client setup. ## Ownership - Owner: personal ops (Windy) - Last reviewed: 2026-09-26 - Related systems: us4 (`/opt/sing-box`, `/opt/nghttpx`, `/opt/traefik`) ## Safety ### Non-negotiable rules - Never put the proxy credential in this repository, in Plane, or in a shell command that lands in shell history on a shared host. - Read it from its server-side source only: `ssh -4 windy@us4.wsvc.info 'sudo cat /opt/sing-box/.proxy-password'`. - Never "fix" a client problem by removing proxy authentication or by publishing the backend port. ### Stop conditions - The client sends no `Proxy-Authorization` and the server answers `407`: that is the server behaving correctly. `STOP` — fix the client, do not change the server. - A plaintext HTTP request to either port is answered by Traefik with `404`: the client is not speaking TLS to the proxy. `STOP` and change the client's proxy protocol; do not add a plaintext entrypoint. - A known-good curl command from [proxy-health.md](proxy-health.md) Step 4 also fails: `STOP` and run the health runbook — the fault is server-side. ## Endpoint facts | | `:6443` (sing-box) | `:443` (nghttpx → Squid) | |---|---|---| | Proxy type to the proxy | **HTTPS / TLS** | **HTTPS / TLS** | | Username | `windy` | `windy` | | Credential source | `/opt/sing-box/.proxy-password` (server-side, mode 0600) | operator password manager; server holds a bcrypt hash | | CONNECT (`https://` targets) | yes | yes | | Absolute-URI (`http://` targets) | yes | **no** — nghttpx answers `400` | Both endpoints terminate TLS in Traefik. The client's proxy type is therefore HTTPS (TLS to the proxy), not "HTTP proxy on port 6443". ## Client configuration ### curl ```bash PW=$(ssh -4 windy@us4.wsvc.info 'sudo cat /opt/sing-box/.proxy-password') curl -sS --proxy https://us4.wsvc.info:6443 --proxy-user "windy:$PW" https://ipinfo.io/ip # expected: 185.201.226.122 ``` ### Environment variables curl prefers the **lowercase** `https_proxy` over `HTTPS_PROXY`; a pre-existing lowercase value wins even when the uppercase one is overridden. On the WSL client both are pre-set to the LAN proxy `http://192.168.66.99:7890`, so overriding only `HTTPS_PROXY` silently keeps using the LAN proxy (observed: returns `152.175.29.59` instead of us4's `185.201.226.122`). Set the lowercase variable, or pass `--proxy` explicitly. ```bash https_proxy="https://windy:$PW@us4.wsvc.info:6443" curl -sS https://ipinfo.io/ip ``` ### Browser proxy-switching extension (Zero Omega / SwitchyOmega) 1. Proxy profile: protocol **HTTPS**, server `us4.wsvc.info`, port `6443`, username `windy`, password from the server-side file. Save **and** click *Apply changes* — an unapplied profile is ignored. 2. Routing conditions must cover every hostname the site needs, not only the landing domain. For `x.com` that means `x.com`, `twitter.com`, `api.x.com`, `t.co`, `twimg.com`, `abs.twimg.com`, `pbs.twimg.com`, `video.twimg.com`. Missing CDN domains are the usual cause of a page that loads incompletely. 3. Set `chrome://flags/#enable-quic` to **Disabled** if individual resources stall: QUIC is UDP and cannot traverse a CONNECT proxy. 4. Watch the server side while the browser loads the page: ```bash ssh -4 windy@us4.wsvc.info "docker logs -f sing-box" | grep --line-buffered 'inbound connection to' ``` ## Troubleshooting ### A — `407 Proxy Authentication Required` Server log on us4: `authentication failed, no Proxy-Authorization header` — the client connected but sent no credentials (extension profile missing the username/password, or not applied). Add them and re-apply. `authentication failed, incorrect password` instead means the value itself is wrong; re-read it from `/opt/sing-box/.proxy-password`. ### B — Page loads but is incomplete Some hostnames are not routed through the proxy (see the condition list above), or QUIC is stalling. Confirm with the live log: if the site's CDN hosts never appear as an `inbound connection to` line, they are not being proxied at all. ### C — Client cannot speak TLS to a proxy `python3 urllib` and `wget` treat an `https://` proxy as a plaintext HTTP proxy. The request reaches Traefik in cleartext and is answered `404 Not Found` (observed: `Tunnel connection failed: 404 Not Found`). Use curl, or a client that supports HTTPS proxies. ### D — `400 Bad Request` on the `:443` endpoint The `:443` path is CONNECT-only. Absolute-URI plain-HTTP proxying is available only on `:6443`. ## Final Verification - `curl --proxy https://us4.wsvc.info:6443 --proxy-user "windy:" https://ipinfo.io/ip` returns `185.201.226.122`. - The browser loads the target site completely, and each expected CDN host appears in the sing-box log as an `inbound connection to` line. - No credential was written to the repository, Plane, or a shared transcript. ## References - [proxy-health.md](proxy-health.md) — read-only server-side health check - [hosts/us4.wsvc.info.md](../hosts/us4.wsvc.info.md) — endpoint and credential facts - [network-change.md](network-change.md), [rollback.md](rollback.md) - Plane VPS-99 (proxy deployment), VPS-100 (root disk recovery)