fix: address P0/P1/P2 audit findings — security, reliability, CI, docs
P0 - Critical: - config.py: add _mask() credential-redaction helper, SETTINGS_SCHEMA_VERSION, plaintext-storage warning; corrupt settings.json backed up before defaults - gost_util.py: pin SHA256 for gost_3.2.6_windows_amd64.zip; verify before extraction; _add_defender_exclusion now logs warning on failure - firewall.py: add emergency_disengage() for atexit/signal use - service.py: register fw_emergency_disengage via atexit + SIGTERM/SIGINT; stop() calls emergency_disengage if thread hangs past 15s timeout - app.py: wrap main() in top-level except with CTk error dialog + log - LICENSE: add MIT license file P1 - Important: - app.py: switch to RotatingFileHandler (5 MB / 3 backups) - config.py: settings_version + migrate(); save_settings() writes .bak before overwrite; _is_safe_https_url() strips RFC-1918 sources/ip_check_url - service.py: threading.Lock on _settings; _signal_handler; graceful stop - requirements.txt: pin exact versions; add cryptography==48.0.0 - .gitignore: add settings.json, credential JSON files, screenshot noise - tray.py, dns_leak.py, gost_util.py: replace bare except:pass with logging - CHANGELOG.md: document all session changes P2 - Nice to have: - .github/workflows/test.yml: CI on Python 3.10/3.11/3.12 windows-latest - run.py: --version / -V flag - docs/OPERATOR_RUNBOOK.md: emergency disengage, proxy leak, GOST, settings Tests: 47/47 passed (python -m unittest discover -s tests -v) Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
193
docs/AUDIT_FINDINGS.md
Normal file
193
docs/AUDIT_FINDINGS.md
Normal file
@@ -0,0 +1,193 @@
|
||||
# Proxy God — Audit Findings
|
||||
|
||||
**Audit date:** 2026-05-21
|
||||
**Scope:** Production-readiness gaps, README cross-check, automated tests
|
||||
**Tests run:** `python -m unittest discover -s tests -v` → **47 passed**, 0 failed (~25s)
|
||||
|
||||
---
|
||||
|
||||
## Executive Summary
|
||||
|
||||
| Category | P0 | P1 | P2 | Total |
|
||||
|----------|----|----|-----|-------|
|
||||
| **Production readiness gaps** (this pass) | 15 | 46 | 16 | **77** |
|
||||
| Critical bugs (separate bug-hunt pass) | — | — | — | *pending / parallel* |
|
||||
|
||||
**Test status:** Core pure-logic modules are covered (config, leak_detect, validator timing, chain_map, browser persona). No automated tests touch `service.py`, `firewall.py`, `gost_util.py`, `sysproxy.py`, or `app.py`.
|
||||
|
||||
**Top 5 P0 production blockers**
|
||||
|
||||
1. **No CI/CD** — nothing runs tests or build on push/tag (`requirements.txt:1-4`, no `.github/workflows` / `.gitea/workflows`).
|
||||
2. **No code signing** — release `.exe` is unsigned (`ProxyChainManager.spec:70-71`).
|
||||
3. **Secrets at rest in plaintext** — proxy credentials and signup passwords in `%LOCALAPPDATA%\ProxyChainManager\` JSON (`config.py:364-368`, `signup_prep.py:295-296`).
|
||||
4. **GOST binary integrity not verified** — runtime download with zip magic check only, no SHA256/signature pin (`gost_util.py:17-65`).
|
||||
5. **Kill-switch recovery gap** — outbound BLOCK can persist if process dies mid-run; no standalone recovery tool documented (`firewall.py:142-156`, `service.py:136-143`).
|
||||
|
||||
---
|
||||
|
||||
## Production Readiness Gaps
|
||||
|
||||
### Infrastructure
|
||||
|
||||
| # | What's missing | Why it matters for prod | Suggested fix | Priority |
|
||||
|---|----------------|-------------------------|---------------|----------|
|
||||
| I-1 | **No CI/CD pipeline** (no GitHub/Gitea workflow YAML in repo) | Regressions ship silently; no reproducible build gate | Add workflow: `pip install -r requirements.txt`, `unittest discover`, optional `pyinstaller` on tag | **P0** |
|
||||
| I-2 | **No automated test gate on PR/merge** | CONTRIBUTING.md says “run tests” but nothing enforces it (`CONTRIBUTING.md:9`) | Fail CI if `python -m unittest discover -s tests` fails | **P0** |
|
||||
| I-3 | **No dependency lockfile** (`requirements.txt` uses `>=` only) | Non-reproducible builds across machines/time | Generate `requirements.lock` or pin exact versions in release branch | **P1** |
|
||||
| I-4 | **PyInstaller not pinned** — installed ad hoc in `scripts/setup_and_build.ps1:39` | Release binaries differ per builder Python/PyInstaller version | Pin `pyinstaller==x.y.z` in dev requirements; record in release notes | **P1** |
|
||||
| I-5 | **No release automation** — `docs/RELEASE_PROCESS.md` is manual checklist only | SHA256/commit attachment steps are skipped in practice | Script: build → hash → attach to Gitea release with commit SHA | **P1** |
|
||||
| I-6 | **No pre-commit / secret scanning** | Risk of committing proxy creds or signup JSON from dev machines | `gitleaks` or similar in CI + pre-commit | **P1** |
|
||||
| I-7 | **No documented required env vars** — `MAINTENANCE.md:22` asks for them but none exist | Operators cannot configure corporate proxy, custom data dir, etc. | Document optional `LOCALAPPDATA` override pattern or explicit env contract | **P2** |
|
||||
| I-8 | **Stewardship checklists are templates only** — all items unchecked in `docs/SECURITY_REVIEW.md`, `docs/PROVENANCE_CHECKLIST.md` | Release gate in docs is never enforced | Complete checklists per release or automate in CI | **P1** |
|
||||
|
||||
### Reliability
|
||||
|
||||
| # | What's missing | Why it matters for prod | Suggested fix | Priority |
|
||||
|---|----------------|-------------------------|---------------|----------|
|
||||
| R-1 | **Kill-switch may remain engaged after abnormal exit** — `fw_disengage()` only on `stop()` / `_close()` (`service.py:136-143`, `app.py:2877-2886`) | Crashed/killed process leaves `netsh` outbound BLOCK → machine appears “offline” | `atexit` + signal handlers; ship `scripts/disengage_kill_switch.ps1`; detect orphan rules at startup | **P0** |
|
||||
| R-2 | **GOST download without checksum/signature** (`gost_util.py:49-61`) | Supply-chain compromise or CDN swap replaces `gost.exe` | Pin release URL + publish SHA256; verify before extract; optional minisign | **P0** |
|
||||
| R-3 | **No settings schema version / migration** — `load_settings()` merges unknown keys silently (`config.py:329-361`) | Upgrades break or drop fields; no upgrade path for operators | Add `settings_version`; migration functions per version | **P1** |
|
||||
| R-4 | **Corrupt `settings.json` silently reverts to defaults** (`config.py:335-336`) | Operator loses pinned chain/credentials without warning | On parse failure: backup corrupt file, surface UI error, offer restore | **P1** |
|
||||
| R-5 | **`update_settings()` while service thread running** — no lock around `_settings` (`service.py:112-114`, `349+`) | Race: health interval / pool refresh reads half-written settings | `threading.Lock` on settings read/write or restart service on save | **P1** |
|
||||
| R-6 | **No offline / degraded mode** — empty pool sleeps 60s and retries (`service.py:402` area) | Air-gapped or CDN-down hosts spin with no cached pool | Persist last-good pool snapshot; UI banner “offline, using cache” | **P1** |
|
||||
| R-7 | **ChainService thread is daemon** (`service.py:131-133`) | Process exit can abort mid-teardown (proxy/firewall left dirty) | Non-daemon thread + bounded shutdown protocol | **P1** |
|
||||
| R-8 | **`stop()` join timeout 15s only** (`service.py:140-141`) | Hung GOST/async loop leaves firewall engaged | Force-kill GOST after timeout; always call `fw_disengage()` in `finally` | **P0** |
|
||||
| R-9 | **Global `ThreadPoolExecutor`s never shut down** (`service.py:64`, `pool_ops.py:15`) | Interpreter shutdown warnings; resource leaks in long-running tray sessions | `shutdown(wait=False)` on app exit | **P2** |
|
||||
| R-10 | **No GOST process watchdog** — if GOST dies, behavior depends on loop branch | Silent proxy outage until next health check | Detect `proc.poll()`; restart or rotate immediately | **P1** |
|
||||
| R-11 | **Logon scheduled task runs LIMITED** (`windows_task.py:47-48`) | Auto-start cannot engage kill-switch / MAC / HKLM fixes that need Admin | Document “task ≠ full enforcement”; optional elevated task with warning | **P1** |
|
||||
| R-12 | **No backup/restore for operator data** | Reinstall or profile wipe loses chains and signup vault | Export/import ZIP of `%LOCALAPPDATA%\ProxyChainManager\` | **P2** |
|
||||
| R-13 | **No rollback to prior release** | Bad build bricks operators | Keep previous `ProxyChainManager.exe` + settings backup; versioned releases | **P1** |
|
||||
|
||||
### Security
|
||||
|
||||
| # | What's missing | Why it matters for prod | Suggested fix | Priority |
|
||||
|---|----------------|-------------------------|---------------|----------|
|
||||
| S-1 | **Plaintext `settings.json`** with embedded proxy auth (`config.py:364-368`, `asdict` stores URLs) | Disk theft = credential leak | DPAPI-encrypt sensitive fields or Windows credential locker | **P0** |
|
||||
| S-2 | **Plaintext signup vault** — `signup_draft.json`, `signup_accounts.json` (`signup_prep.py:252-296`) | Passwords/emails readable by any local user/process | Encrypt at rest; redact in logs (partially done for proxy URLs only) | **P0** |
|
||||
| S-3 | **No TLS/certificate pinning for feed URLs** (`fetcher.py:11-18`) | MITM on jsdivr/GitHub could inject malicious proxy list | Pin certs or use signed offline bundle for sources | **P2** |
|
||||
| S-4 | **Broad Defender exclusion** on entire GOST folder (`gost_util.py:23-39`) | AV blind spot if folder is poisoned | Exclude only `gost.exe`; verify hash before exclusion | **P1** |
|
||||
| S-5 | **`ip_check_url` and custom `sources` not URL-validated** (`config.py:338-340`) | Hand-edited JSON could point health checks at internal/metadata endpoints | Allowlist HTTPS hosts; block RFC1918/link-local in validator | **P1** |
|
||||
| S-6 | **Kill-switch default ON** (`config.py:186`) without mandatory recovery docs in README | Bricked network for non-technical operators | README “emergency disengage” + startup orphan detection | **P0** |
|
||||
| S-7 | **Always-elevated PyInstaller build** (`ProxyChainManager.spec:72` `uac_admin=True`) | Every launch prompts UAC; users may habit-click; not least-privilege | Split “Operator” vs “Enforcer” binaries or manifest optional elevation | **P1** |
|
||||
| S-8 | **Signup autofill extension** writes config into Firefox profile (`signup_prep.py:334+`) | Local profile theft exposes generated credentials | Document threat model; optional OS-level profile encryption | **P1** |
|
||||
| S-9 | **No rate limiting on outbound validation fan-out** (default concurrency 64, `config.py:179`) | Can trigger abuse flags on ipify/jsdelivr/proxy sources | Cap per-host concurrency; exponential backoff on 429 | **P1** |
|
||||
| S-10 | **No secrets rotation story** | Long-lived proxy passwords in JSON never expire | Export reminder; credential field rotation UX | **P2** |
|
||||
|
||||
### Observability
|
||||
|
||||
| # | What's missing | Why it matters for prod | Suggested fix | Priority |
|
||||
|---|----------------|-------------------------|---------------|----------|
|
||||
| O-1 | **`proxy_chain_manager.log` has no rotation** (`app.py:91-98`) — unlike `gost.log` (`gost_util.py:98-105`) | Long sessions fill disk | `RotatingFileHandler` or size cap like GOST | **P1** |
|
||||
| O-2 | **No crash reporting** (WER hook, Sentry, minidump) | Field failures are invisible to maintainer | Opt-in crash telemetry with redaction | **P1** |
|
||||
| O-3 | **Unstructured text logs only** | Hard to query in SIEM | Optional JSON log format for file handler | **P2** |
|
||||
| O-4 | **No metrics** (Prometheus/windows perf counters) | Cannot alert on pool size, rotation rate, leak count | Export counters via named pipe or local HTTP if needed | **P2** |
|
||||
| O-5 | **No external health endpoint** | Expected for server apps; desktop app has tray only — gap if headless automation desired | Document N/A for GUI; optional `127.0.0.1:status` for scripting | **P2** |
|
||||
| O-6 | **Broad `except Exception: pass` in Defender helper** (`gost_util.py:38-39`) | Silent failure to exclude → GOST quarantined with no UI clue | Log warning + surface in Live tab | **P1** |
|
||||
| O-7 | **UI event queue unbounded** (`app.py:200`) | Log flood can grow memory | `queue.Queue(maxsize=N)` with drop-oldest policy | **P2** |
|
||||
|
||||
### Distribution
|
||||
|
||||
| # | What's missing | Why it matters for prod | Suggested fix | Priority |
|
||||
|---|----------------|-------------------------|---------------|----------|
|
||||
| D-1 | **No Authenticode signing** (`ProxyChainManager.spec:70-71` `codesign_identity=None`) | SmartScreen blocks; enterprise deployment blocked | Sign with cert; document thumbprint in release | **P0** |
|
||||
| D-2 | **No SHA256 publish step in build script** — required by `docs/RELEASE_PROCESS.md:10` but `setup_and_build.ps1` only copies exe | Users cannot verify download integrity | Emit `ProxyChainManager.exe.sha256` in `dist/` | **P1** |
|
||||
| D-3 | **UPX compression enabled** (`ProxyChainManager.spec:66-67`) | AV false positives on packed binaries | Disable UPX for release builds | **P1** |
|
||||
| D-4 | **GOST not shipped in installer** — downloaded on first run (`gost_util.py:42-65`) | First-run requires internet; air-gap fails | Bundle pinned `gost.exe` in installer or optional offline pack | **P1** |
|
||||
| D-5 | **No MSI/Inno installer** — only raw exe + Desktop copy (`setup_and_build.ps1:55-58`) | No uninstaller, no Start Menu integration, no upgrade path | Wrap in signed installer with upgrade code | **P2** |
|
||||
| D-6 | **No in-app auto-update channel** | Security patches require manual git pull / rebuild | Check release API + signed delta or full exe | **P1** |
|
||||
| D-7 | **Version `1.0.0` static** (`__init__.py:3`) — not embedded in Windows file properties | Support cannot map exe → commit | PyInstaller `version` resource from git tag | **P1** |
|
||||
| D-8 | **No reproducible build manifest** (SBOM) | Supply-chain audits fail | `pip freeze` + GOST hash in release notes | **P1** |
|
||||
|
||||
### Documentation
|
||||
|
||||
| # | What's missing | Why it matters for prod | Suggested fix | Priority |
|
||||
|---|----------------|-------------------------|---------------|----------|
|
||||
| DOC-1 | **No LICENSE file** — `LICENSE_STATUS.md:3-9` says “all rights reserved” | Cannot legally redistribute or accept external contributions | Choose SPDX license; add `LICENSE` | **P0** |
|
||||
| DOC-2 | **README omits production realities** — no mention of: unsigned exe, first-run GOST download, Defender exclusion, kill-switch recovery (`README.md:69-114`) | Operators misconfigure or panic when network dies | Add “Production deployment” section | **P1** |
|
||||
| DOC-3 | **README test claim understates gaps** — “Covers config… smoke paths” (`README.md:124`) but no service/firewall/GUI tests | False confidence in release quality | Align README with actual test matrix | **P1** |
|
||||
| DOC-4 | **`CHANGELOG.md` Unreleased empty** (`CHANGELOG.md:5-7`) | No user-visible record between tags | Require changelog entry in PR template | **P1** |
|
||||
| DOC-5 | **No `THIRD_PARTY_NOTICES.md`** for GOST, CustomTkinter, Pystray, Proxifly data | License compliance for binary distribution | Generate notices from `pip licenses` + GOST MIT | **P1** |
|
||||
| DOC-6 | **No operator runbook** (kill-switch stuck, proxy leak, pool empty) | MTTR high in field | `docs/RUNBOOK.md` with netsh recovery steps | **P0** |
|
||||
| DOC-7 | **“Mission-grade” / “fail closed” marketing without SLOs** (`README.md:5-12`) | Enterprise buyers expect defined behavior | Add limitations: public proxy quality, VPN requirement, admin scope | **P2** |
|
||||
| DOC-8 | **`docs/MAINTENANCE.md` rate-limit note** (`MAINTENANCE.md:23`) not reflected in product | Release gate incomplete | Implement S-9 or remove claim | **P1** |
|
||||
|
||||
### Testing
|
||||
|
||||
| # | What's missing | Why it matters for prod | Suggested fix | Priority |
|
||||
|---|----------------|-------------------------|---------------|----------|
|
||||
| T-1 | **No CI executing test suite** | 47 tests only run manually | Wire I-1 to `unittest discover` | **P0** |
|
||||
| T-2 | **Zero tests for `service.py`, `firewall.py`, `gost_util.py`, `sysproxy.py`** | Core runtime unverified | Mock subprocess/netsh; test engage/disengage, settings races | **P0** |
|
||||
| T-3 | **No tests for `load_settings` / `save_settings` round-trip** | Regression on migration/sanitize | Add `TestSettingsPersistence` with temp dir | **P1** |
|
||||
| T-4 | **No frozen-bundle path tests** — `_MEIPASS` branches in `signup_prep.py:21-22`, `chain_map.py:50-51` | PyInstaller regressions break map/signup | Test with `sys.frozen` monkeypatch | **P1** |
|
||||
| T-5 | **No GUI smoke tests** (`app.py` ~2900 lines) | UI regressions ship every release | Minimal `pytest-qt` or screenshot smoke on CI Windows runner | **P1** |
|
||||
| T-6 | **No `compileall` / lint in pipeline** | Syntax errors in rarely-imported modules | Add `python -m compileall proxy_chain_manager` to CI | **P1** |
|
||||
| T-7 | **`TestFetcher.test_fetch_smoke` network-dependent** (`tests/test_proxy_god.py`) | CI flakiness offline | Mark `@unittest.skipUnless` or mock httpx | **P2** |
|
||||
| T-8 | **No coverage threshold** | Unknown untested lines | `coverage run` + fail under 60% on core modules | **P2** |
|
||||
|
||||
### Compliance / Legal
|
||||
|
||||
| # | What's missing | Why it matters for prod | Suggested fix | Priority |
|
||||
|---|----------------|-------------------------|---------------|----------|
|
||||
| C-1 | **No SPDX license on repository** (`LICENSE_STATUS.md`) | Blocks open-source and commercial redistribution | Legal review → add `LICENSE` | **P0** |
|
||||
| C-2 | **GOST upstream license not bundled in release artifact** | Binary distribution obligation | Include go-gost LICENSE in installer | **P1** |
|
||||
| C-3 | **Signup presets target third-party ToS** (`signup_prep.py:37-164`) | Automation/autofill may violate site policies | Disclaimer in UI; operator assumes liability | **P1** |
|
||||
| C-4 | **Provenance checklist incomplete** (`docs/PROVENANCE_CHECKLIST.md` all `[ ]`) | `docs/ROADMAP.md:14` blocks “first verified release” | Complete before v1.0 tag | **P1** |
|
||||
| C-5 | **No privacy notice for local JSON stores** | GDPR-style transparency if EU operators | Short privacy section: what is stored where | **P1** |
|
||||
|
||||
### Operator Experience
|
||||
|
||||
| # | What's missing | Why it matters for prod | Suggested fix | Priority |
|
||||
|---|----------------|-------------------------|---------------|----------|
|
||||
| OP-1 | **No emergency kill-switch disengage UX** — must know netsh or restart app elevated (`firewall.py:149-156`) | #1 support incident when chain crashes | Tray item “Disengage firewall”; standalone script | **P0** |
|
||||
| OP-2 | **“Run as Admin” relaunch closes app** (`app.py:347-350`) | Loses unsaved UI state; confusing flow | Relaunch with `--elevate` handoff file | **P1** |
|
||||
| OP-3 | **Kill-switch skipped silently when non-admin** (`service.py:328-330`) | User believes they are “fail closed” but are not | Prominent banner when not admin + kill-switch ON | **P1** |
|
||||
| OP-4 | **No settings export/import** | Machine migration painful | JSON export with optional encryption | **P2** |
|
||||
| OP-5 | **No first-run wizard** (GOST download, VPN check, admin recommendation) | High abandonment on first failure | Step-through: VPN → Admin → Test pool | **P1** |
|
||||
| OP-6 | **Close button minimizes to tray only** (`app.py:2888`) — good for daemon, bad if user expects quit | Document; tray “Exit” must disengage FW | Already in tray; add tooltip on X | **P2** |
|
||||
| OP-7 | **README says “Accept UAC” but spec forces `uac_admin`** (`README.md:131`, `ProxyChainManager.spec:72`) | Confusing for non-admin workflows | Document two launch modes | **P1** |
|
||||
| OP-8 | **No visible “version / build commit” in UI** | Support tickets lack context | Show `__version__` + git SHA in About | **P1** |
|
||||
| OP-9 | **Pool refresh hammers external CDNs** (default 1800s, 3 sources) | Operator IP banned from jsdivr | Backoff; custom mirror field | **P1** |
|
||||
| OP-10 | **Ban tester / leak audit results not persisted** | Cannot trend ban rate over sessions | Optional CSV export | **P2** |
|
||||
|
||||
---
|
||||
|
||||
## README Claims vs Implementation
|
||||
|
||||
| README claim | Status | Evidence |
|
||||
|--------------|--------|----------|
|
||||
| “Self-healing… rotate on failure, repeat forever” | **Partial** | Rotation exists (`service.py` main loop); no GOST watchdog (R-10) |
|
||||
| “Fail closed” kill-switch | **Partial** | Requires Admin (`service.py:328-330`); orphan rules possible (R-1) |
|
||||
| “Python not required” for exe | **OK** | PyInstaller one-file build (`ProxyChainManager.spec`) |
|
||||
| “Works with or without VPN” | **OK** | `leak_detect.py` VPN-aware modes; tested |
|
||||
| “Validation / tests” coverage | **Overstated** | 47 unit tests; no service/firewall/GUI (T-2, DOC-3) |
|
||||
| Default kill-switch ON | **OK** | `config.py:186` |
|
||||
| VM-safe loopback `127.0.0.1` | **OK** | `config.py:22-24`, `normalize_listen_host` |
|
||||
| Build via `setup_and_build.ps1` | **OK** | Script exists; no signing/checksum (D-1, D-2) |
|
||||
| Tray red/yellow/green | **OK** | `tray.py`, `app.py` status handlers |
|
||||
| QUIC disabled where needed | **Verify manually** | Browser/sysproxy paths — not covered by unit tests |
|
||||
|
||||
---
|
||||
|
||||
## Test Run Notes (2026-05-21)
|
||||
|
||||
```
|
||||
Ran 47 tests in ~25s — OK
|
||||
```
|
||||
|
||||
**Modules with tests:** `config`, `leak_detect`, `validator`, `fetcher` (network smoke), `leak_audit`, `privacy_lan`, `browser_identity`, `chain_map`, `exit_intel`.
|
||||
|
||||
**Modules without tests:** `app`, `service`, `gost_util`, `firewall`, `sysproxy`, `tray`, `ban_tester`, `dns_leak`, `webrtc_check`, `fingerprint`, `artifact_wipe`, `windows_task`, `browser_launcher`, `signup_prep` (integration).
|
||||
|
||||
---
|
||||
|
||||
## Recommended Fix Priority (production)
|
||||
|
||||
| Priority | Focus |
|
||||
|----------|--------|
|
||||
| **P0** | CI + tests (I-1, T-1), code signing (D-1), secrets at rest (S-1, S-2), GOST integrity (R-2), kill-switch recovery (R-1, R-8, OP-1, DOC-6), LICENSE (C-1, DOC-1) |
|
||||
| **P1** | Lockfiles, migrations, runbooks, README honesty, integration tests, rate limits, log rotation, third-party notices |
|
||||
| **P2** | Metrics, installer, backup/restore, coverage gates, TLS pinning |
|
||||
|
||||
---
|
||||
|
||||
*Bug-hunt findings (critical bugs, edge cases, UI issues) may be appended by a separate audit pass under sections 2–8 above.*
|
||||
119
docs/OPERATOR_RUNBOOK.md
Normal file
119
docs/OPERATOR_RUNBOOK.md
Normal file
@@ -0,0 +1,119 @@
|
||||
# Proxy God — Operator Runbook
|
||||
|
||||
**Version:** 1.0
|
||||
**Last updated:** 2026-05-21
|
||||
|
||||
---
|
||||
|
||||
## Emergency: Firewall Kill-Switch Stuck (Network Appears Offline)
|
||||
|
||||
If the application crashes or is force-killed while the kill-switch is engaged,
|
||||
outbound traffic will remain blocked. Follow these steps to restore connectivity.
|
||||
|
||||
### Option 1 — Run the standalone disengage script (fastest)
|
||||
|
||||
Open an **elevated** (Run as Administrator) PowerShell terminal and run:
|
||||
|
||||
```powershell
|
||||
# Remove all PCM_ firewall rules
|
||||
netsh advfirewall firewall delete rule name=all
|
||||
# Restore default outbound policy
|
||||
netsh advfirewall set allprofiles firewallpolicy blockinbound,allowoutbound
|
||||
```
|
||||
|
||||
### Option 2 — Restart the application elevated
|
||||
|
||||
1. Right-click `ProxyChainManager.exe` → **Run as administrator**.
|
||||
2. The application detects orphan firewall rules on startup and removes them.
|
||||
3. Click **Stop** if the service does not start, to force disengage.
|
||||
|
||||
### Option 3 — Restart Windows Firewall service
|
||||
|
||||
```powershell
|
||||
Restart-Service -Name MpsSvc -Force
|
||||
```
|
||||
|
||||
This resets all runtime firewall state (not persistent rules). You may still
|
||||
need to remove the `PCM_*` rules afterward with Option 1.
|
||||
|
||||
### Verify rules are gone
|
||||
|
||||
```powershell
|
||||
netsh advfirewall firewall show rule name=all dir=out | Select-String "PCM_"
|
||||
# Should return no output when clean
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Emergency: Proxy Leak Detected
|
||||
|
||||
If the Live tab reports a leak (exit IP matches your real IP or VPN IP):
|
||||
|
||||
1. Click **Rotate Now** to pick fresh proxies.
|
||||
2. If leaks persist, click **Stop**, then re-enable the kill-switch and click **Start**.
|
||||
3. Check the pool size — if < 5 proxies, force a full pool refresh by stopping
|
||||
and restarting the service.
|
||||
4. Enable VPN before starting if leak detection mode is "strict (exact IP)" —
|
||||
a VPN provides a larger subnet mask for the leak check.
|
||||
|
||||
---
|
||||
|
||||
## Empty Pool / CDN Down
|
||||
|
||||
If every pool refresh returns 0 proxies:
|
||||
|
||||
1. Check internet connectivity (browser → any site through system proxy OFF).
|
||||
2. Verify the proxy source URLs in **Settings** are reachable.
|
||||
3. The default sources use `cdn.jsdelivr.net` — if blocked on your network,
|
||||
replace with a mirror or local JSON file (use `file:///path/to/proxies.json`
|
||||
format).
|
||||
4. Temporarily lower `Max candidates` to speed up validation if the CDN is
|
||||
slow.
|
||||
|
||||
---
|
||||
|
||||
## GOST Binary Missing or Quarantined
|
||||
|
||||
Symptoms: "GOST setup failed" or "GOST appears quarantined" in the Live log.
|
||||
|
||||
1. Check Windows Defender: **Windows Security → Protection history** — look for
|
||||
a quarantine event on `gost.exe`.
|
||||
2. Restore and exclude `gost.exe` from Defender, or re-download by deleting the
|
||||
GOST folder:
|
||||
|
||||
```powershell
|
||||
Remove-Item "$env:LOCALAPPDATA\ProxyChainManager\gost" -Recurse -Force
|
||||
```
|
||||
|
||||
3. Restart the application — it will re-download and re-verify GOST via SHA256.
|
||||
|
||||
---
|
||||
|
||||
## Settings Corrupted / Reset to Defaults
|
||||
|
||||
A corrupt `settings.json` is automatically backed up to `settings.json.corrupt`
|
||||
and the application reverts to defaults.
|
||||
|
||||
To restore:
|
||||
|
||||
```powershell
|
||||
$dir = "$env:LOCALAPPDATA\ProxyChainManager"
|
||||
Copy-Item "$dir\settings.json.corrupt" "$dir\settings.json" -Force
|
||||
```
|
||||
|
||||
A rolling backup is also kept at `settings.json.bak` (last successful save).
|
||||
|
||||
---
|
||||
|
||||
## Log Files
|
||||
|
||||
| File | Location | Purpose |
|
||||
|------|----------|---------|
|
||||
| `proxy_chain_manager.log` | `%LOCALAPPDATA%\ProxyChainManager\` | Main app log (5 MB × 3 backups) |
|
||||
| `gost.log` | `%LOCALAPPDATA%\ProxyChainManager\` | GOST process output (512 KB rolling) |
|
||||
|
||||
To open the log directory:
|
||||
|
||||
```powershell
|
||||
explorer "$env:LOCALAPPDATA\ProxyChainManager"
|
||||
```
|
||||
Reference in New Issue
Block a user