@prekucki/iroh-proxy
v0.1.0
Published
`iroh-proxy` is a small Rust CLI that forwards local TCP services over [iroh](https://github.com/n0-computer/iroh).
Readme
iroh-proxy
iroh-proxy is a small Rust CLI that forwards local TCP services over iroh.
It lets you expose a service on one machine and access it locally on another machine through an iroh connection.
Status
Early prototype intended for simple TCP forwarding workflows.
Install / Build
cargo build --releaseBinary path:
./target/release/iroh-proxyCommands
iroh-proxy [--key-file <path>] [--config-file <path>] <command>server
Run the long-lived proxy server that exposes a platform-native control API.
server loads initial served routes from config ([serve]) and persisted forward listeners ([forward]).
iroh-proxy serverInstall a user systemd unit:
iroh-proxy server --installThis writes:
~/.config/systemd/user/iroh-proxy.serviceThen enable it:
systemctl --user daemon-reload
systemctl --user enable --now iroh-proxy.servicestatus
Check whether the live proxy server is running and show current counts.
iroh-proxy status
iroh-proxy status --connectionstui
Open a ratatui dashboard for live server inspection and control.
iroh-proxy tuiOptional icon behavior:
USE_NERD_FONTS=1enables Nerd Font icons in route tabs and pane titlesUSE_NERD_FONTS=0forces plain labels- unset uses auto-detection (
TERM/locale); plain labels are used when detection is not suitable
In the TUI:
- auto layout mode:
- full mode at
>=160x36: always-visible panes forServices,Forwards, andActive Connections - compact mode at
<160columns or<36rows: routes table (Services/Forwards) stacked aboveConnections
- full mode at
- event-driven live updates from control-plane state signals
- dialogs to add/remove services and forwards
- remove-forward mode toggle:
- runtime only (suspend listener)
- runtime + config (persistent remove)
Keybinds:
- full mode:
Tab/Shift-Tabchange focused pane - compact mode:
Tab/Shift-Tabswitch focused row (Routes/Connections) - compact mode:
Left/Rightswitch routes view (Services/Forwards) Up/Down: move selection- when backend is up:
a: add in focused paned: remove selected item
- when backend is down:
s: start backend
r: resync snapshotq: quit
add-serve
Add a served TCP service route to the live proxy server.
If the server is not running, add-serve starts it in the background.
iroh-proxy add-serve <service-name> <target-host:port>Use -p to persist the rule into config ([serve].services):
iroh-proxy add-serve -p <service-name> <target-host:port>Example:
iroh-proxy add-serve -p ollama localhost:11434del-serve
Remove a served TCP service route from the running proxy server.
iroh-proxy del-serve <service-name>Example:
iroh-proxy del-serve ollamaadd-forward
Add a local forward rule to the running proxy server.
If the server is not running, add-forward starts it in the background.
iroh-proxy add-forward <listen-host:port> <endpoint-id>/tcp/<service-name>add-forward enables close-on-request mode by default, with a 2s timeout after local request upload EOF.
Tune it with:
iroh-proxy add-forward --close-on-request-timeout-secs <seconds> <listen-host:port> <endpoint-id>/tcp/<service-name>Use -p to persist the rule into config ([forward].services):
iroh-proxy add-forward -p <listen-host:port> <endpoint-id>/tcp/<service-name>Example:
iroh-proxy add-forward 127.0.0.1:5050 74f3645e8016bb34970c516acde5240e85ed4387dbe3aeb9189f50db5525bd76/tcp/appforward
Forward to a remote iroh service path in two modes.
iroh-proxy forward <endpoint-id>/tcp/<service-name>
iroh-proxy forward <listen-host:port> <endpoint-id>/tcp/<service-name>In listen mode, close-on-request is enabled by default (2s). Override with:
iroh-proxy forward --close-on-request-timeout-secs <seconds> <listen-host:port> <endpoint-id>/tcp/<service-name>Examples:
# stdio mode (for ssh ProxyCommand)
iroh-proxy forward <endpoint-id>/tcp/ssh
# local listener mode
iroh-proxy forward 127.0.0.1:11435 <endpoint-id>/tcp/ollamaSSH example:
Host gpu-iroh
HostName ignored
User your-user
ProxyCommand iroh-proxy forward 74f3645e8016bb34970c516acde5240e85ed4387dbe3aeb9189f50db5525bd76/tcp/sshforward-config
Bind multiple local listeners from config.toml.
iroh-proxy forward-config ./config.tomlConfig file
Default config path:
~/.config/iroh-proxy/config.tomlSee config.example.toml.
[serve]
[[serve.services]]
name = "ollama"
target = "localhost:11434"
[[serve.services]]
name = "vllm"
target = "localhost:8000"
[forward]
[[forward.services]]
listen = "127.0.0.1:11435"
remote = "<endpoint-id>/tcp/ollama"
close_on_request_timeout_secs = 2
[[forward.services]]
listen = "127.0.0.1:18000"
remote = "<endpoint-id>/tcp/vllm"
close_on_request_timeout_secs = 2Sections are optional:
[serve]is used byserverandadd-serve -p[forward]is used byserver(persisted runtime listeners),add-forward -p, andforward-config
End-to-end example
On service host:
iroh-proxy server
iroh-proxy add-serve -p ollama localhost:11434Then get endpoint id:
iroh-proxy statusOn client host:
iroh-proxy forward 127.0.0.1:11435 <endpoint-id>/tcp/ollamaNow local clients can use 127.0.0.1:11435 as if ollama were local on the service host.
Keys and identity
serveruses a persistent key by default:~/.config/iroh-proxy/secret_key
forwardandforward-configuse an ephemeral in-memory key by default (new id each run).- Use
--key-fileto force persistent key behavior for any command.
Discovery
iroh-proxy uses discovery through:
- local mDNS (LAN discovery)
- pkarr (relay + DHT)
Notes and limits
- Supports only TCP forwarding paths in the form
<endpoint-id>/tcp/<name>. - No authentication/authorization layer beyond iroh endpoint identity yet.
- No encryption-termination or HTTP-aware features; this is raw TCP stream proxying.
- Control API backend status:
- Linux: DBus (
zbus) implemented - macOS: sessionless
zbusP2P over UDS ($TMPDIR/iroh-proxy/control.sock) - Windows: sessionless
zbusP2P over UDS (%TEMP%\\iroh-proxy\\control.sock) status/tui/add-serve/add-forward/del-*use the same control interface across these transports
- Linux: DBus (
Development
cargo fmt
cargo check
cargo run -- --helpLicense
TBD.
