finish readme
This commit is contained in:
parent
6b3ebecf9e
commit
e1aa1c9823
5 changed files with 180 additions and 183 deletions
294
README.md
294
README.md
|
|
@ -1,15 +1,24 @@
|
|||
# SSH Piper
|
||||
# sshpiper 🖇
|
||||
|
||||

|
||||
[](https://goreportcard.com/report/github.com/tg123/sshpiper)
|
||||
[](https://hub.docker.com/r/farmer1992/sshpiperd)
|
||||
|
||||
SSH Piper works as a proxy-like ware, and route connections by `username`, `src ip` , etc.
|
||||
`sshpiper` is the reverse proxy for sshd. all protocols, including ssh, scp, port forwarding, running on top of ssh are supported.
|
||||
|
||||
*Note:* this is `v1` version, checkout legacy `v0` [here](https://github.com/tg123/sshpiper/tree/v0)
|
||||
|
||||
### Overview and Terminology
|
||||
|
||||
* `downstream`: the client side, typicall ssh client
|
||||
* `upstream`: the server side, typicall sshd server
|
||||
* `plugin`: handles the routing from `downstream` to `upstream`. the `plugin` are also repsonsible for the mapping authentication methods to upstream. for exmaple, the downstream may use password as authentication method, but the upstream may receive public key authentication mapped by `sshpiper`.
|
||||
* `addtional chanllenge`: some `plugin` will not do routing but add an additional challenges to ssh authentication to `upstream`. for example, the `downstream` may be asked for two factor authentication provided by the `plugin`.
|
||||
|
||||
```
|
||||
+---------+ +------------------+ +-----------------+
|
||||
| | | | | |
|
||||
| Bob +----ssh -l bob----+ | SSH Piper +-------------> Bob' machine |
|
||||
| Bob +----ssh -l bob----+ | sshpiper +-------------> Bob' machine |
|
||||
| | | | | | | |
|
||||
+---------+ | | | | +-----------------+
|
||||
+---> pipe-by-name--+ |
|
||||
|
|
@ -20,140 +29,89 @@ SSH Piper works as a proxy-like ware, and route connections by `username`, `src
|
|||
+---------+ +------------------+ +-----------------+
|
||||
|
||||
|
||||
Downstream SSH Piper Upstream
|
||||
downstream sshpiper upstream
|
||||
|
||||
```
|
||||
|
||||
## Demo
|
||||
|
||||
[](https://asciinema.org/a/222825)
|
||||
|
||||
## Quick start
|
||||
|
||||
Just run `showme.sh` in [sshpiperd example directory](sshpiperd/example)
|
||||
or
|
||||
Copy paste command below to run
|
||||
### Build
|
||||
|
||||
```
|
||||
git clone https://github.com/tg123/sshpiper
|
||||
cd sshpiper
|
||||
git submodule update --init --recursive
|
||||
|
||||
cd sshpiperd/example/
|
||||
./showme.sh
|
||||
mkdir out
|
||||
go build -o out ./...
|
||||
```
|
||||
|
||||
the example script will setup a sshpiper server using
|
||||
```
|
||||
bitbucket -> bitbucket@bitbucket.org:22 # ssh 127.0.0.1 -p 2222 -l bitbucket
|
||||
github -> github@github.com:22 # ssh 127.0.0.1 -p 2222 -l github
|
||||
gitlab -> gitlab@gitlab.com:22 # ssh 127.0.0.1 -p 2222 -l gitlab
|
||||
```
|
||||
## Run simple demo
|
||||
|
||||
connect to gitlab
|
||||
### start dummy sshd server
|
||||
|
||||
```
|
||||
$ ssh 127.0.0.1 -p 2222 -l gitlab
|
||||
Permission denied (publickey).
|
||||
docker run -d -e USER_NAME=user -e USER_PASSWORD=pass -e PASSWORD_ACCESS=true -p 127.0.0.1:5522:2222 lscr.io/linuxserver/openssh-server
|
||||
```
|
||||
|
||||
### start `sshpiperd` with `fixed` plugin targetting the dummy sshd server
|
||||
|
||||
```
|
||||
sudo ./out/sshpiperd ./out/fixed --target 127.0.0.1:5522
|
||||
```
|
||||
|
||||
### test ssh connection (password: `pass`)
|
||||
|
||||
```
|
||||
ssh 127.0.0.1 -l user -p 2222
|
||||
```
|
||||
|
||||
### ➕ math before login?
|
||||
|
||||
Here illustrates the example of `addional challenge` before the `fixed` plugin.
|
||||
|
||||
```
|
||||
sudo ./out/sshpiperd --log-level=trace ./out/simplemath -- ./out/fixed --target 127.0.0.1:5522
|
||||
```
|
||||
|
||||
## Plugins
|
||||
|
||||
### icons
|
||||
|
||||
* 🔀: routing plugin
|
||||
* 🔒: addtional challenge plugin
|
||||
|
||||
Plugin list
|
||||
|
||||
* [workingdir](plugin/workingdir/) 🔀: ask for working directory before login, demo purpose
|
||||
* [azdevicecode](plugin/azdevicecode/) 🔒: ask user to enter [azure device code](https://docs.microsoft.com/en-us/azure/active-directory/develop/v2-oauth2-device-code) before login
|
||||
* [fixed](plugin/fixed/) 🔀: fixed targetting the dummy sshd server
|
||||
* [simplemath](plugin/simplemath/) 🔒: ask for very simple math question before login, demo purpose
|
||||
|
||||
|
||||
## Screening recording
|
||||
|
||||
`sshpiperd` support recording the screen in `typescript` format (not the lang). The format is compatible with [scriptreplay(1)](https://linux.die.net/man/1/scriptreplay)
|
||||
|
||||
To use it, start sshpiperd with `--typescript-log-dir loggingdir`
|
||||
|
||||
Example:
|
||||
|
||||
```
|
||||
ssh user_name@127.0.0.1 -p 2222
|
||||
... do some commands
|
||||
exit
|
||||
|
||||
|
||||
$ cd loggingdir/user_name
|
||||
$ ls *.timing *.typescript
|
||||
1472847798.timing 1472847798.typescript
|
||||
|
||||
$ scriptreplay -t 1472847798.timing 1472847798.typescript # will replay the ssh session
|
||||
```
|
||||
|
||||
|
||||
connect to github.com
|
||||
|
||||
```
|
||||
$ ssh 127.0.0.1 -p 2222 -l github
|
||||
Permission denied (publickey).
|
||||
```
|
||||
|
||||
## Install
|
||||
|
||||
### Build yourself [Go 1.18]
|
||||
|
||||
```
|
||||
git clone https://github.com/tg123/sshpiper.git
|
||||
cd sshpiper
|
||||
git submodule update --init --recursive
|
||||
cd sshpiperd
|
||||
go build
|
||||
```
|
||||
|
||||
### with [Docker image](https://registry.hub.docker.com/r/farmer1992/sshpiperd/)
|
||||
|
||||
```
|
||||
docker run farmer1992/sshpiperd
|
||||
```
|
||||
|
||||
Run with [Workding Dir upstream driver](sshpiperd/upstream/workingdir/README.md)
|
||||
|
||||
```
|
||||
docker run -d -p 2222:2222 \
|
||||
-v /etc/ssh/ssh_host_rsa_key:/etc/ssh/ssh_host_rsa_key \
|
||||
-v /YOUR_WORKING_DIR:/var/sshpiper \
|
||||
farmer1992/sshpiperd
|
||||
```
|
||||
|
||||
Run with [Additional Challenge](#additional-challenge---challenger-driver)
|
||||
|
||||
### with [Snap](https://snapcraft.io/sshpiperd)
|
||||
|
||||
[](https://snapcraft.io/sshpiperd)
|
||||
|
||||
```
|
||||
sudo snap install sshpiperd
|
||||
```
|
||||
|
||||
configure with snap
|
||||
|
||||
```
|
||||
sudo snap set sshpiperd 'port=3333'
|
||||
|
||||
sudo snap restart sshpiperd
|
||||
```
|
||||
|
||||
_NOTE:_
|
||||
* Default working dir for snap verion is `/var/snap/sshpiperd/common`
|
||||
|
||||
|
||||
|
||||
## Configuration
|
||||
|
||||
sshpiper provides 3 pluginable components to highly customize your piper
|
||||
|
||||
* [Upstream Driver](#upstream-Driver---upstream-driver)
|
||||
* [Additional Challenge](#additional-challenge---challenger-driver)
|
||||
* [Auditor](#auditor-for-pipes---auditor-driver)
|
||||
|
||||
`sshpiperd daemon -h` to learn more
|
||||
|
||||
### Upstream Driver (`--upstream-driver=`)
|
||||
|
||||
Upstream driver helps sshpiper to find which upstream host to connect and how to connect.
|
||||
|
||||
For example, you can change the username when connecting to upstream sshd by config upstream driver
|
||||
|
||||
Available Upstream Drivers
|
||||
|
||||
* [Workding Directory](sshpiperd/upstream/workingdir/README.md)
|
||||
|
||||
Working Dir is a /home-like directory. SSHPiperd read files from workingdir/[username]/ to know upstream's configuration.
|
||||
|
||||
* [YAML](sshpiperd/upstream/yaml/README.md)
|
||||
|
||||
YAML based config file driver
|
||||
|
||||
* [gRPC Driver](sshpiperd/upstream/grpcupstream/README.md)
|
||||
|
||||
Everything on remote gRPC server, including the private key, no state stored on sshpiperd server.
|
||||
|
||||
* [Database Driver](sshpiperd/upstream/database/README.md)
|
||||
|
||||
Database upstream driver connected to popular databases, such as mysql, pg or sqlite etc to provide upstream's information.
|
||||
|
||||
* [Kubernetes Driver](sshpiperd/upstream/kubernetes/README.md)
|
||||
|
||||
Kubernetes drive can configure pipe with CRD.
|
||||
|
||||
#### How to do public key authentication when using sshpiper
|
||||
## Public key authentication when using sshpiper (Private key remapping)
|
||||
|
||||
During SSH publickey auth, [RFC 4252 Section 7](http://tools.ietf.org/html/rfc4252#section-7),
|
||||
ssh client sign `session_id` and some other data using private key into a signature `sig`.
|
||||
|
|
@ -163,19 +121,18 @@ However, sshpiper actually holds two ssh connection, and it is doing what `the m
|
|||
the two ssh connections' `session_id` will never be the same, because they are hash of the shared secret. [RFC 4253 Section 7.2](http://tools.ietf.org/html/rfc4253#section-7).
|
||||
|
||||
|
||||
To support publickey auth, sshpiper will modify the `sig` using a private key provided by upstream driver.
|
||||
e.g. (`id_rsa`) in the `workingdir/[username]/`.
|
||||
To support publickey auth, `sshpiper` routing plugin must provide a new private key for the `upstream` to sign the `session_id`. This new private key is called `mapping key`.
|
||||
|
||||
How this work
|
||||
|
||||
```
|
||||
+------------+ +------------------------+
|
||||
| | | |
|
||||
| client | | SSH Piper |
|
||||
| client | | sshpiper |
|
||||
| PK_X +--------> | |
|
||||
| | | v |
|
||||
| | | Check PK_X |
|
||||
+------------+ | in authorized_keys |
|
||||
| | | Check Permission |
|
||||
+------------+ | | |
|
||||
| | |
|
||||
| | | +----------------+
|
||||
| v | | |
|
||||
|
|
@ -186,93 +143,16 @@ How this work
|
|||
+------------------------+ +----------------+
|
||||
```
|
||||
|
||||
e.g.
|
||||
## Migrating from `v0`
|
||||
|
||||
on client
|
||||
### What's the major change in `v1`
|
||||
|
||||
```
|
||||
ssh-copy-id -i PK_X test@sshpiper
|
||||
```
|
||||
* low level sshpiper api is fully redesigned to support more routing protocols.
|
||||
* plugins system totally redesigned to be more flexible and extensible.
|
||||
* plugins are now sperated from main process and no longer a single big binary, this allow user to write their own plugins without touching `sshpiperd` code.
|
||||
* `grpc` is first class now, the plugins are built on top of it
|
||||
|
||||
on ssh piper server
|
||||
|
||||
```
|
||||
ln -s ~test/.ssh/authorized_keys workingdir/test/authorized_keys
|
||||
ssh-keygen -N '' -f workingdir/test/id_rsa # this is PK_Y
|
||||
ssh-copy-id -i workingdir/test/id_rsa test@server
|
||||
```
|
||||
|
||||
now `ssh test@sshpiper -i -i PK_X`, sshpiper will send `PK_Y` to server instead of `PK_X`.
|
||||
|
||||
|
||||
### Additional Challenge (`--challenger-driver=`)
|
||||
|
||||
sshpiper allows you to add your own challenge before dialing to the upstream.
|
||||
if a client failed in this challenge, connection will be closed.
|
||||
however, the client has to pass the upstream server's auth in order to establish the whole connection.
|
||||
`Additional Challenge` is required, but not enough.
|
||||
|
||||
This is useful when you want use publickey and something like [google-authenticator](https://github.com/google/google-authenticator) together.
|
||||
|
||||
|
||||
#### Available Challengers
|
||||
* azdevcode
|
||||
|
||||
Support Azure AD device code grant, [More info](https://docs.microsoft.com/en-us/azure/active-directory/develop/v2-oauth2-device-code)
|
||||
|
||||
sshpier will ask user to login using webpage
|
||||
|
||||
```
|
||||
To sign in, use a web browser to open the page https://microsoft.com/devicelogin and enter the code ****** to authenticate.
|
||||
```
|
||||
|
||||
* authy
|
||||
|
||||
Support token and onetouch from <https://authy.com/>
|
||||
|
||||
#### OpenSSH Native way to do 2FA (No SSHPiper)
|
||||
|
||||
in `sshd_config`
|
||||
```
|
||||
AuthenticationMethods publickey,keyboard-interactive:pam
|
||||
```
|
||||
|
||||
Enable 2FA PAM, for example, `pam_yubico` or `pam_google_authenticator`.
|
||||
|
||||
### Auditor for pipes (`--auditor-driver=`)
|
||||
|
||||
Auditor provides hook for messages transfered by SSH Piper which cloud log messages onto disks or filter some specific message on the fly.
|
||||
|
||||
#### Available Auditor
|
||||
|
||||
* SSH Session logging (`--auditor-driver=typescript-logger`)
|
||||
|
||||
When `record_typescript` is allowed, each piped connection would be recorded into [typescript](https://en.wikipedia.org/wiki/Script_(Unix)) in `--auditor-typescriptlogger-outputdir`.
|
||||
|
||||
The file format is compatible with [scriptreplay(1)](https://linux.die.net/man/1/scriptreplay)
|
||||
|
||||
Example:
|
||||
|
||||
```
|
||||
$ ./sshpiperd daemon --auditor-driver=typescript-logger
|
||||
|
||||
ssh user_name@127.0.0.1 -p 2222
|
||||
... do some commands
|
||||
exit
|
||||
|
||||
|
||||
$ cd workingdir/user_name
|
||||
$ ls *.timing *.typescript
|
||||
1472847798.timing 1472847798.typescript
|
||||
|
||||
$ scriptreplay -t 1472847798.timing 1472847798.typescript # will replay the ssh session
|
||||
```
|
||||
|
||||
## Manage pipes with sshpiper command
|
||||
|
||||
SSH Piper comes with tools to list/add/remove pipes.
|
||||
|
||||
`sshpiperd pipe -h` to learn more.
|
||||
For plugins already in `v1`, you need change params to new params. However, not all plugins are migrated to `v1` yet, they are being migrated gradually. you can still use the old plugins in [`v0` branch](https://github.com/tg123/sshpiper/tree/v0)
|
||||
|
||||
## License
|
||||
MIT
|
||||
19
plugin/azdevicecode/README.md
Normal file
19
plugin/azdevicecode/README.md
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
# Azure Device Code for sshpiperd
|
||||
|
||||
Support Azure AD device code grant, [More info](https://docs.microsoft.com/en-us/azure/active-directory/develop/v2-oauth2-device-code)
|
||||
|
||||
sshpier will ask user to login using webpage
|
||||
|
||||
```
|
||||
To sign in, use a web browser to open the page https://microsoft.com/devicelogin and enter the code ****** to authenticate.
|
||||
```
|
||||
|
||||
NOTE: This is an additional challenge plugin. 🔒 you must use it with other routing plugins.
|
||||
|
||||
## Usage
|
||||
|
||||
Note: you may want to set `login-grace-time` to larger value (default: 30s) to avoid being kicked by `sshpiperd` if code was not entered in time.
|
||||
|
||||
```
|
||||
sshpiperd --login-grace-time=2m azdevicecode --tenant-id 00000000-0000-0000-0000-000000000000 --client-id 00000000-0000-0000-0000-000000000000 -- other-plugin --other-option
|
||||
```
|
||||
10
plugin/fixed/README.md
Normal file
10
plugin/fixed/README.md
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
# fixed plugin for sshpiperd
|
||||
|
||||
Targeting the fixed sshd endpoint. Note, key mapping is not supported. which means you cannot use public to login to remote sshd.
|
||||
|
||||
|
||||
## Usage
|
||||
|
||||
```
|
||||
sshpiperd fixed --target 127.0.0.1:5522
|
||||
```
|
||||
17
plugin/simplemath/README.md
Normal file
17
plugin/simplemath/README.md
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
# simple math plugin for sshpiperd
|
||||
|
||||
## Usage
|
||||
|
||||
Note: this is an additional challenge plugin. 🔒 you must use it with other routing plugins.
|
||||
|
||||
```
|
||||
sshpiperd simplemath -- other-plugin --other-option
|
||||
```
|
||||
|
||||
### Demo
|
||||
|
||||
```
|
||||
$ ssh 127.0.0.1 -l user -p 2222
|
||||
lets do math
|
||||
what is 7 + 9 =
|
||||
```
|
||||
71
plugin/workingdir/README.md
Normal file
71
plugin/workingdir/README.md
Normal file
|
|
@ -0,0 +1,71 @@
|
|||
# Working Directory plugin for sshpiperd
|
||||
|
||||
`Working Dir` is a `/home`-like directory.
|
||||
SSHPiperd read files from `workingdir/[username]/` to know upstream's configuration.
|
||||
|
||||
e.g.
|
||||
|
||||
```
|
||||
workingdir tree
|
||||
|
||||
.
|
||||
├── github
|
||||
│ └── sshpiper_upstream
|
||||
└── linode
|
||||
└── sshpiper_upstream
|
||||
```
|
||||
|
||||
when `ssh sshpiper_host -l github`,
|
||||
sshpiper reads `workingdir/github/sshpiper_upstream` and the connect to the upstream.
|
||||
|
||||
## Usage
|
||||
|
||||
```
|
||||
sshpiperd workingdir --root /var/sshpiper
|
||||
```
|
||||
|
||||
### options (allow supported read from environments)
|
||||
|
||||
```
|
||||
--allow-baduser-name allow bad username (default: false) [$SSHPIPERD_WORKINGDIR_ALLOWBADUSERNAME]
|
||||
--no-check-perm disable 0400 checking (default: false) [$SSHPIPERD_WORKINGDIR_NOCHECKPERM]
|
||||
--root value path to root working directory (default: "/var/sshpiper") [$SSHPIPERD_WORKINGDIR_ROOT]
|
||||
--strict-hostkey upstream host public key must be in known_hosts file, otherwise drop the connection (default: false) [$SSHPIPERD_WORKINGDIR_STRICTHOSTKEY]
|
||||
```
|
||||
|
||||
## User files
|
||||
|
||||
*These file MUST NOT be accessible to group or other. (chmod og-rwx filename)*
|
||||
|
||||
* sshpiper_upstream
|
||||
|
||||
* line starts with `#` are treated as comment
|
||||
* only the first not comment line will be parsed
|
||||
* if no port was given, 22 will be used as default
|
||||
* if `user@` was defined, username to upstream will be the mapped one
|
||||
|
||||
```
|
||||
# comment
|
||||
[user@]upstream[:22]
|
||||
```
|
||||
|
||||
```
|
||||
e.g.
|
||||
|
||||
git@github.com
|
||||
|
||||
google.com:12345
|
||||
|
||||
```
|
||||
|
||||
* authorized_keys
|
||||
|
||||
OpenSSH format `authorized_keys` (see `~/.ssh/authorized_keys`). `downstream`'s public key must be in this file to get verified in order to use `id_rsa` to login to `upstream`.
|
||||
|
||||
* id_rsa
|
||||
|
||||
RSA key for upstream.
|
||||
|
||||
* known_hosts
|
||||
|
||||
when `--strict-hostkey` is set, upstream server's public key must present in known_hosts
|
||||
Loading…
Add table
Add a link
Reference in a new issue