sshpiper/plugin/yaml
eesaanatluri 4fce1dcb45
feat: Decide upstream based on user's unix group membership (#536)
* feat: Decide upstream based on user's unix group membership

If a username is not defined, groupname is parsed. Check if the
user is part of that group and route them to the associated host
defined in the config file for the yaml plugin

* style: fix formatting with gofmt

* feat: Look up user groups only when groupname defined in yaml config

* fix: inefficient assignment because of unused var

* feat: fallback to next rule on group lookup failure

Instead of failing on group lookup errors, the matcher now skips the
groupname rule and proceeds to the next, eventually failing through to
the catchall rule.

* feat: test cases for group based routing in yaml plugin

* Revert "feat: fallback to next rule on group lookup failure"

This reverts commit 622ee9f1eb3157d04f57c068179bb74de8db3a1f.

Handles the error returned by getUserGroups instead of ignoring it,
to prevent potential runtime issues when user lookup fail

* feat: Check if a user is known to the system before group lookup

This will let the rule matching logic skip to the next pipe in the yaml
config when a user is not found on the system.
Note the variable name change from user to username to avoid ambiguity
dur to name collision with os/user package.

* feat: Avoid redundant user lookup

* feat: Improve error handling for user and group lookup failures

* feat: Use appropriate test user name for group routing
2025-04-07 23:53:16 -07:00
..
main.go Refactor plugin/yaml/main.go and plugin/yaml/yaml.go to support multiple YAML config files (#477) 2024-10-28 01:57:55 -07:00
README.md YAML Plugin add regex match group (#464) 2024-10-20 02:15:46 -07:00
schema.json feat: Decide upstream based on user's unix group membership (#536) 2025-04-07 23:53:16 -07:00
skel.go feat: Decide upstream based on user's unix group membership (#536) 2025-04-07 23:53:16 -07:00
yaml.go feat: Decide upstream based on user's unix group membership (#536) 2025-04-07 23:53:16 -07:00
yaml_test.go Refactor YAML schema to support multiple authorized keys and known hosts (#463) 2024-10-20 00:20:40 -07:00

yaml plugin for sshpiperd

The yaml plugin for sshpiperd is a simple plugin that allows you to use single yaml file to configure your sshpiperd.

some basic idea of yaml config file:

  • first matched pipe will be used.

  • any from in pipe fits downstream authentication will be considered as the pipe matched.

  • username_regex_match can be used to match with regex

    • to.Username can be template of regex match groups, example: from.username: "^password_(.*?)_regex$" and to.username: $1", will match password_user_regex to user, more sytax see https://pkg.go.dev/regexp#Regexp.Expand
  • authorized_keys, known_hosts are array path/to/target/file or single string, but there are also authorized_keys_data, known_hosts_data accepting base64 inline data, file and data will be merged if both are set

  • private_key is path/to/target/file, but there are also private_key_data accepting base64 inline data, file wins if both are set

  • magic placeholders in path, example usage: /path/to/$UPSTREAM_USER/file

    • DOWNSTREAM_USER: supported in private_key, known_hosts
    • UPSTREAM_USER: supported in authorized_keys, private_key, known_hosts
    • environment variables: supported in authorized_keys, private_key, known_hosts

Usage

sshpiperd yaml --config /path/to/sshpiperd.yaml

options

   --config value   path to yaml config file [$SSHPIPERD_YAML_CONFIG]
   --no-check-perm  disable 0400 checking (default: false) [$SSHPIPERD_YAML_NOCHECKPERM]

Config example

# yaml-language-server: $schema=https://raw.githubusercontent.com/tg123/sshpiper/master/plugin/yaml/schema.json
version: "1.0"
pipes:
- from:
    - username: "password_simple"
  to:
    host: host-password:2222
    username: "user"
    ignore_hostkey: true
- from:
    - username: "^password_(.*?)_regex$"
      username_regex_match: true
  to:
    host: host-password:2222
    username: "$1"
    ignore_hostkey: true
- from:
    - username: "publickey_simple"
      authorized_keys: 
      - /path/to/publickey_simple/authorized_keys
      - /path/to/publickey_simple/authorized_keys2
  to:
    host: host-publickey:2222
    username: "user"
    private_key: /path/to/host-publickey/id_rsa
    known_hosts_data: 
    - "base64_known_hosts_data"
    - "base64_known_hosts_data2"
- from:
    - username: ".*" # catch all    
      username_regex_match: true
      authorized_keys: /path/to/catch_all/authorized_keys
  to:
    host: host-publickey:2222
    username: "user"
    ignore_hostkey: true
    private_key: /path/to/host-publickey/id_rsa