Skip to main content

Installation

WaterWall is distributed as a standalone executable. You do not need a package manager service, a database, or a separate runtime. Download the build for your operating system, place a core.json beside the executable, and run it from that directory.

Most deployments run WaterWall on a Linux VPS. You can manage the files from a Windows machine over SSH or VS Code Remote SSH, but the commands below are meant to be executed on the server.

Download

Download the latest release from the WaterWall release page and choose the asset that matches your operating system and CPU architecture.

On Linux, a typical manual install looks like this:

mkdir -p ~/waterwall
cd ~/waterwall

# Put the downloaded archive or binary here, then extract it if needed.
chmod +x ./WaterWall

If the release asset is compressed, extract it first with the matching tool, for example tar, unzip, or 7z.

Directory Layout

A small deployment usually looks like this:

waterwall/
WaterWall
core.json
configs/
local-test.json
logs/

WaterWall reads core.json from the process working directory. The paths inside core.json, including the files listed in configs, are passed to the loader as written, so keep your working directory intentional.

Minimal core.json

Create core.json beside the executable:

{
"log": {
"path": "logs/",
"core": {
"loglevel": "INFO",
"file": "core.log",
"console": true
},
"network": {
"loglevel": "INFO",
"file": "network.log",
"console": true
},
"dns": {
"loglevel": "INFO",
"file": "dns.log",
"console": true
},
"internal": {
"loglevel": "INFO",
"file": "internal.log",
"console": true
}
},
"misc": {
"workers": 1,
"ram-profile": "client",
"mtu": 1500,
"try-enabling-bbr": true,
"libs-path": "libs/"
},
"dns": {
"domain-strategy": "prefer-ipv4"
},
"configs": [
"configs/local-test.json"
]
}

The configs array is required and must contain at least one config file path. Other sections are optional, but keeping misc explicit makes the runtime easier to reason about.

Minimal Test Chain

Create configs/local-test.json:

{
"name": "local-test",
"author": "waterwall-user",
"config-version": 1,
"core-minimum-version": 0,
"nodes": [
{
"name": "listen-http",
"type": "TcpListener",
"settings": {
"address": "127.0.0.1",
"port": 8080
},
"next": "connect-example"
},
{
"name": "connect-example",
"type": "TcpConnector",
"settings": {
"address": "example.com",
"port": 80
}
}
]
}

Run WaterWall:

cd ~/waterwall
./WaterWall

In another terminal, test the local listener:

curl -v http://127.0.0.1:8080/

If the request reaches example.com, the binary, core file, config loader, TCP listener, DNS resolver, and TCP connector are all working.

Running on a VPS

For a public service, bind listeners to a public or wildcard address:

"address": "0.0.0.0"

Then allow the port in your VPS firewall or cloud firewall. For example, if you listen on port 443, the operating system and provider firewall must both allow inbound TCP 443.

Ports below 1024 usually require root privileges or a capability such as CAP_NET_BIND_SERVICE. Packet-level nodes such as TunDevice may also require extra privileges because they create or use network interfaces.

Common Problems

core.json not found: Make sure you run WaterWall from the directory that contains core.json, or use your service manager's working-directory option.

Config file not found: Check every path in configs. Relative paths are normally relative to the current working directory.

Permission denied: Run chmod +x ./WaterWall. If the listener port is below 1024, run with the needed privilege or choose a higher port for testing.

Port already in use: Use ss -ltnp on Linux to find the process already listening on that TCP port.

Remote clients cannot connect: Check the listener address, WaterWall logs, the Linux firewall, and the provider firewall. A listener bound to 127.0.0.1 only accepts local connections.

DNS resolution fails: Check the dns block in core.json, especially servers and domain-strategy, then look at logs/dns.log.