Skip to content

Commit 181a610

Browse files
committed
Align documentation and inventory examples with current behavior
1 parent 6cc9ab5 commit 181a610

6 files changed

Lines changed: 113 additions & 48 deletions

File tree

‎README.md‎

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,11 +27,14 @@ administrative key on your computer before confirming provisioning. See the
2727

2828
### Manage servers from another machine
2929

30-
Requirements: macOS or Linux, Python 3.12+, `uv`, OpenSSH, and a Debian or Ubuntu server reachable through a
30+
Requirements: macOS or Linux, Git, Python 3.12+, `uv`, OpenSSH, and a Debian or Ubuntu server reachable through a
3131
sudo-capable SSH account.
3232

3333
```shell
34+
git clone https://github.com/andre487/MegaProxyServer.git
35+
cd MegaProxyServer
3436
./mega-proxy inventory
37+
./mega-proxy bootstrap
3538
./mega-proxy plan
3639
./mega-proxy apply
3740
./mega-proxy verify
@@ -84,7 +87,10 @@ See [`inventory.example.yml`](inventory.example.yml) and the
8487
```
8588

8689
This runs Ruff, pytest, Python byte-compilation and Ansible syntax checks with dependencies locked
87-
in `uv.lock`.
90+
in `uv.lock`. Separate GitHub Actions jobs test real GOST/nginx and Ubuntu/Debian LXD
91+
provisioning; `check` does not run these integrations. See the
92+
[English](docs/en/README.md#development-and-troubleshooting) or
93+
[Russian](docs/ru/README.md#разработка-и-диагностика) guide for coverage and `main` protection.
8894

8995
## License
9096

‎docs/en/README.md‎

Lines changed: 39 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ open a shell, TTY, subsystem, remote forwarding or tunnel device.
1414

1515
## Requirements
1616

17-
The control machine needs macOS or Linux, `uv`, OpenSSH and Python 3.12+. Managed machines need a
17+
The control machine needs macOS or Linux, Git, `uv`, OpenSSH and Python 3.12+. Managed machines need a
1818
current Debian or Ubuntu release and a sudo-capable SSH account. Open TCP 443 for HTTPS and TCP 80
1919
during standalone ACME validation in both the provider firewall and the host firewall.
2020

@@ -73,6 +73,8 @@ key paths. Local setup handles one server; multi-host management is described be
7373
### Manage from another machine
7474

7575
```shell
76+
git clone https://github.com/andre487/MegaProxyServer.git
77+
cd MegaProxyServer
7678
./mega-proxy inventory
7779
./mega-proxy bootstrap
7880
./mega-proxy plan
@@ -87,7 +89,9 @@ at any time with `--inventory PATH`.
8789
The wizard supports an initial password or a separate SSH key. Bootstrap prompts for the password
8890
without echoing it. The password is kept only in a private temporary connection file, removed after
8991
Ansible exits. Verify the server fingerprint and add its key to `known_hosts` first. Load
90-
passphrase-protected administrative keys with `ssh-add`.
92+
passphrase-protected administrative keys with `ssh-add`; deriving or validating the public key
93+
also uses `ssh-keygen -y`, which can ask for the passphrase separately. Unattended apply requires
94+
this step to work without an interactive prompt.
9195

9296
`bootstrap` creates the administrator and sudo access, checks a fresh key-only login and `sudo -n`,
9397
then disables root and password-based administrative login. It verifies access again after SSH
@@ -147,12 +151,14 @@ provide metadata for personalized delivery; the current `export` and `configs` c
147151
`services.ssh.generate_profile` defaults to false and selects hosts for direct SSH profiles in
148152
`export`, `configs` and the configuration API. Administrative SSH uses `admin` settings separately.
149153

150-
The wizard asks whether to publish direct SSH profiles. `enabled: false` also
154+
The wizard asks whether to publish direct SSH profiles, defaulting to yes; omitting the field
155+
in hand-written YAML still defaults to false. `enabled: false` also
151156
disables an existing proxy: HTTPS stops GOST, HAProxy and the renewal timer; SSH
152157
denies the `megaproxy` group and closes its sessions while preserving administrative
153158
SSH. Keep the disabled service in YAML: an absent service is unmanaged. Firewall
154159
records its own rules and revokes retired ports on the next full apply, preserving
155-
other rules. An initial upgrade records existing configured ports before later changes.
160+
other rules. An initial upgrade records existing configured ports before later changes;
161+
older open ports already absent from inventory are not discovered automatically.
156162

157163
Only accounts whose primary group is `megaproxy` may be modified or removed;
158164
new proxy accounts are created in that group. Administrative/bootstrap accounts,
@@ -167,7 +173,7 @@ Bootstrap verifies the new login before revoking the old key; mismatched public
167173
and private keys are rejected.
168174

169175
Inventory and exports are replaced atomically with mode `0600`. Export validation
170-
runs before replacing an existing file; unknown country codes become empty strings.
176+
runs before replacing an existing file; country codes outside `[A-Z]{2}` become empty strings.
171177
Port conflicts and HTTPS without routes are rejected before connecting to a host.
172178
Docker cleanup only removes old GOST/Certbot images, without global prune operations.
173179
HTTPS chains verify the exit certificate and hostname. CI uses a local CA to test
@@ -180,8 +186,9 @@ or unavailable exits, without external domains or ACME for these checks.
180186
| true | false | Provision SSH proxy users; use the host only in declared jump pairs |
181187
| false | any | Deny proxy access, close proxy sessions and omit profiles; jump pairs cannot reference this host |
182188

183-
Setting `enabled: false` skips the role; it does not remove previously provisioned accounts or
184-
stop the server's SSH daemon. To revoke an account, use `remove-users` and `apply`.
189+
Disabling SSH retains proxy accounts but denies their access; it does not stop the server's SSH
190+
daemon. To delete an account, use `remove-users` and `apply`. A tagged apply must include
191+
`firewall` to reconcile ports, for example `apply --tags ssh,https,firewall`.
185192

186193
```yaml
187194
hosts:
@@ -244,8 +251,11 @@ first, then server-side chains.
244251
HTTPS and SSH services and all chain/jump pairs require a nonblank `title`.
245252
Names are read directly from inventory; no names are derived from host identifiers.
246253

247-
For country flags, start host identifiers with a two-letter country code followed by `_`, such as
248-
`de_entry` and `us_exit`. Explicit HTTPS chain pairs supply the exit country in `country_code`.
254+
Direct HTTPS country codes come from the first segment of the host identifier after removing
255+
an optional `proxy_` prefix: `de_entry` and `proxy_de` yield `DE`. Identifiers such as `px-de`
256+
yield an empty code. Codes must match two uppercase letters; no country registry is consulted.
257+
Explicit HTTPS chain pairs require `country_code`; jump pairs can override the exit's inferred
258+
code. Direct SSH and SOCKS5 profiles currently have an empty country code.
249259
The code is a display hint; use the client connection test to check the observed exit country.
250260
HTTPS and jump profile IDs use logical host/route identifiers and the account, so changing a
251261
title or endpoint preserves those IDs. Direct SSH IDs also use the host and account. SOCKS5 exports still derive IDs from their names.
@@ -259,9 +269,9 @@ Set a knock host per HTTPS proxy using `services.https.probe_resistance.knock`:
259269
probe_resistance:
260270
enabled: true
261271
mode: local_decoy
262-
knock: [px-knock.jethelix.ru]
272+
knock: [knock.example.com]
263273
```
264-
The first host becomes `browser.knockHost` in API and MegaProxy file profiles.
274+
When probe resistance is enabled, the first host becomes `browser.knockHost` in API and MegaProxy file profiles.
265275
Chain routes inherit the entry setting unless the pair overrides `probe_resistance`.
266276
The setup wizard asks for the knock hostname when probe resistance is enabled.
267277
Apply HTTPS settings to the proxy hosts and update the config API bundle after changing it.
@@ -276,6 +286,9 @@ Masked routes serve a static site using GOST's built-in loopback file server. A
276286
Python script generates a random heading and abstract SVG once. Repeated `apply` runs keep the
277287
site; remove `/opt/megaproxy/decoy/index.html` to regenerate it on the next `apply`.
278288
The page includes `noindex,nofollow`; `/robots.txt` contains `User-agent: *` and `Disallow: /`.
289+
Only `enabled` and `knock` currently affect masking. The inventory model accepts `mode`,
290+
`status_code` and `site_title`, but they do not select another response mode
291+
or control the generated site's title.
279292

280293
## HTTPS certificates and chains
281294

@@ -300,7 +313,7 @@ clients to allow an invalid proxy certificate.
300313

301314
The default `.generated/configs` directory contains:
302315

303-
- `MegaProxy.json`: HTTPS, direct SSH for hosts with `services.ssh.generate_profile: true`, and explicitly configured SSH/HTTPS jump profiles;
316+
- `MegaProxy.json`: HTTPS, enabled MASQUE/SOCKS5 transports, direct SSH for hosts with `services.ssh.generate_profile: true`, and explicitly configured SSH/HTTPS jump profiles;
304317
- `FoxyProxy.json`: HTTPS profiles;
305318
- `SuperProxy.txt`: HTTPS URLs with the Super Proxy v1 header;
306319
- `ProxyList.txt`: URL-encoded HTTPS proxy URLs.
@@ -383,8 +396,10 @@ SNI routes remain usable through the HTTPS-only export formats. SSH jump profile
383396

384397
### Client limits and diagnostics
385398

386-
The Android client forwards TCP application traffic; general UDP and QUIC forwarding are not
387-
implemented. SSH keys protected by a passphrase are unsupported. DNS, per-app routing, failover
399+
HTTPS and SSH forward TCP; MASQUE and SOCKS5 also forward UDP in compatible Android builds.
400+
Availability depends on the installed client release; see its
401+
[transport guide](https://github.com/andre487/AndroidMegaProxy#current-limitations).
402+
SSH keys protected by a passphrase are unsupported. DNS, per-app routing, failover
388403
and Android Always-on VPN are configured in the app. Exported profiles do not enable failover.
389404

390405
Use **Test** to distinguish proxy setup, destination access and exit-IP failures. It contacts
@@ -449,8 +464,16 @@ directory is suitable for machine-local integrations such as px-manager.
449464

450465
## Development and troubleshooting
451466

452-
`./mega-proxy check` runs Ruff, pytest, byte-compilation and Ansible syntax checks. CI runs the same
453-
suite; integration jobs provision isolated Ubuntu/Debian LXD systems.
467+
`./mega-proxy check` runs Ruff, pytest, byte-compilation and Ansible syntax checks. CI runs this
468+
suite on Python 3.12 and 3.14. Separate integration jobs run real GOST and nginx on loopback
469+
and provision Ubuntu 24.04 plus two Debian 12 LXD guests. They cover SSH Jump, credential
470+
rotation, account removal, proxy disable/re-enable, firewall cleanup and administrative access.
471+
They use temporary credentials and self-signed or local-CA certificates; they do not test
472+
production DNS, public ACME issuance or an Android device. These jobs are not run by `check`.
473+
474+
`main` requires a pull request, all five CI checks, an up-to-date branch and resolved
475+
conversations. Force pushes and deletion are forbidden, including for administrators;
476+
approval by a second person is not required. The required check names match the workflows.
454477

455478
- **ACME fails:** check DNS, TCP 80 and provider firewall rules.
456479
- **A chain domain serves an old certificate:** run `apply --limit ENTRY --tags https`, then inspect

0 commit comments

Comments
 (0)