docs: add README and manual pages
This commit is contained in:
@@ -0,0 +1,356 @@
|
||||
# prx
|
||||
|
||||
Safe proxy routing manager for Linux.
|
||||
|
||||
`prx` turns proxy routing on and off without breaking the connections that
|
||||
reach *you*. In particular, an SSH session that is already open when you enable
|
||||
the proxy keeps working — regardless of which port it uses.
|
||||
|
||||
```
|
||||
prx on # route outbound traffic through the proxy, protect inbound replies
|
||||
prx off # restore a clean state
|
||||
prx status # what is currently applied
|
||||
```
|
||||
|
||||
- Proxy engine: **sing-box** (TUN mode) by default, managed through systemd.
|
||||
- Routing: **nftables** + **ip rule** policy routing.
|
||||
- Privileges: an unprivileged CLI plus a small privileged helper invoked with
|
||||
**polkit/pkexec** (falling back to **sudo**).
|
||||
- Target: **Arch Linux**, and any other Linux with `nftables`, `iproute2` and
|
||||
`systemd`. Nothing is hard-coded to a particular interface, gateway, address
|
||||
or distribution layout.
|
||||
|
||||
---
|
||||
|
||||
## Why inbound connections survive
|
||||
|
||||
When a TUN-based proxy is enabled, the default route is usually replaced so
|
||||
that traffic enters the tunnel. That is exactly what breaks inbound sessions:
|
||||
the replies you send to a client that connected to you get pulled into the
|
||||
tunnel and never reach the client.
|
||||
|
||||
`prx` prevents this at the routing layer:
|
||||
|
||||
1. Incoming connections on the WAN interface are given a conntrack mark
|
||||
(`0x100` by default).
|
||||
2. Outgoing packets belonging to a connection whose **original destination** is
|
||||
one of our WAN addresses are marked too. Matching on the original
|
||||
destination — instead of only `ct state new` — means connections that were
|
||||
**already established before `prx on`** are protected as well.
|
||||
3. An `ip rule` routes marked packets through a dedicated table whose default
|
||||
route points at the physical gateway, not the tunnel.
|
||||
|
||||
Because the decision is based on the connection, not a port number, it works
|
||||
for SSH on any port and for any other inbound service.
|
||||
|
||||
---
|
||||
|
||||
## Install
|
||||
|
||||
### From source
|
||||
|
||||
```sh
|
||||
git clone https://github.com/example/prx
|
||||
cd prx
|
||||
make build # produces bin/prx and bin/prx-helper
|
||||
sudo make install # installs binaries, man pages, polkit policy and systemd units
|
||||
```
|
||||
|
||||
### Arch Linux (PKGBUILD)
|
||||
|
||||
```sh
|
||||
cd packaging
|
||||
makepkg -si
|
||||
```
|
||||
|
||||
### Dependencies
|
||||
|
||||
Runtime: `nftables` (>= 0.9.4, for the `destroy` keyword), `iproute2` (with `-j`
|
||||
JSON support), `systemd`, and a way to elevate privileges — `polkit`/`pkexec`
|
||||
or `sudo`. Optional: `sing-box` (the default engine).
|
||||
|
||||
```sh
|
||||
# Arch
|
||||
sudo pacman -S nftables iproute2 polkit sing-box
|
||||
# other distributions: install the equivalent packages
|
||||
```
|
||||
|
||||
`prx` makes no assumptions about this machine: the WAN interface, gateway and
|
||||
local addresses are detected at runtime from `ip route`/`ip addr`, IPv6 is used
|
||||
only when the host actually has an IPv6 uplink, and the helper is found by
|
||||
searching the standard install locations (see *Privileges*). Missing tools
|
||||
produce an actionable message that names the package to install.
|
||||
|
||||
Create a starting configuration:
|
||||
|
||||
```sh
|
||||
prx init # writes ~/.config/prx/config.json
|
||||
prx init --engine-config # also writes a baseline sing-box config
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Commands
|
||||
|
||||
| Command | Description |
|
||||
| --- | --- |
|
||||
| `prx on [--skip-engine] [--dry-run]` | Enable routing; installs nftables + policy routing rules |
|
||||
| `prx off` | Remove prx-managed rules and restore a clean state |
|
||||
| `prx toggle` | Enable or disable based on current state |
|
||||
| `prx status [--json]` | Human readable status, or machine readable JSON |
|
||||
| `prx doctor` | Diagnose configuration and applied rules |
|
||||
| `prx bypass add <cidr\|ip\|domain>` | Keep a destination out of the tunnel |
|
||||
| `prx bypass rm <cidr\|ip\|domain>` | Remove a bypass entry |
|
||||
| `prx bypass ls` | List bypass entries |
|
||||
| `prx logs [--follow]` | Tail the engine journal |
|
||||
| `prx init [--engine-config]` | Write a default configuration |
|
||||
| `prx version` | Print version information |
|
||||
|
||||
Exit codes are `0` on success and non-zero with an actionable message on
|
||||
failure.
|
||||
|
||||
### Useful flags
|
||||
|
||||
- `prx on --dry-run` — validate the plan without changing anything.
|
||||
- `prx on --skip-engine` — apply only the routing layer (useful for testing or
|
||||
when you manage the engine yourself).
|
||||
|
||||
### Man pages
|
||||
|
||||
Two manual pages are installed under `share/man/man1`:
|
||||
|
||||
```sh
|
||||
man prx # the CLI
|
||||
man prx-helper # the privileged helper
|
||||
```
|
||||
|
||||
They are listed in `man/prx.1` and `man/prx-helper.1` and can be previewed
|
||||
without installing:
|
||||
|
||||
```sh
|
||||
man --local-file man/prx.1
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Configuration
|
||||
|
||||
`~/.config/prx/config.json` (override with `--config` or `$PRX_CONFIG`):
|
||||
|
||||
```json
|
||||
{
|
||||
"engine": {
|
||||
"type": "sing-box",
|
||||
"config_path": "/etc/sing-box/config.json",
|
||||
"service_name": "sing-box",
|
||||
"manage": true,
|
||||
"stop_on_off": false
|
||||
},
|
||||
"network": {
|
||||
"wan_interface": "",
|
||||
"wan_gateway": "",
|
||||
"wan_gateway6": "",
|
||||
"dns_keepalive": true
|
||||
},
|
||||
"marks": { "inbound_mark": 256 },
|
||||
"routing": {
|
||||
"table_v4": 100,
|
||||
"table_v6": 101,
|
||||
"priority_v4": 100,
|
||||
"priority_v6": 100,
|
||||
"bypass_table_v4": 102,
|
||||
"bypass_table_v6": 103,
|
||||
"bypass_priority_v4": 50,
|
||||
"bypass_priority_v6": 50
|
||||
},
|
||||
"bypass": {
|
||||
"always_cidrs": ["127.0.0.0/8", "10.0.0.0/8", "172.16.0.0/12", "192.168.0.0/16", "169.254.0.0/16", "::1/128", "fc00::/7", "fe80::/10"],
|
||||
"extra_cidrs": [],
|
||||
"domains": []
|
||||
},
|
||||
"process_bypass": { "names": ["ssh", "scp", "sftp"] },
|
||||
"health": { "probe": "1.1.1.1:443" },
|
||||
"state": { "path": "/run/prx/state.json" }
|
||||
}
|
||||
```
|
||||
|
||||
- `network.wan_interface` / `network.wan_gateway` / `network.wan_gateway6` are
|
||||
optional overrides; otherwise the default route is detected from
|
||||
`ip route show default` (IPv4 first, then IPv6 for an IPv6-only uplink).
|
||||
- `health.probe` is a `host:port` dialed after enabling to confirm
|
||||
connectivity. Set it to `""` to disable the check.
|
||||
- `marks.inbound_mark` is `256` (0x100). Keep it distinct from the mark your
|
||||
engine uses; `prx doctor` warns on a collision.
|
||||
- `always_cidrs` are hints for the engine (they are baked into the generated
|
||||
engine config). `extra_cidrs` are additionally enforced by the routing layer:
|
||||
each one gets a route in the bypass table and a destination-based `ip rule`,
|
||||
so that traffic to it never enters the tunnel.
|
||||
|
||||
Unknown keys are rejected (the config is decoded strictly), and every value is
|
||||
validated before it is written.
|
||||
|
||||
State is stored in `/run/prx/state.json` so `off` and rollback know what was
|
||||
applied. A companion `prx.lock` file serialises concurrent `on`/`off` so two
|
||||
runs cannot interleave.
|
||||
|
||||
---
|
||||
|
||||
## Privileges
|
||||
|
||||
Privileged actions go through a small helper:
|
||||
|
||||
```
|
||||
prx (unprivileged) --pkexec--> prx-helper (root)
|
||||
--sudo----->
|
||||
```
|
||||
|
||||
The CLI resolves and validates everything, then sends a JSON plan on stdin to
|
||||
`prx-helper`. The helper re-validates every field before touching the system, so
|
||||
the privileged attack surface stays small. `on`, `off`, `toggle`, `bypass`,
|
||||
`init --engine-config` and `doctor` use the helper; `status`, `logs` and
|
||||
`version` do not.
|
||||
|
||||
Elevation prefers `pkexec` (a polkit prompt) and falls back to `sudo -n` when
|
||||
polkit is not installed, so prx also works on minimal systems. The helper is
|
||||
located in this order:
|
||||
|
||||
- `$PRX_HELPER` (explicit override),
|
||||
- next to the `prx` binary, then `../lib/prx` and `../libexec/prx`,
|
||||
- `/usr/libexec/prx`, `/usr/lib/prx`, `/usr/local/libexec/prx`,
|
||||
`/usr/local/lib/prx`,
|
||||
- finally `$PATH`.
|
||||
|
||||
If `sudo` needs a password, run the command as `sudo prx ...` directly (the CLI
|
||||
then runs the helper in-process), or install the polkit policy for a prompt.
|
||||
|
||||
The polkit action is defined in `polkit/org.prx.policy` and requires
|
||||
authentication (`auth_admin`) for changes.
|
||||
|
||||
---
|
||||
|
||||
## How `on` works (transactionally)
|
||||
|
||||
1. Acquire a `prx.lock` file lock so concurrent runs never interleave.
|
||||
2. Detect the WAN interface, gateway and local addresses.
|
||||
3. Install the nftables table `inet prx` in a single atomic transaction
|
||||
(`destroy` + full redefinition, so re-running never duplicates rules).
|
||||
4. Install the policy rule and route (and bypass rules), idempotently. A
|
||||
rollback handler is registered **before** each table is touched, so a failure
|
||||
part-way through still cleans up.
|
||||
5. Ensure the engine service is running.
|
||||
6. Run health checks (rules present, engine active, connectivity probe).
|
||||
7. If any blocking check fails, **roll back** everything (in reverse order) and
|
||||
exit non-zero. If a rollback step itself fails, prx says so explicitly (a
|
||||
`rollback warning:` line and an error stating the rollback was incomplete)
|
||||
instead of pretending the system is clean.
|
||||
|
||||
`off` removes only objects prx created: the `inet prx` table, rules that look up
|
||||
prx's tables, and prx's routes. It never flushes your whole ruleset.
|
||||
|
||||
Re-running `on` is idempotent; running `off` twice is a no-op. Configuration and
|
||||
state are written atomically (temp file + fsync + rename) so they are never
|
||||
observed half-written, and `Ctrl-C` cancels cleanly via signal handling. A
|
||||
corrupt state file never crashes a command: it is reported (for example by
|
||||
`prx status`) and the rest of the information is still shown.
|
||||
|
||||
---
|
||||
|
||||
## The generated sing-box config
|
||||
|
||||
`prx init --engine-config` writes a baseline TUN configuration:
|
||||
|
||||
- a `tun` inbound with `auto_route`;
|
||||
- a `direct` outbound that **you should replace** with your real proxy
|
||||
outbound (Shadowsocks, VLESS, …);
|
||||
- a route rule that sends the bypass CIDRs, domains and process names direct.
|
||||
|
||||
`prx` does not rewrite an existing engine config on every `on`; it only
|
||||
validates that a TUN inbound is present and warns otherwise.
|
||||
|
||||
---
|
||||
|
||||
## systemd
|
||||
|
||||
Two optional units are shipped:
|
||||
|
||||
- `prx-reapply.service` — re-applies the routing (runs `prx on`, which is
|
||||
idempotent). It only runs when `/run/prx/state.json` exists, i.e. when prx was
|
||||
enabled.
|
||||
- `prx-reapply.timer` — triggers the service periodically so a changed gateway
|
||||
(DHCP) is picked up.
|
||||
|
||||
Enable the timer if you want automatic re-application:
|
||||
|
||||
```sh
|
||||
sudo systemctl enable --now prx-reapply.timer
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
Start with:
|
||||
|
||||
```sh
|
||||
prx doctor
|
||||
```
|
||||
|
||||
Common situations:
|
||||
|
||||
- **`nft: ... Operation not permitted`** — run the command with `sudo` or
|
||||
install the polkit policy so `pkexec` can prompt.
|
||||
- **`required binary "nft" not found ... install nftables`** — install the named
|
||||
package (`nftables`, `iproute2` or `systemd`).
|
||||
- **`nftables may be too old ... needs >= 0.9.4`** — upgrade your nftables
|
||||
package; older releases do not understand the `destroy` keyword prx uses.
|
||||
- **`prx-helper not found`** — the helper is not installed or lives outside the
|
||||
searched paths; install prx or set `$PRX_HELPER`.
|
||||
- **`sudo needs a password`** — run `sudo prx ...` directly, or install polkit
|
||||
for a graphical prompt.
|
||||
- **`journalctl not found` / `prx logs` unavailable** — install `systemd`.
|
||||
- **`state file unreadable`** — `/run/prx/state.json` is corrupt; remove it and
|
||||
re-run `prx on`.
|
||||
- **engine-config warning: no tun inbound** — enable TUN mode in your engine
|
||||
config; prx relies on it.
|
||||
- **mark-collision** — your engine uses the same mark as prx; change
|
||||
`marks.inbound_mark` (or the engine's mark).
|
||||
- **connectivity check fails** — the marking/routing is installed but the host
|
||||
could not open an outbound TCP connection; check the engine and upstream (or
|
||||
set `health.probe` to `""` to skip the check).
|
||||
- **`pkexec` returns "authorization cancelled"** — you dismissed the polkit
|
||||
prompt.
|
||||
|
||||
Inspect the applied objects manually:
|
||||
|
||||
```sh
|
||||
sudo nft list table inet prx
|
||||
ip rule show
|
||||
ip route show table 100
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Testing
|
||||
|
||||
```sh
|
||||
make test # unit tests (no root required)
|
||||
sudo -E PRX_BIN="$PWD/bin/prx" ./scripts/integration-test.sh
|
||||
```
|
||||
|
||||
The integration script enables the routing layer with `--skip-engine`, asserts
|
||||
the rules exist, checks idempotency, and then disables it and asserts a clean
|
||||
state.
|
||||
|
||||
---
|
||||
|
||||
## Author
|
||||
|
||||
- **Amir Husayn Panahifar** <ahp@panahifar.ir> — author and maintainer.
|
||||
|
||||
Contributions are welcome.
|
||||
|
||||
---
|
||||
|
||||
## License
|
||||
|
||||
MIT. See `LICENSE`.
|
||||
@@ -0,0 +1,81 @@
|
||||
.\" Manual page for prx-helper
|
||||
.\" Copyright (C) 2026 Amir Husayn Panahifar <ahp@panahifar.ir>
|
||||
.TH PRX-HELPER 1 "2026-10-15" "prx 0.1.0" "User Commands"
|
||||
.SH NAME
|
||||
prx-helper \- privileged core of prx
|
||||
.SH SYNOPSIS
|
||||
.B prx-helper
|
||||
.SH DESCRIPTION
|
||||
.B prx-helper
|
||||
is the privileged half of
|
||||
.BR prx (1).
|
||||
It reads a single JSON
|
||||
.I plan
|
||||
from standard input, validates it, executes it, and writes a JSON result to
|
||||
standard output.
|
||||
.PP
|
||||
It is not meant to be run by hand; the unprivileged
|
||||
.B prx
|
||||
CLI launches it through
|
||||
.BR pkexec (1)
|
||||
or
|
||||
.BR sudo (8),
|
||||
and communicates over standard input and standard output.
|
||||
It refuses to run without root privileges.
|
||||
.PP
|
||||
Every field of the incoming plan is re\-validated before any system change is
|
||||
made, so the privileged attack surface stays small.
|
||||
The
|
||||
.B apply
|
||||
operation is transactional: if a post\-apply health check fails, the changes
|
||||
made so far are rolled back.
|
||||
If a rollback step itself fails, that is reported in the result rather than
|
||||
being ignored.
|
||||
.SH ACTIONS
|
||||
The plan's
|
||||
.B action
|
||||
field selects one of:
|
||||
.TP
|
||||
.B apply
|
||||
Detect the WAN interface and gateway, install the nftables table, the policy
|
||||
rule and route, any bypass rules and routes, ensure the engine is running, run
|
||||
health checks, and record the state snapshot.
|
||||
A health\-check failure triggers a rollback.
|
||||
.TP
|
||||
.B remove
|
||||
Remove the prx\-managed rules, tables and routes, optionally stop the engine,
|
||||
and delete the state snapshot.
|
||||
.TP
|
||||
.B inspect
|
||||
Report the state of the rules, tables, engine and TUN interfaces without
|
||||
changing anything.
|
||||
.TP
|
||||
.B engine
|
||||
Start, stop, reload or query the engine service.
|
||||
.TP
|
||||
.B init-engine
|
||||
Write a generated engine configuration to disk after validating it as JSON.
|
||||
.SH SECURITY
|
||||
Input is treated as untrusted.
|
||||
Interface names, IP addresses, CIDR blocks, route table identifiers, rule
|
||||
priorities, marks and service names are validated against strict patterns and
|
||||
ranges before being used to build nftables scripts or
|
||||
.B ip
|
||||
commands.
|
||||
.SH "EXIT STATUS"
|
||||
.TP
|
||||
.B 0
|
||||
The action succeeded.
|
||||
.TP
|
||||
.B 1
|
||||
The action failed, or the process was not run as root.
|
||||
.TP
|
||||
.B 2
|
||||
The plan on standard input was malformed, or the result could not be encoded.
|
||||
.SH "SEE ALSO"
|
||||
.BR prx (1),
|
||||
.BR polkit (8),
|
||||
.BR pkexec (1),
|
||||
.BR sudo (8)
|
||||
.SH AUTHOR
|
||||
Amir Husayn Panahifar <ahp@panahifar.ir>.
|
||||
@@ -0,0 +1,279 @@
|
||||
.\" Manual page for prx
|
||||
.\" Copyright (C) 2026 Amir Husayn Panahifar <ahp@panahifar.ir>
|
||||
.TH PRX 1 "2026-10-15" "prx 0.1.0" "User Commands"
|
||||
.SH NAME
|
||||
prx \- safe proxy routing manager
|
||||
.SH SYNOPSIS
|
||||
.B prx
|
||||
.RI [ options ]
|
||||
.I command
|
||||
.RI [ arguments ]
|
||||
.SH DESCRIPTION
|
||||
.B prx
|
||||
turns proxy routing on and off without breaking the connections that reach
|
||||
your host.
|
||||
In particular, an inbound session that is already open when the proxy is
|
||||
enabled (for example an SSH login) keeps working, regardless of the port it
|
||||
uses.
|
||||
.PP
|
||||
The tool orchestrates an external proxy engine (by default
|
||||
.BR sing-box (1)
|
||||
in TUN mode, managed through systemd) and installs the network configuration
|
||||
needed to keep reply traffic on the physical uplink:
|
||||
.IP "1." 4
|
||||
Incoming connections on the WAN interface are tagged with a conntrack mark
|
||||
(\fB0x100\fR by default).
|
||||
.IP "2." 4
|
||||
Outgoing packets belonging to a connection whose
|
||||
.I original
|
||||
destination is one of the host's WAN addresses are tagged as well.
|
||||
Because the original destination is matched, connections that were already
|
||||
established before
|
||||
.B prx on
|
||||
are protected too.
|
||||
.IP "3." 4
|
||||
An
|
||||
.BR ip-rule (8)
|
||||
entry routes marked packets through a dedicated routing table whose default
|
||||
route points at the physical gateway rather than the tunnel.
|
||||
.PP
|
||||
Because the decision is based on the connection and not on a port number, the
|
||||
protection is port\-independent.
|
||||
.PP
|
||||
All privileged work is performed by a small helper,
|
||||
.BR prx-helper (1),
|
||||
which the unprivileged
|
||||
.B prx
|
||||
CLI invokes through
|
||||
.BR pkexec (1)
|
||||
(polkit), falling back to
|
||||
.BR sudo (8)
|
||||
when polkit is not installed.
|
||||
.SH OPTIONS
|
||||
.SS Global options
|
||||
.TP
|
||||
.BR \-\-config " " \fIFILE\fR
|
||||
Read configuration from
|
||||
.IR FILE .
|
||||
Defaults to
|
||||
.IR $XDG_CONFIG_HOME/prx/config.json
|
||||
(or
|
||||
.IR ~/.config/prx/config.json ).
|
||||
The environment variable
|
||||
.B PRX_CONFIG
|
||||
overrides this default.
|
||||
.TP
|
||||
.BR \-v ", " \-\-verbose
|
||||
Enable verbose logging on standard error.
|
||||
.TP
|
||||
.BR \-h ", " \-\-help
|
||||
Show help for
|
||||
.B prx
|
||||
or for a subcommand.
|
||||
.SH COMMANDS
|
||||
.TP
|
||||
.BR on " [" \-\-skip\-engine "] [" \-\-dry\-run ]
|
||||
Enable proxy routing.
|
||||
Installs the nftables table
|
||||
.BR "inet prx" ,
|
||||
the policy rule and route, and (for extra bypass CIDRs) the bypass rules and
|
||||
routes, then ensures the engine service is running and runs health checks.
|
||||
If a blocking health check fails, every change made so far is rolled back and
|
||||
the command exits non\-zero.
|
||||
Re\-running
|
||||
.B on
|
||||
is idempotent.
|
||||
.TP
|
||||
.B off
|
||||
Disable proxy routing.
|
||||
Removes only the objects
|
||||
.B prx
|
||||
created: the
|
||||
.B "inet prx"
|
||||
table, any rules that look up
|
||||
.BR prx 's
|
||||
routing tables, and
|
||||
.BR prx 's
|
||||
routes.
|
||||
It never flushes the whole ruleset.
|
||||
Running
|
||||
.B off
|
||||
twice is a no\-op.
|
||||
.TP
|
||||
.B toggle
|
||||
Run
|
||||
.B on
|
||||
or
|
||||
.B off
|
||||
depending on the current state.
|
||||
.TP
|
||||
.BR status " [" \-\-json ]
|
||||
Print the current status.
|
||||
Reads the state snapshot and inspects the policy rules without requiring root.
|
||||
With
|
||||
.B \-\-json
|
||||
the result is emitted as JSON.
|
||||
.TP
|
||||
.B doctor
|
||||
Run diagnostics.
|
||||
Checks required binaries, the configuration, the engine configuration, mark
|
||||
collisions, the applied rules and the engine status.
|
||||
Exits non\-zero when a critical (local) problem is found, or when
|
||||
.B prx
|
||||
is enabled but the applied rules are inconsistent.
|
||||
.TP
|
||||
.BR bypass " add " \fICIDR\fR | \fIIP\fR | \fIDOMAIN\fR
|
||||
Add a destination to the bypass list.
|
||||
A CIDR or bare IP is additionally enforced at the routing layer: a route is
|
||||
installed in the bypass table and a destination\-based
|
||||
.B ip-rule
|
||||
is added, so traffic to it never enters the tunnel.
|
||||
A domain is recorded as an engine hint only.
|
||||
.TP
|
||||
.BR bypass " rm " \fICIDR\fR | \fIIP\fR | \fIDOMAIN\fR
|
||||
Remove an entry from the bypass list.
|
||||
.TP
|
||||
.B bypass ls
|
||||
List the bypass entries.
|
||||
.TP
|
||||
.BR logs " [" \-f | \-\-follow ]
|
||||
Show the proxy engine's journal output (via
|
||||
.BR journalctl (1)).
|
||||
.TP
|
||||
.BR init " [" \-\-force "] [" \-\-engine\-config "]"
|
||||
Write a default configuration file to the configured path.
|
||||
With
|
||||
.B \-\-engine\-config
|
||||
also generate a baseline engine (sing\-box) configuration.
|
||||
.TP
|
||||
.B version
|
||||
Print version information.
|
||||
.SH "ON OPTIONS"
|
||||
.TP
|
||||
.B \-\-skip\-engine
|
||||
Apply only the routing layer without starting or stopping the engine.
|
||||
Useful for testing and when the engine is managed separately.
|
||||
.TP
|
||||
.B \-\-dry\-run
|
||||
Validate the plan with
|
||||
.BR "nft \-c"
|
||||
without changing anything.
|
||||
.SH "INIT OPTIONS"
|
||||
.TP
|
||||
.B \-\-force
|
||||
Overwrite an existing configuration file.
|
||||
.TP
|
||||
.B \-\-engine\-config
|
||||
Also write a baseline engine configuration containing a TUN inbound and a
|
||||
placeholder outbound.
|
||||
.TP
|
||||
.BR \-\-engine\-config\-path " " \fIPATH\fR
|
||||
Path for the generated engine configuration.
|
||||
Defaults to
|
||||
.B engine.config_path
|
||||
from the prx configuration.
|
||||
.SH FILES
|
||||
.TP
|
||||
.I ~/.config/prx/config.json
|
||||
User configuration.
|
||||
.TP
|
||||
.I /run/prx/state.json
|
||||
Runtime snapshot written when
|
||||
.B prx
|
||||
is enabled; used by
|
||||
.B off
|
||||
and for rollback.
|
||||
.TP
|
||||
.I /run/prx/prx.lock
|
||||
Advisory lock held during
|
||||
.B on
|
||||
and
|
||||
.B off
|
||||
so concurrent runs do not interleave.
|
||||
.TP
|
||||
.I /etc/sing-box/config.json
|
||||
Default engine configuration.
|
||||
.TP
|
||||
.I /usr/share/polkit-1/actions/org.prx.policy
|
||||
Polkit action definition mapping
|
||||
.B prx-helper
|
||||
to
|
||||
.BR org.prx.manage .
|
||||
.TP
|
||||
.I /usr/lib/prx/prx-helper
|
||||
Installed location of the privileged helper.
|
||||
.B prx
|
||||
also searches
|
||||
.IR /usr/libexec/prx ,
|
||||
.IR /usr/local/lib/prx
|
||||
and
|
||||
.IR /usr/local/libexec/prx .
|
||||
.SH ENVIRONMENT
|
||||
.TP
|
||||
.B PRX_CONFIG
|
||||
Default configuration file path, used when
|
||||
.B \-\-config
|
||||
is not given.
|
||||
.TP
|
||||
.B PRX_HELPER
|
||||
Explicit path to the privileged helper, overriding the search locations.
|
||||
.SH "EXIT STATUS"
|
||||
.TP
|
||||
.B 0
|
||||
Success.
|
||||
.TP
|
||||
.B 1
|
||||
An error occurred; a message is printed to standard error.
|
||||
.TP
|
||||
.B 126
|
||||
Authorization was cancelled or is not permitted (from
|
||||
.BR pkexec ).
|
||||
.TP
|
||||
.B 127
|
||||
The privileged helper could not be started.
|
||||
.SH EXAMPLES
|
||||
Enable the proxy:
|
||||
.PP
|
||||
.RS 4
|
||||
.B prx on
|
||||
.RE
|
||||
.PP
|
||||
Enable only the routing layer, without touching the engine:
|
||||
.PP
|
||||
.RS 4
|
||||
.B prx on \-\-skip\-engine
|
||||
.RE
|
||||
.PP
|
||||
Validate without making changes:
|
||||
.PP
|
||||
.RS 4
|
||||
.B prx on \-\-dry\-run
|
||||
.RE
|
||||
.PP
|
||||
Keep a subnet out of the tunnel and refresh the rules:
|
||||
.PP
|
||||
.RS 4
|
||||
.B prx bypass add 203.0.113.0/24
|
||||
.RE
|
||||
.PP
|
||||
Check status as JSON:
|
||||
.PP
|
||||
.RS 4
|
||||
.B prx status \-\-json
|
||||
.RE
|
||||
.PP
|
||||
Disable the proxy:
|
||||
.PP
|
||||
.RS 4
|
||||
.B prx off
|
||||
.RE
|
||||
.SH "SEE ALSO"
|
||||
.BR prx-helper (1),
|
||||
.BR nft (8),
|
||||
.BR ip-rule (8),
|
||||
.BR ip-route (8),
|
||||
.BR pkexec (1),
|
||||
.BR sudo (8),
|
||||
.BR systemctl (1)
|
||||
.SH AUTHOR
|
||||
Amir Husayn Panahifar <ahp@panahifar.ir>.
|
||||
Reference in New Issue
Block a user