Skip to content

Configuration

Ken Tobias edited this page Jun 22, 2026 · 8 revisions

Configuration

etr (client) options

etr [OPTIONS] [TARGET] [COMMAND]...

Arguments:
  [TARGET]              Remote host — user@host or host
  [COMMAND]...          Optional command to run instead of an interactive shell (exits when command exits)

Connection options:
  -s, --ssh-port PORT                          SSH port for bootstrap [default: 22 or config ssh_port]
  --server-path PATH                           Path to etrs on the remote host [default: etrs or config server_path]
  -v, -vv, -vvv                                Verbosity level (see Verbosity levels below)

Port forwarding:
  -L [bind:]local_port:host:port[/tcp|/udp]    Forward a local port to a remote address (repeatable)
  -R [bind:]remote_port:host:port[/tcp|/udp]   Forward a remote port back to a local address (repeatable)
  -g, --gateway-ports                          Bind local/remote listeners on all interfaces instead of loopback

Environment:
  --env KEY[=VALUE]                            Set or forward an env var in the remote shell (repeatable)

Logging:
  --log-path PATH                              Path to the client log file [default: ~/.local/state/etr/etr.log]
  --server-log-path PATH                       Path to the server log file on remote host [default: ~/.local/state/etr/etrs.log]

Configuration:
  --generate-config                            Print a fully-commented default config to stdout
  --write-config [PATH]                        Write default config to PATH [default: ~/.config/etr/config.toml]
  --merge-config                               Add any missing options (as comments) to the existing config file

Utility:
  --completions SHELL                          Print shell completions and exit (bash, zsh, fish, nushell, elvish, power-shell)
  -h, --help
  -V, --version

Config file

etr reads $XDG_CONFIG_HOME/etr/config.toml (usually ~/.config/etr/config.toml) on startup. All fields are optional. CLI flags take precedence over config file values.

To get a starter config with every option documented:

etr --write-config          # write to ~/.config/etr/config.toml
etr --generate-config       # print to stdout instead

To update an existing config after upgrading (adds new options as comments, never removes anything):

etr --merge-config

[client] section

Key Type Default Description
ssh_port integer 22 SSH port used for the bootstrap connection. Equivalent to -s.
server_path string "etrs" Path to the etrs binary on remote hosts. Equivalent to --server-path.
log_path string ~/.local/state/etr/etr.log Client log file path. Equivalent to --log-path. Only written when -v or higher is passed.
server_log_path string ~/.local/state/etr/etrs.log Server log file path on the remote host. Equivalent to --server-log-path.
gateway_ports boolean false Bind local forwarded ports on all interfaces instead of loopback. Equivalent to -g.
forward array of strings [] Default local port forwards, applied to every connection. Same syntax as -L.
reverse_forward array of strings [] Default remote port forwards, applied to every connection. Same syntax as -R.
env array of strings [] Environment variables to set or forward in the remote shell. "KEY=VALUE" sets the variable; "KEY" forwards it from the local environment. Equivalent to --env.

[server] section

Key Type Default Description
reconnect_timeout integer (seconds) 1800 How long etrs keeps a session alive while the client is disconnected. Overridden by --reconnect-timeout or ETR_SERVER_NETWORK_TMOUT.

Example config

[client]
ssh_port = 2222
server_path = "/home/user/.cargo/bin/etrs"
env = ["EDITOR", "COLORTERM"]
forward = ["5432:db-host:5432"]

[server]
reconnect_timeout = 3600   # keep session alive for 1 hour

Port forwarding

# Forward local port 5432 to db-host:5432 via jumphost (TCP, default)
etr -L 5432:db-host:5432 user@jumphost

# Use the same port number on both ends
etr -L db-host:5432 user@jumphost

# UDP forwarding
etr -L 5353:8.8.8.8:53/udp user@jumphost

# Multiple forwards in one session
etr -L 5432:db:5432 -L 6379:cache:6379 user@host

# Reverse forwarding: expose a local service on the remote host
etr -R 8080:localhost:8080 user@host

# Reverse UDP forwarding
etr -R 5353:localhost:53/udp user@host

# Bind local listener on all interfaces (not just loopback)
etr -g -L 5432:db-host:5432 user@jumphost

# Set default forwards in config so they apply to every connection
# [client]
# forward = ["5432:db-host:5432", "6379:cache:6379"]

Port forwards run alongside the PTY session and survive the same reconnect cycle. Each TCP connection gets its own QUIC stream. UDP uses a dedicated QUIC stream per -L/-R spec, and multiple concurrent UDP senders on the same forwarded port are supported — each source address gets its own ephemeral socket so replies are routed correctly.

By default, local (-L) and remote (-R) listeners bind to loopback only (127.0.0.1 + [::1]). Pass -g / --gateway-ports to bind on all interfaces, or specify an explicit bind address in the spec (e.g. -L 0.0.0.0:5432:db:5432).

etrs (server) options

etrs is normally started by etr automatically. You can run it manually for testing:

etrs [OPTIONS]

Options:
  -p, --port PORT              QUIC port to bind [default: 0 = OS-assigned]
  -b, --bind ADDR              IP address to bind [default: [::] = dual-stack]
  --reconnect-timeout SECS     Session keep-alive timeout [default: 1800 or config server.reconnect_timeout]
  -v, -vv, -vvv                Verbosity level (see below)
  --log-path PATH              Server log file path [default: ~/.local/state/etr/etrs.log]
  --completions SHELL          Print shell completions and exit
  -h, --help
  -V, --version

Verbosity levels

Both binaries use SSH-style -v counting:

Flag What you see
(none) Silent
-v Connection events: connect, reconnect, disconnect, timeout
-vv QUIC details, TLS cipher suite, session ID, port
-vvv Stream trace: every chunk type, sequence number, size

Client verbose logs are written to ~/.local/state/etr/etr.log by default during a live session (to avoid corrupting the raw-mode terminal display), or to the path specified by --log-path or config log_path. A single line on stderr tells you the path. Watch it with:

tail -f ~/.local/state/etr/etr.log

Server logs go to ~/.local/state/etr/etrs.log by default on the remote host, or to the path specified by client --server-log-path / config server_log_path or server --log-path.

Server not in PATH

If etrs is installed somewhere not on the SSH session PATH:

etr --server-path /home/user/.cargo/bin/etrs user@host

Or set it permanently in the config:

[client]
server_path = "/home/user/.cargo/bin/etrs"

SSH non-interactive sessions often have a minimal PATH. The safest fix is to add ~/.cargo/bin to PATH unconditionally in ~/.bashrc or ~/.zshrc (not just in the interactive section).

Shell completions

# Zsh
etr --completions zsh > ~/.zfunc/_etr
# then add `fpath=(~/.zfunc $fpath)` and `autoload -Uz compinit && compinit` to ~/.zshrc

# Bash
etr --completions bash > /etc/bash_completion.d/etr

# Fish
etr --completions fish > ~/.config/fish/completions/etr.fish

# Nushell
etr --completions nushell | save completions-etr.nu

Clone this wiki locally