pico logo

Authenticated *nix pipes over ssh

The simplest authenticated pubsub system. Send messages through user-defined topics (aka channels). By default, topics are private to the authenticated ssh user. The default pubsub model is multicast with bidirectional blocking, meaning a publisher (pub) will send its message to all subscribers (sub) for a topic. There can be many publishers and many subscribers on a topic. Further, both pub and sub will wait for at least one event to be sent or received on the topic.

Features

  1. Familiar *nix pipes API
  2. Zero-install
  3. Authenticated pubsub using ssh
  4. Private pubsub by default
  5. Public pubsub by topic (opt-in)
  6. Multicast (many pubs to many subs)
  7. Bidirectional (e.g. chat)
  8. Configurable blocking characteristics for pub
  9. Configurable timeout for pub
  10. Paradigms for connecting to a topic:
    1. Read (sub)
    2. Write (pub)
    3. Read & Write (pipe)
This service is undergoing active development, expect bugs, feature dev, and server restarts

A basic API

Pipe some data into our ssh app and we will send it to anyone listening.

ssh pipe.pico.sh sub mykey
echo "hello world!" | ssh pipe.pico.sh pub mykey
Demo

Simple desktop notifications

Want to quickly receive a notification when a job is done? It can be as simple as:

ssh pipe.pico.sh sub notify; notify-send "job done!"
./longjob.sh; ssh pipe.pico.sh pub notify -e

File sharing

Sometimes you need data exfiltration and all you have is SSH:

cat doc.md | ssh pipe.pico.sh pub thedoc
ssh pipe.pico.sh sub thedoc > ./important.md
Demo

Pipe command output

Send command output through our pipe command. The pipe command is just like pub except it is non-blocking and also acts like a sub. So a client that can read and write to the topic.

ssh pipe.pico.sh sub htop
htop | ssh pipe.pico.sh pipe htop
Demo

Chat

Use our pipe command to have a chat with someone.

ssh pipe.pico.sh pipe mychan -p

Now anyone with a pico account can subscribe to this topic using the same command and start typing!

Demo

Pipe reverse shell

If you squint hard enough you can give users interactive access to your shell.

mkfifo /tmp/f; cat /tmp/f | /bin/sh -i 2>&1 | ssh pipe.pico.sh pipe myshell > /tmp/f
ssh pipe.pico.sh pipe myshell
Demo

Simple CI/CD

I'm always looking for easy ways to simplify deploying apps automatically. Having an authenticated, zero-install event system seems handy for this purpose.

while true; do ssh pipe.pico.sh sub deploy-app; docker compose pull && docker compose up -d; done
docker buildx build --push -t myapp .; ssh pipe.pico.sh pub deploy-app -e

Pubsub interactions

Multiple subs

Have many subscribers, they will all receive the message.

ssh pipe.pico.sh sub foobar
ssh pipe.pico.sh sub foobar
while true; do echo "foobar1"; sleep 1; done | ssh pipe.pico.sh pub foobar
Demo

Multiple pubs

Have many publishers send messages to subscribers.

while true; do echo "foobar1"; sleep 1; done | ssh pipe.pico.sh pub foobar
while true; do echo "foobar2"; sleep 1; done | ssh pipe.pico.sh pub foobar
ssh pipe.pico.sh sub foobar
Demo

Multiple pubs and subs

Have many publishers send messages to many subscribers.

ssh pipe.pico.sh sub foobar
ssh pipe.pico.sh sub foobar
while true; do echo "foobar1"; sleep 1; done | ssh pipe.pico.sh pub foobar
while true; do echo "foobar2"; sleep 1; done | ssh pipe.pico.sh pub foobar
Demo

Send a public message

echo "hello world!" | ssh pipe.pico.sh pub mychan -p

Now anyone with a pico account can subscribe to this topic:

ssh pipe.pico.sh sub mychan -p

Caveats

You must always pipe something into pub or else it will block indefinitely until the process is killed. However, you can provide a flag to send an empty message: pub xyz -e.

Inspiration

A special thanks to patchbay.pub for our inspiration.

Latest posts

built on our go pkg.

GET STARTED