Fowl
Forward over Wormhole: streams over magic-wormhole Dilation connections
Install / Use
/learn @magic-wormhole/FowlREADME
Forward over Wormhole, Locally (fowl)
.. image:: logo.svg :width: 42% :align: right :alt: Fowl Logo: a chicken head with two blue ethernet cables
Get TCP streams from one computer to another, safely.
(The base protocol below Magic Wormhole <https://github.com/magic-wormhole/magic-wormhole>_ provides a powerful account-less, peer-to-peer networking solution -- fowl helps you use this power immediately with existing programs)
- Code: https://github.com/meejah/fowl
- Documentation: https://fowl.readthedocs.io/en/latest/
🛗 Elevator Pitch
There is lots of "self-hostable" networking software, with both the server and client available as FOSS.
With Fowl, we turn that software into end-to-end-encrypted peer-to-peer software. (Note for this use-case of using tty-share over wormhole, there is now https://github.com/magic-wormhole/shwim <ShWiM>_)
Self-hosting services on a public IP address often takes "real work": setting things up on a VPS, worrying about attacks, doing updates, etc etc. With Fowl, we only worry about connections to one other peer.
Persistent, durable connections provided by Dilated Magic Wormhole connections allow one side to change networks (e.g. close laptop, go to library, open laptop) and resume talking without any special support from the "actual" software being used.
.. NOTE::
Astute readers will notice there is still a "public server" involved: the Magic Wormhole Mailbox server.
This server, however, cannot see any traffic content.
It does learn certain metadata -- e.g. client IP addresses, if not using Tor <https://torproject.org>_.
🤔 Motivation
We sometimes pair-program but don't like the idea of sending keystrokes over a third-party server. That could be solved by self-hosting, but we also like avoiding the extra work of "set up a server on a public IP address".
For more context, see my blog posts: Forwarding Streams over Magic Wormhole <https://meejah.ca/blog/fow-wormhole-forward>_ and Wizard Gardens vision <https://meejah.ca/blog/wizard-gardens-vision>_.
.. image:: four-window-localhost-demo-1500.png :width: 100% :alt: screenshot of four terminals demonstrating fowl with two peers, one "nc" and one "telnet": encrypted chat with telnet over wormhole
🦃 What?
The command-line tool fowl allows you use any client/server program over Magic Wormhole <https://github.com/magic-wormhole/magic-wormhole>_.
Magic Wormhole provides a persistent, strongly-encrypted session (end-to-end) with no need for pre-shared keys.
Conceptually, this is somewhat similar to combining ssh -R and ssh -L.
fowl may be used to set up complex workflows directly between participants, integrating services that would "traditionally" demand a server on a public IP address.
Key features:
- no need to pre-exchange keys
- simple, one-time-use codes that are easy to transcribe
- secure (full-strength keys via SPAKE2)
- end-to-end encryption (and no possibility for unencrypted application data)
- integrate with any tools that can listen on or connect to localhost
This allows an author to write a "glue" program in any language that ties together unchanged networked progams. The communcation channel is:
- set up without pre-shared secrets;
- fully encrypted;
- and survives IP address changes or outages.
All this with no action required at the application level, it is just a normal localhost TCP (or UNIX) streaming socket.
✍ Motivational Example
When pair-programming using tty-share <https://tty-share.com/>_ one handy option is to use the default, public server.
However, I don't like the idea of sending keystrokes over a third-party server that I don't run.
(Please note: I have no reason to believe this nice person is doing anything nefarious!)
I could fire up such a server myself and use it with my friends...
...but with fowl, one side can run a localhost tty-share server and the other side can run a tty-share client that connects to a localhost endpoint -- data flows over the wormhole connection (only).
Key advantage: no need to expose keystrokes to a third-party server.
Additional advantage: no need to set up a server on a public IP address.
🐃 Why is This Particular Yak Being Shorn?
I wanted to write a pair-programming application in Haskell, but didn't want to implement Dilation in the Magic Wormhole Haskell library (maybe one day!)
It also occurred to me that other people might like to experiment with Magic Wormhole (and advanced features like Dilation) in languages that lack a Magic Wormhole implementation -- that is, most of them!
So, the first step in "write a Haskell pair-programming utility" became "write and release a Python program" :)
(p.s. the next-higher level Yak is now online at sr.ht <https://git.sr.ht/~meejah/pear-on>_ but not "released")
⌨ How Does It Work?
fowl uses the "Dilation <https://magic-wormhole.readthedocs.io/en/latest/api.html#dilation>" feature of the Magic Wormhole <https://github.com/magic-wormhole/magic-wormhole> protocol.
This means that a Magic Wormhole Mailbox server is used to perform a SPAKE2 exchange via a short (but one-time only) pairing code.
For details on the security arguments, please refer to the Magic Wormhole documentation <https://magic-wormhole.readthedocs.io/>_.
After this, an E2E-encrypted direct P2P connection (or, in some cases, via a "transit relay" service) is established between the two computers;
that is, between the computer that created the wormhole code, and the one that consumed it.
The key encrypting messages on this connection is only known to the two computers; the Mailbox server cannot see any message contents.
(It, like any attacker, could try a single guess at the wormhole code). See the Magic Wormhole documentation <https://magic-wormhole.readthedocs.io/en/latest/welcome.html#design>_ for more details on this.
The "Dilation" feature further extends the above protocol to provide subchannels and "durability" -- this means the overall connection survives network changes, disconnections, etc. You can change WiFi networks or put one computer to sleep yet remain connected.
What fowl adds is a way to set up any number of localhost listeners on either end, forwarding data over subchannels.
The always-present "control" subchannel is used to co-ordinate opening and closing such listeners.
With some higher-level co-ordination, fowl may be used to set up complex workflows between participants, integrating services that would "traditionally" demand a server on a public IP address.
Another way to view this: streaming network services can integrate the Magic Wormhole protocol without having to find, link, and use a magic-wormhole library (along with the implied code-changes) -- all integration is via local streams. (There are implementations in a few languages so you could take that route if you prefer).
👤 Who Should Use This?
We handle and expect two main use-cases of this program: integrators and end-users.
Human CLI users can use fowl itself to set up and use connections, for any purpose.
For developers doing integration, fowld provides a simple stdin/out protocol for any runtime to use.
That is, some "glue" code running fowld as a sub-process.
This co-ordination program will also handle running necessary client-type or server-type networking applications that accomplish some goal useful to users. For example, "pair-programming" (for my case).
Some other ideas to get you started:
- "private" / invite-only streaming (one side runs video source, invited sides see it)
- on-demand tech support or server access (e.g. set up limited-time SSH, VNC, etc)
- ...
💼 Installation and Basic Usage
fowl and fowld are Python programs using the Twisted <https://twisted.org>_ asynchronous networking library.
You may install them with pip::
pip install fowl
Once this is done, fowl and fowld will appear on your PATH.
Run either for instructions on use.
In accordance with best practices, we recommend using a virtualenv to install all Python programs.
Never use sudo pip.
To create a virtualenv in your checkout of fowl, for example:
.. code-block:: shell
python -m venv venv
./venv/bin/pip install --upgrade pip
./venv/bin/pip install fowl
# or: ./venv/bin/pip install --editable .
./venv/bin/fowl
.. _hello-world-chat:
💬 Hello World: Chat!
The actual "hello world" of networked applications these days is chat, amirite? 😉
We will use two venerable network utilities (nc and telnet) to implement a simple, secure, and e2e-encrypted chat.
Yes, that's correct: we will make secure chat over telnet!
The first insight here is that we can make nc listen on a localhost-only port, and we can make telnet connect to a localhost TCP port.
At first we can prove the concept locally, from one terminal to another.
Open two terminals.
In the first, run: nc -l localhost 8888
This tells nc (aka "net cat") to listen on the localhost TCP port "8888" (it will echo anything that comes in, and send anything you type).
In the second terminal: telnet localhost 8888
This instructs telnet to connect to localhost TCP port 8888 -- that is, the very netcat instance running in the first terminal.
Type "hello world" into either of the terminals, and you should see it appear on the other side.
Goal achieved!, partially.
We have "chat" over nc and telnet.
It's not pretty, but it works fine.
However, we want to talk to other machines. This means we need:
- encryption;
- and a way to arrange network connectivity
These additional features are exactly what ``fo
Related Skills
node-connect
342.0kDiagnose OpenClaw node connection and pairing failures for Android, iOS, and macOS companion apps
frontend-design
84.7kCreate distinctive, production-grade frontend interfaces with high design quality. Use this skill when the user asks to build web components, pages, or applications. Generates creative, polished code that avoids generic AI aesthetics.
openai-whisper-api
342.0kTranscribe audio via OpenAI Audio Transcriptions API (Whisper).
commit-push-pr
84.7kCommit, push, and open a PR
