Fixed & WorkingDir Plugins
Relevant source files
The following files were used as context for generating this wiki page:
The Fixed and WorkingDir plugins are core routing components of sshpiperd, responsible for determining how a downstream SSH client is mapped and authenticated to an upstream SSH server. While the Fixed plugin provides a static routing mechanism primarily used for simple demos and direct proxying, the WorkingDir plugin offers a dynamic, filesystem-based routing approach similar to a traditional Unix /home directory structure.
These plugins act as gRPC servers that interact with the main sshpiperd daemon. They implement callback functions that sshpiperd invokes during the SSH handshake to retrieve upstream connection details, such as the host, port, and required authentication credentials.
Sources: README.md:12-16, CONTRIBUTING.md:43-46
Fixed Plugin
The Fixed plugin is the simplest routing implementation in the sshpiper ecosystem. It is designed to route all incoming connections to a single, pre-defined upstream target. It is often used to verify the basic functionality of an sshpiperd installation.
Architecture and Logic
The plugin initializes by parsing a mandatory --target flag. When a downstream client provides a password, the plugin's PasswordCallback is triggered. This callback ignores the host key of the upstream and forwards the provided password directly to the target.
Sources: plugin/fixed/main.go:21-43
The diagram above shows the static flow where every connection is mapped to the same destination.
Sources: plugin/fixed/main.go:34-42
Configuration
| Flag | Environment Variable | Description |
|---|---|---|
--target | SSHPIPERD_FIXED_TARGET | The static upstream SSH endpoint address (e.g., 127.0.0.1:22). |
| Sources: plugin/fixed/main.go:19-23 |
WorkingDir Plugin
The WorkingDir plugin provides a directory-based configuration system. It maps the downstream username to a subdirectory within a specified root directory (defaulting to /var/sshpiper). This plugin supports more advanced features, including Two-Factor Authentication (2FA) via TOTP and recursive upstream searching.
Sources: plugin/workingdir/main.go:21-25, README.md:113
Filesystem Structure
The plugin expects a specific file structure within the user's directory to manage routing and authentication.
Sources: plugin/workingdir/workingdir.go:20-25
| File Name | Description |
|---|---|
sshpiper_upstream | Contains the upstream host address (and optional username in user@host format). |
authorized_keys | Standard SSH public keys for downstream authentication. |
id_rsa | The private key used by sshpiper to authenticate against the upstream server. |
known_hosts | Used to verify the upstream server's host key if strict checking is enabled. |
totp | Contains the secret key for Time-based One-Time Password verification. |
| Sources: plugin/workingdir/workingdir.go:20-25, plugin/workingdir/main.go:87-89 |
Authentication Flow and 2FA
The plugin dynamically determines available authentication methods. If check-totp is enabled, the plugin forces a keyboard-interactive challenge before allowing the connection to proceed.
Sources: plugin/workingdir/main.go:66-78
The sequence shows how the WorkingDir plugin intercepts the auth flow to inject a TOTP requirement.
Sources: plugin/workingdir/main.go:80-112
Key Implementation Details
- Username Validation: The plugin enforces strict username rules based on Debian defaults (
^[a-z_][-a-z0-9_]{0,31}$) unless--allow-baduser-nameis set. Sources: plugin/workingdir/workingdir.go:18, plugin/workingdir/main.go:26-30 - Permission Checking: By default, the plugin checks that files in the working directory have secure permissions (no access for group/others, i.e.,
0400). Sources: plugin/workingdir/workingdir.go:47-51 - Upstream Parsing: The
sshpiper_upstreamfile is parsed to extract the host and an optional user. If no user is specified, the downstream user is used. Sources: plugin/workingdir/workingdir.go:78-100
Configuration
| Flag | Env Var | Default | Description |
|---|---|---|---|
--root | SSHPIPERD_WORKINGDIR_ROOT | /var/sshpiper | Path to the root directory containing user subdirectories. |
--allow-baduser-name | ...ALLOWBADUSERNAME | false | Disables strict regex validation of usernames. |
--no-check-perm | ...NOCHECKPERM | false | Disables the 0400 file permission check. |
--strict-hostkey | ...STRICTHOSTKEY | false | Requires upstream host keys to be in known_hosts. |
--check-totp | ...CHECKTOTP | false | Enables 2FA via a totp file in the user directory. |
| Sources: plugin/workingdir/main.go:20-53 |
Data Structures and Communication
Both plugins utilize the libplugin library to communicate with sshpiperd over gRPC. They share common data structures defined in the plugin.proto file.
Sources: libplugin/plugin.pb.go:56-120
Connection Metadata (ConnMeta)
Used to pass information about the incoming connection to the plugin.
user_name: The username provided by the client.from_addr: The source IP and port of the client.uniq_id: A unique UUID for the session.metadata: A map of additional connection properties.
Sources: libplugin/plugin.pb.go:68-75
Upstream Definition
The plugin returns an Upstream message to sshpiperd containing:
uri: The destination address (replaces deprecatedhost/port).user_name: The username to use for the upstream connection.auth: A one-of field containingpassword,private_key, ornone.
Sources: libplugin/plugin.pb.go:122-140
Summary
The Fixed plugin serves as a straightforward entry point for static proxying, while the WorkingDir plugin provides a robust, filesystem-based management system for multi-user environments. WorkingDir's support for TOTP and strict permission checking makes it suitable for production environments requiring localized, file-based configuration. Both plugins demonstrate the extensibility of the sshpiper architecture via its gRPC-based plugin system.
Sources: README.md:113-126, CONTRIBUTING.md:65-71