210 lines
14 KiB
Markdown
210 lines
14 KiB
Markdown
> 历史记录 / Historical record:ProxyDoctor 是项目旧名。以下旧版本、SHA256、测试数量与路径保留原样,不代表 VPSMaster 新构建已通过;当前范围见 README.md、CURRENT_STATUS.md 和新包同 SHA256 验收报告。
|
||
|
||
See [current status](CURRENT_STATUS.md) for implemented and outstanding work. Family-specific DNS/TCP/TLS checks now back suite/quality; untested.
|
||
|
||
# Current development scope (2026-11-01)
|
||
|
||
This branch develops an independent Python VPS diagnostics CLI. See [backlog](PROBLEM_BACKLOG.md), [architecture](ARCHITECTURE.md), [source research](OPEN_SOURCE_RESEARCH.md), [test plan](TEST_PLAN.md), and [changelog](CHANGELOG.md). The previous 0.5.0 documentation below is historical context.
|
||
|
||
Routine `proxydoctor suite` skips CPU and bandwidth benchmarks. Consent to traffic tests with `proxydoctor bandwidth --allow-bandwidth` or `proxydoctor suite --allow-bandwidth`. The displayed payload budget excludes protocol overhead and other checks. Use `suite --offline` to skip network checks. Third-party executable/script wrappers are temporarily disabled.
|
||
|
||
These changes have not been tested or released. Earlier test results do not validate this branch.
|
||
|
||
---
|
||
|
||
# ProxyDoctor
|
||
|
||
[中文](README.md) | [English](README.en.md)
|
||
|
||
Native Python read-only VPS diagnostics for Ubuntu 22.04 and newer. Python 3.10+;
|
||
no third-party runtime dependencies. Ubuntu 22.04/24.04 are the current acceptance
|
||
targets; other versions need separate testing. No automatic sudo, installation,
|
||
SSH/firewall changes or fetching/executing remote scripts.
|
||
|
||
## Run
|
||
|
||
Extract the source package and run from its directory:
|
||
|
||
```bash
|
||
bash proxydoctor.sh
|
||
bash proxydoctor.sh suite --lang en
|
||
bash proxydoctor.sh suite --offline --lang en
|
||
python3 -m proxydoctor check --lang en --port 8388 --json --output check.json
|
||
```
|
||
|
||
Downloading/cloning does not execute code. The default `suite` contacts external
|
||
services and streams compact colored rows. `check` defaults to local reads.
|
||
Ordinary users can run it; missing privileges remain unknown. Report files stay
|
||
local, do not overwrite existing files and redact IPs. Review before sharing;
|
||
redaction is not an anonymity guarantee. `--show-ip` displays egress IP in the
|
||
terminal only. Routes display actual hop IPs in the terminal; exports mask them.
|
||
|
||
## Four modules
|
||
|
||
| Module | Terminal output | Limits |
|
||
| --- | --- | --- |
|
||
| Resources/preflight | OS, architecture, CPU/model/count, kernel, memory, disk, SHA-256 sample; route/DNS config, target port, SSH guard/config, local/cloud firewall status | Visible resources may differ from quotas; SHA-256 is not a general CPU benchmark; local reads cannot establish cloud ingress |
|
||
| Network/IP | Real DNS/TCP probes; ownership/ASN/location/type, provider flags/scores, coverage and disagreements | AAAA answers do not prove IPv6 connectivity; provider scores are separate observations, not safety certification |
|
||
| Route | Linux IPv4/IPv6 UDP error queue, 30 hops by default, up to 64; IP, latency, estimated location | NAT/filtering or silent routers can prevent completion; geolocation is approximate |
|
||
| Media | Ten independent service adapters, repeat confirmation, catalog/metadata evidence and explicit unknown reasons | No paid account/DRM playback verification; public offers/catalogs do not prove full unlock |
|
||
|
||
Suite JSON schema_version=2 includes local checks, DNS/TCP, per-source bandwidth,
|
||
IP observations/provenance/conflicts, route hops and media probe evidence.
|
||
Green indicates acquired data/local success, red known warnings/restrictions,
|
||
yellow unknown/skipped/insufficient evidence. `--color auto|always|never` and
|
||
`NO_COLOR` are supported. Use `check --json` for detailed local evidence.
|
||
`sshd -T` defaults may differ from running instances/Match rules. Future repair
|
||
features still require separate SSH safeguards.
|
||
|
||
## Bandwidth
|
||
|
||
```bash
|
||
bash proxydoctor.sh bandwidth --lang en
|
||
bash proxydoctor.sh bandwidth --lang en --source ovh-rbx --rounds 3 --sample-mib 4
|
||
bash proxydoctor.sh bandwidth --lang en --source hetzner-fsn --sample-mib 1
|
||
bash proxydoctor.sh suite --lang en --bandwidth-source cloudflare
|
||
```
|
||
|
||
| ID | Source/node label | Download | Upload | Default |
|
||
| --- | --- | --- | --- | --- |
|
||
| cloudflare | Cloudflare / Anycast | Yes | Yes | Yes |
|
||
| ovh-rbx | OVHcloud / FR Roubaix | Yes | No | Yes |
|
||
| hetzner-fsn | Hetzner / DE Falkenstein | Yes | No | No; slow on current test network |
|
||
|
||
Excluded 128 KiB warmup per supported direction; 3–8 measured rounds of 1–20 MiB.
|
||
Default requested benchmark payload is at most 36.375 MiB, excluding protocol
|
||
and other module traffic. Medians/ranges/success counts stay separate per source.
|
||
Short samples (<1s), missing rounds and high variation stay yellow. Wall-time
|
||
HTTPS throughput includes connection setup and cannot verify advertised capacity.
|
||
Static files require exact HTTP 206 ranges; ignored Range responses are closed
|
||
without reading the full body, never falling back to a full-file download.
|
||
Unsupported upload is skipped, not counted as failure. Bandwidth JSON schema=2.
|
||
|
||
## IP sources and keys
|
||
|
||
```bash
|
||
bash proxydoctor.sh ipquality --lang en --show-ip --json-output ip.json
|
||
bash proxydoctor.sh ipquality --lang en --no-enrichment
|
||
bash proxydoctor.sh suite --lang en --no-ip-enrichment
|
||
```
|
||
|
||
Defaults: ipapi.is, proxycheck.io and IP2Location. On an ipapi.is transport failure,
|
||
ipify can provide an egress address. Subsequent sources query that exact address;
|
||
mismatched responses are rejected. These services see the source address and the
|
||
additional sources receive the selected egress IP. Disable extra sources with
|
||
`--no-ip-enrichment` or all suite networking with `--offline`.
|
||
|
||
Seventeen core fields cover ownership/ASN, location/timezone, type/network abuse
|
||
share and datacenter/proxy/VPN/Tor/recent-abuse/mobile/satellite/anycast/bogon flags.
|
||
Per-source observations and field provenance are retained. Conflicting booleans
|
||
become unknown with disagreement evidence. IP2Location's limited free-plan proxy
|
||
flag is kept separate, not converted into a broad VPN guarantee. proxycheck.io
|
||
risk/confidence and AbuseIPDB scores are not averaged. Network abuse share is not
|
||
a single-IP maliciousness probability.
|
||
|
||
Keyless limits currently include 100 queries/day for proxycheck.io and 1000/day
|
||
for IP2Location, subject to provider rules. No automatic quota retries. Anonymous
|
||
ipapi.is has limited fields; optional keys provide extended fields/AbuseIPDB reports.
|
||
Enter locally without echoing; never send keys to chat or commit them:
|
||
|
||
```bash
|
||
read -rsp 'ipapi.is API Key: ' PROXYDOCTOR_IPAPI_KEY
|
||
export PROXYDOCTOR_IPAPI_KEY
|
||
printf '\n'
|
||
read -rsp 'AbuseIPDB API Key: ' PROXYDOCTOR_ABUSEIPDB_KEY
|
||
export PROXYDOCTOR_ABUSEIPDB_KEY
|
||
printf '\n'
|
||
bash proxydoctor.sh ipquality --lang en
|
||
```
|
||
|
||
ipapi.is keys travel in HTTPS POST JSON; AbuseIPDB keys use headers, not URLs or
|
||
reports. Missing fields remain unknown. Complete coverage means defined fields,
|
||
not every database or a security certification. Zero reports do not guarantee
|
||
safety. Observed API egress/family may differ from media connections.
|
||
|
||
## Route and media
|
||
|
||
```bash
|
||
bash proxydoctor.sh suite --lang en --max-hops 64 --route-target 1.1.1.1
|
||
bash proxydoctor.sh suite --lang en --route-target 2606:4700:4700::1111 --no-geo
|
||
bash proxydoctor.sh media --lang en --json-output media.json
|
||
```
|
||
|
||
ipwho.is geolocation is cached per run; private/reserved hops are never queried.
|
||
Media covers Netflix, Disney+, YouTube Premium, Spotify, Prime Video, Max, Apple
|
||
TV+, Hulu, BBC iPlayer and Paramount+. Clear regional messages and visible priced
|
||
offers require repeat agreement. Netflix uses structured catalog metadata; BBC
|
||
also checks public test-channel metadata. No media segments/paid content are
|
||
fetched and signed media URLs are not retained. BBC's channel result is scoped
|
||
to that channel. HTTP 200/403 or catalog/offer visibility never proves playback.
|
||
|
||
## Exit codes
|
||
|
||
`check`: 0=no known warning/failure (unknowns may remain), 1=findings, 2=usage/export
|
||
error. Online suite/bandwidth/ipquality/media: 1 also covers incomplete/unknown/
|
||
variable measurements or unverified playback. Offline 0 means local execution
|
||
completed, not online success. Media intentionally leaves playback untested and
|
||
returns 1. Ctrl+C returns 130 without changing system settings.
|
||
|
||
## Install and contribute
|
||
|
||
Source runs directly. Install the supplied wheel into a local virtual environment:
|
||
|
||
```bash
|
||
python3 -m venv .venv
|
||
.venv/bin/python -m pip install /path/to/proxydoctor-0.5.0-py3-none-any.whl
|
||
.venv/bin/proxydoctor suite --offline --lang en
|
||
```
|
||
|
||
If Ubuntu lacks venv support, install its matching OS component separately;
|
||
ProxyDoctor never installs it automatically. Development: install pytest and run
|
||
`python -m pytest -q`. An Actions workflow is supplied; remote CI is not claimed
|
||
before repository publication. See [CONTRIBUTING.md](CONTRIBUTING.md) and [SECURITY.md](SECURITY.md).
|
||
|
||
## Stage 1 and scope
|
||
|
||
This iteration targets code plus Ubuntu 22.04/24.04 VM acceptance as selected by
|
||
the user; consult the delivered acceptance records for actual results. Overseas
|
||
VPS tests, real-key extended data, paid-account playback and other Ubuntu releases
|
||
remain separately unverified. Later stages cover sing-box installation, Karing
|
||
protocol validation, repair previews/backups/rollback, Web UI and secure subscription
|
||
transport. No public plaintext subscription server or automatic SSH/firewall changes.
|
||
|
||
## License and acknowledgements
|
||
|
||
Original code is MIT. Thanks to ECS, NodeQuality, NetQuality/IPQuality, NextTrace
|
||
and RegionRestrictionCheck for feature/presentation references. No upstream script
|
||
source/databases are bundled by the default implementation. See [THIRD_PARTY_NOTICES.md](THIRD_PARTY_NOTICES.md).
|
||
Explicit local-script adapters are opt-in; external behavior/output may not be
|
||
read-only or redacted.
|
||
|
||
Official data references: [Cloudflare](https://github.com/cloudflare/speedtest),
|
||
[OVHcloud](https://proof.ovh.net/), [Hetzner](https://docs.hetzner.com/storage/object-storage/troubleshooting/bandwidth-latency-issues/),
|
||
[ipapi.is](https://ipapi.is/developers.html), [proxycheck.io](https://proxycheck.io/api/),
|
||
[IP2Location](https://www.ip2location.io/ip2location-documentation), [AbuseIPDB](https://docs.abuseipdb.com/),
|
||
[ipwho.is](https://ipwhois.io/documentation), [ipify](https://www.ipify.org/).
|
||
[Netflix VPN guidance](https://help.netflix.com/en/node/114701) explains catalog restrictions.
|
||
|
||
|
||
## Reliability batch — 2026-11-01 (implemented, untested)
|
||
|
||
`suite` now creates a local redacted JSON report and sibling `.events.jsonl` recovery journal. Without `--json-output`, files are placed under `./reports/` with unique names. Detection does not modify system configuration, but does write these local output files. Linux file creation requests mode 0600; Windows uses inherited ACLs.
|
||
|
||
Each module start/completion and completed DNS/TCP result, route hop, and media service writes a flushed/fsynced snapshot. Module exceptions use `MODULE_ERROR` without storing raw exception text; other modules continue. `success` in `modules` means the module executed, not that a service is unlocked or a server is safe. Overall partial measurement remains incomplete. Ctrl+C records cancellation and returns 130. Previously completed journal records remain useful after a crash; use the Python `proxydoctor.reports.recover_latest(path)` API to read the latest complete snapshot.
|
||
|
||
Existing final/journal files and dangling final symlinks are rejected. Storage errors during checks produce a terminal warning, keep prior records, and return a nonzero result. The final JSON is exclusively created; a failed final write can leave a partial final file, so recover from the journal. No absolute durability guarantee applies to disk/controller failure. Storage paths must be in user-controlled directories; parent-directory symlink attacks are outside this first implementation.
|
||
|
||
Limits: module-level isolation does not isolate every individual local system check. Bandwidth and IP collection currently checkpoint on module completion; interruption can lose the current module's unfinished results. Media cancellation may wait for in-flight bounded network calls when the thread pool exits. SIGKILL/power loss cannot trigger cleanup; the journal contains only the last complete checkpoint. Standalone commands retain their existing save behavior. These changes and the new fault-injection tests have not been run yet.
|
||
|
||
## Resource observations (unverified)
|
||
|
||
`suite` and `check` now include visible CPU quotas, process affinity, visible memory bounds, swap, PSI and short-sample CPU steal. Numeric results are preserved separately from terminal language. The default 0.2-second passive observation does not benchmark the CPU or change cgroup settings. Missing data remains unknown. Visible limits do not establish dedicated capacity; namespace/host scope and long-term contention require separate verification. New tests have not been run.
|
||
|
||
Basic security now inspects fixed-path ownership/mode metadata and optional local update-cache age/counts. Password-file contents are not read. Review findings manually; cached counts do not establish patch status. Untested.
|
||
|
||
## Local report export and IP overview
|
||
|
||
Use `proxydoctor report --input report.json --output report.md` to export a local snapshot; `proxydoctor recover --journal report.json.events.jsonl --output recovered.json` recovers the last complete record. Add `--format markdown --lang en` for English Markdown recovery. Files are never overwritten. Inspect exports before sharing.
|
||
|
||
`proxydoctor ipquality --mail-probes` opts into bounded PTR/forward consistency and one outbound TCP/25 target without sending mail. The overview panel precedes provider evidence. DNSBL and IP maps are not yet integrated; see IPQUALITY_COVERAGE.md. Final code passed 239 tests on each Ubuntu VM.
|