Command reference
psh(1) — Client
Connection options, identities, host trust, signals, and exit status.
60c72c2bView original On this page
Read this manual locally with man 1 psh, or download its roff source
.
NAME
psh - pirate-shell remote login client and identity manager
SYNOPSIS
psh [-F config] [-p port] [-i identity] [-t|-T] [--batch] [--host-key public.pem] [--known-hosts file] [user@]host [-- command ...]
psh keygen -f private.pem [--no-passphrase]
psh fingerprint public.pem
psh host trust host --host-key public.pem [--known-hosts file] [-p port]
psh host forget host [--known-hosts file] [-p port]
psh -h|--help|--version
DESCRIPTION
psh opens one remote shell session over encrypted UDP to pshd(8). The protocol requires DTLS 1.3, hybrid X25519 + ML-KEM-768 key exchange, ChaCha20-Poly1305 encryption, and paired Ed25519 + ML-DSA-87 host and user identities. Both identity components are mandatory. There is no legacy fallback or SSH wire compatibility.
The host may be a hostname, address, or client configuration alias. An explicit user overrides the alias user; otherwise an alias supplies the user, or the local effective account name is used. Options must precede the connection target. IPv6 connection addresses are supplied without brackets; the port is a separate option.
With no command, the server starts the account's configured login shell. Otherwise the client joins command arguments with spaces and the server passes the resulting string to that shell with -c. Argument boundaries are not preserved. Quote a complete command locally when it contains pipes, redirects, or shell expansions. Commands are limited to 8192 bytes after joining.
A PTY is allocated automatically only when no command is supplied and local standard input is a terminal. Without a PTY, standard output and standard error are separate byte streams. With a PTY, terminal output is combined.
CONNECTION OPTIONS
- -F config
- Read the specified client YAML file instead of the default configuration. An explicitly selected file must exist and pass validation.
- -p port
- Use UDP port 1 through 65535. Overrides an alias port. The default is 2222.
- -i identity
- Use this paired private identity instead of the alias or global identity. Relative command-line paths use the current working directory.
- -t
- Request a PTY, including for a remote command.
- -T
- Disable PTY allocation. Use for binary input/output and separate stderr. If both PTY options are given, the last takes effect.
- --batch
- Disable local passphrase and first-use trust prompts. An encrypted identity cannot be unlocked in this mode. A saved matching pin or a matching --host-key file is required.
- --host-key public.pem
- Require the complete host identity to match this protected public file. A new matching identity is saved in the trust store without a prompt. An existing conflicting pin still fails and is never replaced implicitly.
- --known-hosts file
- Override the configured or default trust store. Relative command-line paths use the current working directory.
- -h, --help
- Print usage and exit.
- --version
- Print the client version and exit.
IDENTITY COMMANDS
- keygen -f private.pem [--no-passphrase]
- Create a new paired private identity and a public companion whose name is the private filename plus .pub. Both destination files must be absent. The private file contains two PKCS#8 PEM objects; the public file contains two SPKI PEM objects, Ed25519 first and ML-DSA-87 second. These are not OpenSSH key formats.
- By default, prompt twice on a controlling terminal for a matching, nonempty local passphrase. Both private components use that passphrase with separate encryption salts and IVs. The --no-passphrase option explicitly requests an unencrypted private file, as needed for unattended daemon host keys and batch clients. Private files must be owned by the effective user and have mode 0600 or stricter.
- fingerprint public.pem
- Print the complete-pair SHA512: fingerprint of a protected paired SPKI PEM public file. Use the public companion created by key generation.
HOST TRUST COMMANDS
These commands operate locally. They do not contact the server, load client YAML, or expand aliases. Supply the actual hostname and port used by the connection. Hostnames are normalized to lowercase; different names for the same server have separate pins.
- host trust host --host-key public.pem
- Install a verified complete-pair public identity. Refuse an existing conflicting pin. Obtain the public file through a trusted channel first.
- host forget host
- Remove the pin for this host and port, permitting deliberate reprovisioning.
Both commands accept -p (default 2222) and --known-hosts. Their default store is in the effective account's home directory, even if client YAML would select another store. Pass the same explicit store and port when replacing a connection's pin.
TRUST AND AUTHENTICATION
The client verifies both host identity components before revealing the user identity or command. A previously unseen host requires an explicit yes on a controlling terminal, unless a matching public identity was supplied. Verify the complete-pair fingerprint through an independent trusted channel before accepting. Possession of a key alone does not establish host trust.
Changed host keys always fail, including when a different --host-key file is supplied. Remove the old pin deliberately before provisioning a verified replacement. Legacy SHA256 pins cannot authenticate a psh/3 identity. Keep the protected .lock sidecar alongside the trust store for concurrent updates.
The privileged server broker independently verifies both client signatures and authorization for the requested Linux account. Remote password and keyboard-interactive authentication are not supported. Local private-key passphrases never authenticate a remote account.
SESSION BEHAVIOR
Authenticated keepalives run every 15 seconds; 120 seconds without authenticated peer traffic expires the connection and triggers remote process cleanup. Client IP or port changes preserve the live connection after encrypted return-path validation. A new client invocation starts a new session; detached reattachment is not supported.
SIGNALS
These handlers apply during an established session:
- SIGWINCH
- Forward terminal size changes when using a PTY.
- SIGUSR1
- Replace the local UDP socket and request migration to a fresh local port. This does not forward SIGUSR1 to the remote process.
- SIGINT, SIGTERM, SIGHUP
- Request delivery of the signal to the remote process group. In PTY mode, terminal control characters are also passed through terminal input.
ENVIRONMENT
- HOME
- Select the home directory used to find the default client configuration. If unset or empty, use the effective account's home. The result must be absolute. Default identity and trust-store paths use the effective account's home from the account database independently of this variable.
XDG_CONFIG_HOME is not consulted. Passphrases are read from the controlling terminal, not command-line arguments, environment variables, or piped session stdin.
FILES
- ~/.config/psh/config.yaml
- Optional default client configuration. If present, it must pass validation. See psh_config(5).
- ~/.config/psh/id_psh_hybrid.pem
- Default paired private identity when no configuration overrides it.
- ~/.config/psh/known_hosts
- Default host trust store. Strict tab-separated hostname, port, and fingerprint records; this is not the OpenSSH known_hosts format.
- ~/.config/psh/known_hosts.lock
- Protected coordination file for trust-store operations.
EXIT STATUS
For a completed session, return the remote shell's exit status (0 through 255). Remote signal termination maps to 128 plus the signal number. Connection, authentication, protocol, and local session failures return 255; a remote exit of 255 is therefore indistinguishable by exit status alone.
Local identity and host-management commands return 0 on success and 1 on failure. Usage errors return 2. Help and version requests return 0.
EXAMPLES
psh keygen -f ~/.config/psh/id_psh_hybrid.pem psh lab psh -F client.yaml alice@host -- 'uname -a; id' psh -t lab -- 'stty size' psh -T lab -- cat < input.bin > output.bin psh fingerprint host_psh_hybrid.pem.pub psh host trust host --host-key host_psh_hybrid.pem.pub psh --batch -i client.pem alice@host -- 'id -u'
CAVEATS
psh is an experimental protocol and implementation without an external security audit. It provides no agent forwarding, port forwarding, file transfer, PAM integration, or multiple sessions per connection.
SEE ALSO
psh_config(5), pshd(8)