A fast, custom encrypted transport protocol written in Rust.
Go to file
ospab 234497759b fix(gui): config went to the working directory; installer wrote unusable XML
Three defects the first installer build exposed.

Settings could not be read or saved, "os error 5". With no config beside the
executable — which is the case for every fresh install — get_config_path fell
back to a bare relative "config.json", resolved against the process working
directory. Launched from a Start Menu shortcut that is whatever Windows chose,
frequently C:\Windows\System32. On a writable working directory the silent
outcome would have been worse than the error: settings persisting somewhere
unrelated and appearing to vanish. The config now lives beside the executable
only where that directory actually accepts writes, and otherwise under the
user's own profile, carrying an existing read-only copy across once.
Writability is measured, not inferred from the path: an install onto a data
drive may well be writable where Program Files is not.

The installer could not register the task: "The task XML is malformed.
(1,2)::ERROR: incorrect document syntax". Writing it from NSIS emitted a UTF-16
byte-order mark ahead of content whose encoding depends on whether makensis was
built in Unicode mode. Replaced with the ScheduledTasks cmdlets, which take the
same settings as arguments — no file, so no encoding to get wrong. Verified the
invocation reaches Register-ScheduledTask and fails only on "Access is denied"
when unelevated, which is exactly what the elevated installer supplies.

That command is delimited with backticks, NSIS's third quote character. As a
single-quoted string it would have ended at PowerShell's first quote.

"Copy failed" on wintun.dll: CopyFiles takes a destination directory, and it
was given a file path. It is also guarded now, so a missing resource says so
instead of failing mutely.

Finally, per request, the app no longer registers the task itself — that is the
installer's job alone. Without a task it goes straight to the direct elevated
launch, which prompts per connect as it always did, rather than spending a
prompt on a registration attempt and then another on the launch.
2026-08-11 17:43:04 +03:00
.github/workflows fix(ci): staging script was CommonJS in an ES-module package 2026-08-11 17:07:55 +03:00
docs fix(relay): explain the 404 — the API lives under the panel's secret webpath 2026-07-31 20:00:29 +03:00
icons docs: update CLI arguments to subcommands 2026-07-10 03:05:30 +03:00
ostp refactor(relay)!: forward transparently instead of re-authenticating clients 2026-08-03 18:49:57 +03:00
ostp-client fix: post-suspend reconnect no longer strands the machine without internet 2026-08-04 00:34:12 +03:00
ostp-core feat(congestion): actually pace sends instead of releasing whole windows 2026-07-31 19:18:42 +03:00
ostp-flutter chore: release v0.4.5-beta.2 on beta 2026-08-11 17:08:08 +03:00
ostp-gui fix(gui): config went to the working directory; installer wrote unusable XML 2026-08-11 17:43:04 +03:00
ostp-jni fix: restore LICENSE file to actual AGPL-3.0 text (was stuck on old BSL 1.1) 2026-07-10 01:36:41 +03:00
ostp-server refactor(relay)!: forward transparently instead of re-authenticating clients 2026-08-03 18:49:57 +03:00
ostp-tun §B: port stability fixes from 0.3.x onto the clean base 2026-06-27 16:30:42 +03:00
ostp-tun-helper feat(gui): one UAC prompt per machine instead of one per connect 2026-08-07 17:19:36 +03:00
ostp.wiki@2a22b520b2 docs: update architecture diagram to be more understandable 2026-07-12 00:34:32 +03:00
scripts fix(install): alpha/beta self-update actually finds a real release now 2026-07-21 18:39:48 +03:00
.gitattributes chore: enforce LF line endings on bash scripts via gitattributes to fix 'bad interpreter' on Linux 2026-05-15 19:08:03 +03:00
.gitignore feat(gui): register the helper task from an installer, not from the app 2026-08-11 16:43:49 +03:00
.release-state.json chore: release v0.4.5-beta.2 on beta 2026-08-11 17:08:08 +03:00
CONTRIBUTING.md fix(release): the second branch is 'beta', not 'pre-release' — was never checkoutable 2026-07-12 02:12:57 +03:00
CONTRIBUTING.ru.md fix(release): the second branch is 'beta', not 'pre-release' — was never checkoutable 2026-07-12 02:12:57 +03:00
Cargo.lock chore: release v0.4.5-beta.1 on beta 2026-08-11 16:54:34 +03:00
Cargo.toml chore: release v0.4.5-beta.1 on beta 2026-08-11 16:54:34 +03:00
Cross.toml CI/CD: Resolve MIPS Tier-3 compilation by instructing Cross to dynamically build-std library from source 2026-05-14 23:57:19 +03:00
LICENSE fix: restore LICENSE file to actual AGPL-3.0 text (was stuck on old BSL 1.1) 2026-07-10 01:36:41 +03:00
README.md fix(release): the second branch is 'beta', not 'pre-release' — was never checkoutable 2026-07-12 02:12:57 +03:00
README.ru.md fix(release): the second branch is 'beta', not 'pre-release' — was never checkoutable 2026-07-12 02:12:57 +03:00
REBUILD_PLAN.md §A: remove WSS + Reality (TLS-mimicry); bump to 0.4.0 / AGPL-3.0 2026-06-27 16:29:42 +03:00
app-icon.svg Refactor: Phase 1 and 2 - Async architecture, JNI fixes, SmolTCP data races, and Tunnel optimizations 2026-06-03 02:06:06 +03:00

