by tg123

tg123 / sshpiper

The missing reverse proxy for ssh scp

441 Stars 64 Forks Last release: 12 months ago (v0.4.2) MIT License 252 Commits 6 Releases

Available items

No Items, yet!

The developer of this repository has not created any items for sale yet. Need a bug fixed? Help with integration? A different license? Create a request here:

SSH Piper

Go Go Report Card Docker Image

SSH Piper works as a proxy-like ware, and route connections by

src ip
, etc.
+---------+                      +------------------+          +-----------------+
|         |                      |                  |          |                 |
|   Bob   +----ssh -l bob----+   |   SSH Piper   +------------->   Bob' machine  |
|         |                  |   |               |  |          |                 |
+---------+                  |   |               |  |          +-----------------+
                             +---> pipe-by-name--+  |                             
+---------+                  |   |               |  |          +-----------------+
|         |                  |   |               |  |          |                 |
|  Alice  +----ssh -l alice--+   |               +------------->  Alice' machine |
|         |                      |                  |          |                 |
+---------+                      +------------------+          +-----------------+

Downstream SSH Piper Upstream





Build yourself [Go 1.14+]

git clone 
cd sshpiper/sshpiperd/
go build

with pam module support

go build -tags pam 

with Docker image

docker run farmer1992/sshpiperd

Run with Workding Dir upstream driver

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 \

Run with Additional Challenge

use env

to specify which challenger to use
docker run -d -p 2222:2222 \
  -v /YOUR_PAM_CONFIG:/etc/pam.d/sshpiperd \
  -v /etc/ssh/ssh_host_rsa_key:/etc/ssh/ssh_host_rsa_key \
  -v /YOUR_WORKING_DIR:/var/sshpiper \

with Snap

Get it from the Snap Store

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

* use classic mode if PAM is not working:
sudo snap install --classic sshpiperd

Quick start

Just run
in sshpiperd example directory or Copy paste command below to run
go get && `go env GOPATH`/src/

the example script will setup a sshpiper server using

bitbucket -> [email protected]:22 # ssh -p 2222 -l bitbucket
github -> [email protected]:22 # ssh -p 2222 -l github
gitlab -> [email protected]:22 # ssh -p 2222 -l gitlab

connect to gitlab

$ ssh -p 2222 -l gitlab
Permission denied (publickey).

connect to

$ ssh -p 2222 -l github
Permission denied (publickey).


sshpiper provides 3 pluginable components to highly customize your piper

sshpiperd daemon -h
to learn more

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

Database upstream driver connected to popular databases, such as mysql, pg or sqlite etc to provide upstream's information.

How to do public key authentication when using sshpiper

During SSH publickey auth, RFC 4252 Section 7, ssh client sign

and some other data using private key into a signature
. This is for server to verify that the connection is from the client not
the man in the middle

However, sshpiper actually holds two ssh connection, and it is doing what

the man in the middle
does. the two ssh connections'
will never be the same, because they are hash of the shared secret. RFC 4253 Section 7.2.

To support publickey auth, sshpiper will modify the

using a private key provided by upstream driver. e.g. (
) in the

How this work

+------------+        +------------------------+                       
|            |        |                        |                       
|   client   |        |   SSH Piper            |                       
|   PK_X     +-------->      |                 |                       
|            |        |      v                 |                       
|            |        |   Check PK_X           |                       
+------------+        |   in authorized_keys   |                       
                      |      |                 |                       
                      |      |                 |     +----------------+
                      |      v                 |     |                |
                      |   sign agian           |     |   server       |
                      |   using PK_Y  +-------------->   check PK_Y   |
                      |                        |     |                |
                      |                        |     |                |
                      +------------------------+     +----------------+


on client

ssh-copy-id -i PK_X [email protected]

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 [email protected]


ssh [email protected] -i -i PK_X
, sshpiper will send
to server instead of

Additional Challenge (

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 together. OpenSSH do not support use publickey and other auth together.

Available Challengers

  • pam

Linux-PAM challenger

this module use the pam service called


you can configure the rule at

  • azdevcode

Support Azure AD device code grant, More info

sshpier will ask user to login using webpage

   To sign in, use a web browser to open the page and enter the code ****** to authenticate.

Auditor for pipes (

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 (



    is allowed, each piped connection would be recorded into typescript in

    The file format is compatible with scriptreplay(1)


    $ ./sshpiperd daemon --auditor-driver=typescript-logger

    ssh [email protected] -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.



We use cookies. If you continue to browse the site, you agree to the use of cookies. For more information on our use of cookies please see our Privacy Policy.