English | 简体ä¸ć–‡
WindSend-Relay is a Go implementation of the WindSend relay server. WindSend uses TLS certificates for authentication and encrypts the relay traffic, ensuring data security even when using third-party relay servers.
-
Pull the latest image
docker pull doraemonkey/windsend-relay:latest
-
Show version information
docker run --rm doraemonkey/windsend-relay:latest -version
-
Run the container
docker run -d \ --name ws-relay \ -p 16779:16779 \ -p 16780:16780 \ -e WS_MAX_CONN="100" \ doraemonkey/windsend-relay:latest # Admin password will be generated and shown in docker logs.
Port 16779 is used for relay traffic (protocol: TCP), and port 16780 is used for the web interface (protocol: HTTP).
You can run WindSend-Relay using pre-built binaries, by building from source, or using Docker.
Option 1: Pre-built Binaries
Check the Releases page for pre-compiled binaries for your operating system. Download the appropriate archive, extract it, and run the executable. Usually, you should download Linux version to run on most Linux distributions.
Option 2: Using Docker
docker pull doraemonkey/windsend-relay:latestOption 3: Build from Source
-
Clone the repository:
git clone https://github.com/doraemonkeys/WindSend-Relay.git
-
Build the application:
# Go 1.24+ cd WindSend-Relay/server go build -o windsend-relay cd ../relay_admin npm install npm run build
Run with defaults (listening on 0.0.0.0:16779, no auth, admin on 0.0.0.0:16780 with default user/generated password):
./windsend-relay -max-conn=50
# Note: SecretInfo and IDWhitelist cannot be set via simple flags. Use JSON or Env Vars for those.
# Admin password will be generated and printed to the log on first run.Run on a different port with authentication enabled (using env vars):
# Listen on port 19999 for relay
export WS_LISTEN_ADDR="0.0.0.0:19999"
# Enable authentication
export WS_ENABLE_AUTH="true"
# Set secret key for the first secret
export WS_SECRET_0_KEY="your_secret_key_0"
# Set max connections for the first secret
export WS_SECRET_0_MAX_CONN="5"
# Configure admin interface
export WS_ADMIN_ADDR="0.0.0.0:19998"
export WS_ADMIN_USER="myadmin"
export WS_ADMIN_PASSWORD="a_very_secure_password_at_least_12_chars"
# Run the relay using environment variables
./windsend-relay -use-envRun using a JSON config file:
./windsend-relay -config /path/to/your/config.json{
"listen_addr": "0.0.0.0:16779",
"max_conn": 100,
"secret_info": [
{
"secret_key": "your_secret_key_0",
"max_conn": 5
},
{
"secret_key": "your_secret_key_1",
"max_conn": 10
}
],
"enable_auth": true,
"log_level": "INFO",
"admin_config": {
"user": "admin",
"password": "a_very_secure_password_at_least_12_chars",
"addr": "0.0.0.0:16780"
}
}Run with docker defaults (no auth)
docker run -d \
--name ws-relay \
-p 16779:16779 \
-p 16780:16780 \
-e WS_MAX_CONN="100" \
doraemonkey/windsend-relay:latest
# Admin password will be generated and shown in docker logs.Run with Docker Compose
services:
windsend-relay:
image: doraemonkey/windsend-relay:latest
container_name: windsend-relay-app
restart: unless-stopped
ports:
- "16779:16779" # Relay traffic port(protocol: TCP)
- "16780:16780" # Web Interface port(protocol: HTTP)
environment:
# --- Basic Relay Configuration ---
WS_LISTEN_ADDR: "0.0.0.0:16779"
WS_MAX_CONN: "100" # Overall max connections (adjust as needed)
WS_LOG_LEVEL: "INFO"
# --- Authentication ---
WS_ENABLE_AUTH: "true" # Set to "false" to disable authentication
# Configure SecretInfo.
# Example: Using Secret Keys (WS_SECRET prefix)
# Add more WS_SECRET_<index>_* variables for multiple secrets. Index starts at 0.
WS_SECRET_0_KEY: "YOUR_VERY_SECRET_KEY_HERE" # !!! IMPORTANT: CHANGE THIS !!!
WS_SECRET_0_MAX_CONN: "10" # Max connections allowed for this specific key
# Example for a second secret key:
# WS_SECRET_1_KEY: "ANOTHER_SECRET_KEY"
# WS_SECRET_1_MAX_CONN: "5"
# --- Admin Web Interface Configuration ---
WS_ADMIN_ADDR: "0.0.0.0:16780" # Address for the Admin UI
WS_ADMIN_USER: "admin" # Admin username
WS_ADMIN_PASSWORD: "YOUR_SECURE_ADMIN_PASSWORD_12_CHARS_MIN" # !!! CHANGE THIS !!! If left empty or omitted, a random password is generated and printed to the container logs on the first start.
volumes:
- ./logs:/app/logs
- ./data:/app/data # relay.db
#- ./config.json:/app/config.json # Optional: use config file instead of env vars
# Optional: use config file instead of env vars
# command: ["-config", "/app/config.json"]Get Version Information:
./windsend-relay -version
# Or with Docker
docker run --rm doraemonkey/windsend-relay:latest -versionWindSend-Relay can be configured using three methods, with the following order of precedence:
- Command-line Flags: Highest precedence. If
-configor-use-envis specified, other flags (except-version) are ignored. - Environment Variables: Used if the
-use-envflag is passed or if running the default Docker entrypoint. Environment variables override JSON file settings if both-configand-use-envare somehow used (though typically only one method is chosen). - JSON Configuration File: Used if the
-configflag is passed with a file path. - Default Values: Lowest precedence, used if no other configuration is provided for a specific option.
| Parameter | JSON Key | Flag | Environment Variable | Type | Default | Description |
|---|---|---|---|---|---|---|
| Listen Address | listen_addr |
-listen-addr |
WS_LISTEN_ADDR |
string |
0.0.0.0:16779 |
IP address and port for the relay server to listen on. |
| Max Connections | max_conn |
-max-conn |
WS_MAX_CONN |
int |
100 |
Global maximum number of concurrent client connections allowed. |
| ID Whitelist | id_whitelist |
N/A | WS_ID_WHITELIST |
[]string |
[] |
List of client IDs allowed to connect. If empty or omitted, all IDs are allowed (subject to auth). Indexed from 0. |
| Secret Info | secret_info |
N/A | WS_SECRET_<n>_KEY, WS_SECRET_<n>_MAX_CONN |
[]SecretInfo |
[] |
List of secret keys for authentication and their associated connection limits. See details below. Indexed from 0. |
| Enable Auth | enable_auth |
N/A | WS_ENABLE_AUTH |
bool |
false |
If true, clients must authenticate using a valid secret key from Secret Info. |
| Log Level | log_level |
-log-level |
WS_LOG_LEVEL |
string |
INFO |
Log level. Valid values: DEBUG, INFO, WARN, ERROR, DPANIC, PANIC, FATAL. |
| Admin User | admin_config.user |
N/A | WS_ADMIN_USER |
string |
admin |
Username for the admin web interface. |
| Admin Password | admin_config.password |
N/A | WS_ADMIN_PASSWORD |
string |
(generated 12-char ASCII string) | Password for the admin web interface. If empty, a random 12-character ASCII password is generated on startup and logged. Must be at least 12 characters if set. |
| Admin Listen Address | admin_config.addr |
N/A | WS_ADMIN_ADDR |
string |
0.0.0.0:16780 |
IP address and port for the admin web interface to listen on. |
| Config File | N/A | -config |
N/A | string |
"" |
Path to a JSON configuration file. If set, other flags (except -version) are ignored. |
| Use Environment | N/A | -use-env |
N/A | bool |
false |
If true, configuration is read from environment variables. Other flags (except -version) are ignored. |
| Show Version | N/A | -version |
N/A | bool |
false |
Print version information and exit. |
Note: In v0.1.0 and later versions, the command line flag -enable-auth has been removed. Please use the environment variable WS_ENABLE_AUTH or the JSON configuration enable_auth to control it.
Notes on Environment Variables for Slices and Nested Structures:
-
WS_ID_WHITELIST:export WS_ID_WHITELIST="client_id_1,client_id_2"
-
WS_SECRET_<n>_KEY/WS_SECRET_<n>_MAX_CONN: For the Secret Info slice, use indexed variables for each struct field. Example:# Secret 0 export WS_SECRET_0_KEY="mysecret1" export WS_SECRET_0_MAX_CONN="5" # Secret 1 export WS_SECRET_1_KEY="mysecret2" export WS_SECRET_1_MAX_CONN="10"
-
WS_ADMIN_*: For the Admin configuration, use the prefixWS_ADMIN_followed by the uppercase field name (USER,PASSWORD,ADDR). Example:export WS_ADMIN_USER="myadmin" export WS_ADMIN_PASSWORD="a_very_secure_password_at_least_12_chars" export WS_ADMIN_ADDR="0.0.0.0:19998"
Contributions are welcome! Please feel free to submit pull requests or open issues on the GitHub repository.