docs: add README and manual pages
This commit is contained in:
@@ -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