README.md

OSTP - Ospab Stealth Transport Protocol

Русский язык · Wiki · Contributing · Releases

GitHub Release License: AGPL v3 Platform: Windows | Linux | macOS | Android Crypto Transport

A fast, custom encrypted transport protocol written in Rust.

OSTP (Ospab Stealth Transport Protocol) is a high-performance transport protocol. It implements a custom ARQ transport over UDP, as well as a UoT (UDP-over-TCP) mode. Every byte on the wire - including packet headers - is cryptographically indistinguishable from random noise, making it highly resistant to Deep Packet Inspection (DPI).


Quick Install

Linux

bash <(curl -Ls https://raw.githubusercontent.com/ospab/ostp/master/scripts/install.sh)

Windows (PowerShell, run as Administrator)

irm https://raw.githubusercontent.com/ospab/ostp/master/scripts/install.ps1 | iex

Manual Download

Download pre-built binaries for your platform from GitHub Releases.


Key Features

Feature Description
Full Traffic Obfuscation Every packet - including headers - is indistinguishable from random noise. Session IDs and nonces are masked with per-packet HMAC-derived keys.
Noise Protocol Handshake Noise_NNpsk0_25519_ChaChaPoly_BLAKE2s - PSK-authenticated, forward-secret key exchange with no static identity exposure.
Reliable UDP (ARQ) Selective ACK/NACK with rate-limited retransmission, configurable reorder buffer, and exponential backoff.
Multiplexed Streams Multiple logical TCP streams over a single encrypted UDP session with per-stream flow control.
Seamless Roaming Clients can switch networks (WiFi ↔ LTE) without session interruption - tracked by session-ID, not IP.
Management API Built-in REST API for third-party panels (3x-ui, custom dashboards). Per-user stats, traffic limits, key CRUD.
Fallback Server TCP fallback proxy to a web server - makes OSTP indistinguishable from nginx during active probing.
Multi-Listener Bind to multiple addresses simultaneously (dual-stack IPv4/IPv6, multi-port).
TUN Mode Full-system VPN via native smoltcp network stack without external dependencies. All traffic transparently routed through the tunnel.
UoT (UDP-over-TCP) Bare UDP-over-TCP tunnel, no protocol mimicry. Since all data is fully encrypted and length-prefixed, it bypasses DPI filters that block unknown UDP traffic by riding over a plain TCP connection.
Mobile & Web Apps Beautiful cross-platform mobile client (Flutter) and a modern Web Control Panel (React/Vite) for effortless server and client management.
TURN Relay RFC 5766 TURN support for environments where direct UDP is blocked.
Hot-Reload Runtime config reload without restart (access keys, exclusions, mux settings).
Structured Logging tracing-based logging with RUST_LOG filtering. JSON/file/syslog output support.
Cross-Platform Windows, Linux, macOS, Android, FreeBSD, MIPS, RISC-V. Single binary, no runtime dependencies.

Architecture

flowchart LR
    %% Styles
    classDef userApp fill:#e1f5fe,stroke:#01579b,stroke-width:2px,color:#01579b
    classDef ostpCore fill:#e8f5e9,stroke:#2e7d32,stroke-width:2px,color:#2e7d32
    classDef network fill:#fff3e0,stroke:#e65100,stroke-width:2px,color:#e65100,stroke-dasharray: 5 5
    classDef external fill:#f3e5f5,stroke:#4a148c,stroke-width:2px,color:#4a148c
    classDef fallback fill:#ffebee,stroke:#c62828,stroke-width:2px,color:#c62828

    subgraph Local["💻 Client Device"]
        Apps["Web Browser / Apps"]:::userApp
        Socks["SOCKS5 / HTTP Proxy"]:::ostpCore
        Tun["Global TUN (VPN)"]:::ostpCore
        Client["OSTP Client Protocol Engine\n(Noise + ChaCha20 + ARQ)"]:::ostpCore

        Apps -->|TCP/UDP| Socks
        Apps -->|IP Packets| Tun
        Socks --> Client
        Tun --> Client
    end

    subgraph Internet["🌐 Hostile Network (DPI/Firewall)"]
        Tunnel{"Fully Obfuscated\nEncrypted UDP\n(Looks like noise)"}:::network
    end

    subgraph Remote["🖥️ Remote VPS (Server)"]
        Server["OSTP Server Protocol Engine\n(Authentication & Decryption)"]:::ostpCore
        Relay["Connection Multiplexer"]:::ostpCore
        Fallback["Fake Website\n(Nginx/Caddy)"]:::fallback
        Target["Open Internet\n(YouTube, Google, etc)"]:::external

        Server -->|Decrypted Traffic| Relay
        Server -->|Active Probe / Scanner| Fallback
        Relay -->|Clear Traffic| Target
    end

    Client <==> Tunnel <==> Server

Quick Start

1. Generate config

# On your VPS (server):
./ostp init server

# On your machine (client):
./ostp init client

2. Edit config

Server - set your access keys:

{
  "mode": "server",
  "listen": "0.0.0.0:50000",
  "access_keys": ["YOUR_SECRET_KEY"],
  "api": { "enabled": true, "bind": "127.0.0.1:9090", "token": "admin-token" },
  "fallback": { "enabled": false, "listen": "0.0.0.0:443", "target": "127.0.0.1:8080" }
}

Client - point to your server:

{
  "mode": "client",
  "server": "YOUR_SERVER_IP:50000",
  "access_key": "YOUR_SECRET_KEY",
  "socks5_bind": "127.0.0.1:1088",
  "transport": { "mode": "udp" },
  "tun": { "enable": false, "dns": "1.1.1.1" }
}

3. Run

./ostp                         # Uses config.json in current directory
./ostp --config /path/to.json  # Custom config path
./ostp check                   # Validate config without running
./ostp gk                      # Generate a new access key
./ostp links                   # Print client share links
./ostp connect "ostp://ACCESS_KEY@server.com:50000?..."

[!WARNING] Always wrap the ostp://... link in quotes (") so your terminal doesn't misinterpret special characters like & or ?.


Management API

Built-in REST API for building panels and dashboards.

# Server status
curl -H "Authorization: Bearer mytoken" http://127.0.0.1:9090/api/server/status

# List all users with traffic stats  
curl -H "Authorization: Bearer mytoken" http://127.0.0.1:9090/api/users

# Create a user with 10GB traffic limit
curl -X POST -H "Authorization: Bearer mytoken" \
  -H "Content-Type: application/json" \
  -d '{"limit_bytes": 10737418240}' \
  http://127.0.0.1:9090/api/users

Full API reference: Management API


CLI Reference

ostp [--config <PATH>] [COMMAND]

Commands:
  run                    Run the daemon using the config file (default when no command is given)
  connect <URL>          Connect once using a share link: ostp://KEY@HOST:PORT
  setup                  Interactive setup wizard
  init <MODE>            Generate a template config (server/client/relay)
  check                  Validate the configuration file and exit
  gk                     Generate a secure access key (alias: generate-key)
    --format <FMT>         Key format: hex, base64 (default: hex)
    -n, --count <N>        Number of keys to generate (default: 1)
  links                  Print client share links from the server config
  import <URL>           Import a share link into the config file
  update                 Update OSTP to the latest release
    -b, --branch <NAME>    Release channel: stable, beta, alpha (default: stable)
    -v, --version <VER>    Update to an exact version instead of the channel's latest
  migrate                Force-migrate the configuration file to the current format
  proxy-env              Print shell export commands for the local SOCKS proxy
  proxy-env-clear        Print shell export commands to unset it
  uninstall              Stop the service and remove the binary and config

Global options:
  --config <PATH>        Config file path (default: config.json)

Every subcommand also accepts -h/--help for its own option list.


Protocol Summary

Layer Mechanism
Key Exchange Noise NNpsk0 (X25519 + ChaChaPoly + BLAKE2s) zero-RTT
Encryption ChaCha20-Poly1305 AEAD per-packet
Header Obfuscation HMAC-SHA256 derived per-packet mask
Reliability Selective ACK with cumulative + SACK ranges
Retransmission Rate-limited NACK + exponential backoff RTO
Keepalive Ping/Pong with RTT measurement every 5s

Building from Source

# Prerequisites: Rust 1.75+
cargo build --release

# Cross-compile for Linux
cross build --release --target x86_64-unknown-linux-gnu

# Run tests
cargo test -p ostp-core -p ostp-server

Documentation


License

GNU Affero General Public License v3.0 (AGPL-3.0). See LICENSE for the full text.


Contact