Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/refraction-networking/water

WebAssembly Transport Executables Runtime
https://github.com/refraction-networking/water

censorship-circumvention computer-networks pluggable-transports proxy transport wasi webassembly webassembly-runtime

Last synced: 2 months ago
JSON representation

WebAssembly Transport Executables Runtime

Awesome Lists containing this project

README

        

# W.A.T.E.R.: WebAssembly Transport Executables Runtime
![Apache-2.0](https://img.shields.io/badge/License-Apache_2.0-green)
[![FOSSA](https://app.fossa.com/api/projects/git%2Bgithub.com%2Frefraction-networking%2Fwater.svg?type=shield&issueType=license)](https://app.fossa.com/projects/git%2Bgithub.com%2Frefraction-networking%2Fwater?ref=badge_shield&issueType=license)
[![CI](https://github.com/refraction-networking/water/actions/workflows/water.yml/badge.svg?branch=master)](https://github.com/refraction-networking/water/actions/workflows/water.yml)
[![Go Doc](https://pkg.go.dev/badge/github.com/refraction-networking/water.svg)](https://pkg.go.dev/github.com/refraction-networking/water)



WATER-go provides a Go runtime for WebAssembly Transport Modules(WATM) as a pluggable
application-layer transport protocol provider. It is designed to be highly portable and
lightweight, allowing for rapidly deployable pluggable transports. While other pluggable
transport implementations require a fresh client deployment (and app-store review) to update
their protocol WATER allows dynamic delivery of new transports in real time
over the network or out-of-band.





WATER wasm transport

To build a WATM in Go, please refer to [watm](https://github.com/refraction-networking/watm) for examples and helper libraries interfacing Pluggable Transports-like interfaces. Official Go compiler is currently not supported until further notice.

You can contact one of developers personally via [email protected], or simply [opening an issue](https://github.com/refraction-networking/water/issues/new).

The Rust implementation of the runtime library and information about writing, building, and using WebAssembly Transport Modules(WATM) from Rust can be found in [water-rs](https://github.com/refraction-networking/water-rs).

### Cite our work

If you quoted or used our work in your own project/paper/research, please cite our paper [Just add WATER: WebAssembly-based Circumvention Transports](https://www.petsymposium.org/foci/2024/foci-2024-0003.pdf), which is published in the proceedings of Free and Open Communications on the Internet (FOCI) in 2024 issue 1, pages 22-28.

BibTeX

```bibtex
@inproceedings{water-foci24,
author = {Erik Chi and Gaukas Wang and J. Alex Halderman and Eric Wustrow and Jack Wampler},
title = {Just add {WATER}: {WebAssembly}-based Circumvention Transports},
booktitle = {Free and Open Communications on the Internet},
publisher = {},
year = {2024},
url = {https://www.petsymposium.org/foci/2024/foci-2024-0003.pdf},
}
```

## Be Water

> Empty your mind, be formless, shapeless, like water. If you put water into a cup, it becomes the cup. You put water into a bottle and it becomes the bottle. You put it in a teapot, it becomes the teapot. Now, water can flow or it can crash. Be water, my friend.
>
> -- Bruce Lee

# License

This project is licensed under Apache 2.0 license.

## Contents

This repo contains a Go package `water`, which implements the runtime library used to interact with `.wasm` WebAssembly Transport Modules(WATM).

# Usage

Based on **WASI Snapshot Preview 1** (_wasip1_), currently W.A.T.E.R. provides a set of `net`-like APIs via `Dialer`, `Listener` and `Relay`.

## Versioning

W.A.T.E.R. is designed to be future-proof with the automated multi-version WebAssembly Transport Module(WATM) support. In order to minimize the size of compiled application binaries importing `water`, the support for each WATM version is implemented in separate sub-packages and by default none will be enabled. The developer MUST manually enable each version to be supported by importing the corresponding package:

```go
import (
// ...

_ "github.com/refraction-networking/water/transport/v0"

// ...
)
```

Otherwise, it is possible that the W.A.T.E.R. runtime cannot determine the version of the WATM and therefore fail to select the corresponding runtime:

```go
panic: failed to listen: water: listener version not found
```

### Customizable Version

_TODO: add documentations for customizable WATM version._

## Components

### Dialer

A `Dialer` connects to a remote address and returns a `net.Conn` to the caller if the connection can
be successfully established. The `net.Conn` then provides tunnelled read and write to the remote
endpoint with the WebAssembly module wrapping / encrypting / transforming the traffic.

`Dialer` is used to encapsulate the caller's connection into an outbound, transport-wrapped
connection.

```go
wasm, _ := os.ReadFile("./examples/v0/plain/plain.wasm")

config := &water.Config{
TransportModuleBin: wasm,
}

dialer, _ := water.NewDialerWithContext(context.Background(), config)
conn, _ := dialer.DialContext(context.Background(),"tcp", remoteAddr)
// ...
```

### Listener

A `Listener` listens on a local address for incoming connections which it `Accept()`s, returning
a `net.Conn` for the caller to handle. The WebAssembly Module is responsible for the initial
accpt allowing it to implement both the server side handshake as well as any unwrap / decrypt
/reform operations required to validate and re-assemble the stream. The `net.Conn` returned provides
the normalized stream, and allows the caller to write back to the client with the WebAssembly module
encoding / encrypting / transforming traffic to be obfuscated on the wire on the way to the remote
client.

`Listener` is used to decapsulate incoming transport-wrapped connections for the caller to handle,
managing the tunnel obfuscation once a connection is established.

```go
wasm, _ := os.ReadFile("./examples/v0/plain/plain.wasm")

config := &water.Config{
TransportModuleBin: wasm,
}

lis, _ := config.ListenContext(context.Background(), "tcp", localAddr)
defer lis.Close()
log.Printf("Listening on %s", lis.Addr().String())

for {
conn, err := lis.Accept()
handleConn(conn)
}

// ...
```

### Relay

A `Relay` combines the role of `Dialer` and `Listener`. It listens on a local address `Accept()`-ing
incoming connections and `Dial()`-ing the remote endpoints on establishment. The connecions are
tunneled through the WebAssembly Transport Module allowing the module to handshake, encode,
transform, pad, etc. without any caller interaction. The internal `Relay` manages the incoming
connections as well as the associated outgoing connectons.

`Relay` is a managed many-to-many handler for incoming connections that uses the WebAssemble module
to tunnel traffic.

```go
wasm, _ := os.ReadFile("./examples/v0/plain/plain.wasm")

config := &water.Config{
TransportModuleBin: wasm,
}

relay, _ := water.NewRelayWithContext(context.Background(), config)

relay.ListenAndRelayTo("tcp", localAddr, "tcp", remoteAddr) // blocking
```

## Example

See [examples](./examples) for example usecase of W.A.T.E.R. API, including `Dialer`, `Listener` and `Relay`.

## Submodules

`watm` has its own licensing policy, please refer to [watm](https://github.com/refraction-networking/watm) for more information.

# Cross-platform Support

W.A.T.E.R. is designed to be cross-platform (and cross-architecture).
Currently, it supports the following platforms:

| Target | Compiles? | Tests Pass? |
| ------------------ | --------- | ----------- |
| linux/amd64 | ✅ | ✅ |
| linux/arm64 | ✅ | ✅ |
| linux/riscv64 | ✅ | ✅ |
| macos/amd64 | ✅ | ✅ |
| macos/arm64 | ✅ | ✅ |
| windows/amd64 | ✅ | ✅ |
| windows/arm64 | ✅ | ❓ |
| others | ❓ | ❓ |

## Acknowledgments

* We thank [GitHub.com](https://github.com) for providing GitHub Actions runners for all targets below:
* `linux/amd64` on Ubuntu Latest
* `linux/arm64` via [docker/setup-qemu-action](https://github.com/docker/setup-qemu-action)
* `linux/riscv64` via [docker/setup-qemu-action](https://github.com/docker/setup-qemu-action)
* `macos/amd64` on macOS 12
* `macos/arm64` on macOS 14
* `windows/amd64` on Windows Latest

* We thank [FlyCI.net](https://www.flyci.net) for providing GitHub Actions runners on `macos/arm64` (Apple M1) _in the past_. (We switched to GitHub's `macos-14` runner as of Jan 31 2024)

We are currently actively looking for a CI provider for more target platforms. Please reach out and let us know if you would like to help.