A fast, custom encrypted transport protocol written in Rust.
Go to file
ospab ebfc751471 fix(android): treat a blank signing secret as absent, not as the password
The Android jobs failed with "Get Key failed: Given final block not properly
padded" once the store password was corrected - the keystore opened, but the
KEY could not be decrypted.

Cause: GitHub Actions substitutes an empty string, not an unset variable, for
a secret that does not exist. ANDROID_KEY_PASSWORD is deliberately not set (our
keystore is PKCS12, where the key password cannot differ from the store
password), so OSTP_KEY_PASSWORD arrived as "". Kotlin's elvis operator only
falls back on null, so `getenv(...) ?: storePassword` kept the empty string and
used it as the literal key password.

signingSetting() now maps blank to null, so the documented fallback actually
happens. Applies to every signing field, not just the key password - the same
trap would have hit any of them.
2026-07-30 20:56:33 +03:00
.github ci: cache the GUI/Android Rust builds, and diagnose signing failures early 2026-07-30 20:43:55 +03:00
docs docs: document DH-inclusive transport keys / forward secrecy + trial rate-limit 2026-07-11 22:01:40 +03:00
icons docs: update CLI arguments to subcommands 2026-07-10 03:05:30 +03:00
ostp fix(cli): trait-qualify Sha256::digest so it builds with or without the import 2026-07-30 14:41:16 +03:00
ostp-client fix: two independent causes of the tunnel freezing at 0 b/s 2026-07-30 00:36:17 +03:00
ostp-core fix: two independent causes of the tunnel freezing at 0 b/s 2026-07-30 00:36:17 +03:00
ostp-flutter fix(android): treat a blank signing secret as absent, not as the password 2026-07-30 20:56:33 +03:00
ostp-gui feat(gui): green aura on the connected state 2026-07-30 19:54:11 +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 fix(server): rate-limit the (currently unwired) open UDP DNS listener 2026-07-18 17:42:49 +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 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.wiki@2a22b520b2 docs: update architecture diagram to be more understandable 2026-07-12 00:34:10 +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 chore: never let an Android signing key be committed 2026-07-30 20:25:28 +03:00
.release-state.json chore: release v0.4.2 on master 2026-07-30 20:31:26 +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: update Cargo.lock for ostp's new direct sha2 dependency 2026-07-21 18:10:23 +03:00
Cargo.toml chore: release v0.4.2-beta.1 on beta 2026-07-12 02:18:47 +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