diff --git a/Building-from-Source.md b/Building-from-Source.md new file mode 100644 index 0000000..a7957ef --- /dev/null +++ b/Building-from-Source.md @@ -0,0 +1,84 @@ +# Building from Source + +## Prerequisites + +- [Rust](https://rustup.rs/) (stable toolchain) +- Git + +### For GUI (additional) + +- Node.js 20+ +- Tauri CLI: `cargo install tauri-cli --version "^2"` + +### For Cross-Compilation + +- [cross](https://github.com/cross-rs/cross): `cargo install cross` + +## Build CLI + +```bash +git clone https://github.com/ospab/ostp.git +cd ostp +cargo build --release --bin ostp +``` + +Output: `target/release/ostp` (or `ostp.exe` on Windows) + +## Build GUI + +```bash +cd ostp-gui +cargo tauri build +``` + +Output: `ostp-gui/src-tauri/target/release/ostp-gui.exe` + +## Build for Specific Targets + +```bash +# Linux ARM64 +cargo build --release --target aarch64-unknown-linux-musl --bin ostp + +# Windows ARM64 +cargo build --release --target aarch64-pc-windows-msvc --bin ostp + +# Android (via cross) +cross build --release --target aarch64-linux-android --bin ostp + +# Router (MIPS) +cross build --release --target mipsel-unknown-linux-musl --bin ostp +``` + +## Build JNI Library (Android) + +```bash +cross build --release --target aarch64-linux-android -p ostp-jni +``` + +Output: `target/aarch64-linux-android/release/libostp_jni.so` + +## Supported Targets + +| Target | Architecture | OS | +|---|---|---| +| `x86_64-pc-windows-msvc` | x64 | Windows | +| `aarch64-pc-windows-msvc` | ARM64 | Windows | +| `x86_64-unknown-linux-musl` | x64 | Linux | +| `aarch64-unknown-linux-musl` | ARM64 | Linux | +| `armv7-unknown-linux-musleabihf` | ARMv7 | Linux | +| `x86_64-apple-darwin` | x64 | macOS | +| `aarch64-apple-darwin` | ARM64 | macOS (M1+) | +| `mipsel-unknown-linux-musl` | MIPS LE | Linux (Routers) | +| `riscv64gc-unknown-linux-gnu` | RISC-V 64 | Linux | +| `aarch64-linux-android` | ARM64 | Android | +| `x86_64-unknown-freebsd` | x64 | FreeBSD | + +## Running Tests + +```bash +cargo test -p ostp-core +``` + +--- + +[← GUI Client](GUI-Client) | [FAQ →](FAQ) diff --git a/Configuration.md b/Configuration.md new file mode 100644 index 0000000..9ae6688 --- /dev/null +++ b/Configuration.md @@ -0,0 +1,99 @@ +# Configuration + +## Server Configuration + +| Field | Type | Default | Description | +|---|---|---|---| +| `mode` | string | required | Must be `"server"` | +| `listen` | string | `"0.0.0.0:50000"` | Listen address and port | +| `access_keys` | string[] | required | List of access keys for client authentication | +| `log_level` | string | `"info"` | Logging level: `debug`, `info`, `warn`, `error` | + +### Example + +```json +{ + "mode": "server", + "listen": "0.0.0.0:50000", + "access_keys": [ + "key-for-user-1", + "key-for-user-2" + ], + "log_level": "info" +} +``` + +## Client Configuration + +| Field | Type | Default | Description | +|---|---|---|---| +| `mode` | string | required | Must be `"client"` | +| `server` | string | required | Server address (`host:port`) | +| `access_key` | string | required | Access key matching server config | +| `socks5_bind` | string | `"127.0.0.1:1088"` | Local HTTP/SOCKS5 proxy address | +| `debug` | bool | `false` | Enable verbose logging | +| `tun` | object | `null` | TUN tunnel configuration | +| `exclude` | object | `null` | Traffic exclusion rules | +| `mux` | object | `null` | Multiplexing configuration | + +### TUN Configuration + +| Field | Type | Description | +|---|---|---| +| `enable` | bool | Enable TUN tunnel mode (routes all traffic) | +| `dns` | string | Custom DNS server for the tunnel interface | + +### Exclusions + +| Field | Type | Description | +|---|---|---| +| `domains` | string[] | Domain suffixes to bypass (e.g., `"google.com"`) | +| `ips` | string[] | IP addresses or CIDR ranges to bypass (e.g., `"192.168.0.0/16"`) | +| `processes` | string[] | Process names to bypass in proxy mode (e.g., `"chrome.exe"`) | + +### Multiplexing + +| Field | Type | Description | +|---|---|---| +| `enabled` | bool | Enable session multiplexing | +| `sessions` | int | Number of concurrent OSTP sessions | + +### Full Client Example + +```json +{ + "mode": "client", + "server": "example.com:50000", + "access_key": "my-secret-key", + "socks5_bind": "127.0.0.1:1088", + "debug": false, + "tun": { + "enable": true, + "dns": "1.1.1.1" + }, + "exclude": { + "domains": ["bank.com", "local.network"], + "ips": ["192.168.0.0/16", "10.0.0.0/8"], + "processes": ["steam.exe"] + }, + "mux": { + "enabled": false, + "sessions": 1 + } +} +``` + +### TURN Relay (Optional) + +For networks that block direct UDP: + +| Field | Type | Description | +|---|---|---| +| `turn.enabled` | bool | Enable TURN relay | +| `turn.server_addr` | string | TURN server address | +| `turn.username` | string | TURN username | +| `turn.access_key` | string | TURN password | + +--- + +[← Installation](Installation) | [Protocol Design →](Protocol-Design) diff --git a/FAQ.md b/FAQ.md new file mode 100644 index 0000000..4e20d20 --- /dev/null +++ b/FAQ.md @@ -0,0 +1,73 @@ +# FAQ + +## General + +### What is the difference between OSTP and other proxy protocols? + +OSTP is designed specifically for DPI/TSPU resistance. Unlike Shadowsocks, VMess, or VLESS, OSTP: +- Has no protocol-specific magic bytes or version fields +- Derives all obfuscation parameters from the access key +- Uses UDP with Noise protocol for key exchange +- Cannot be identified by binary analysis + +### Is OSTP compatible with xray-core or sing-box? + +No. OSTP is a standalone protocol with its own transport and encryption. It is not a plugin for existing proxy frameworks. + +### Does OSTP support multiple users? + +Yes. The server accepts multiple access keys in the `access_keys` array. Each key creates an independent encrypted session. + +## Connection + +### Why does the handshake fail? + +1. **Wrong access key** — Keys must match exactly between client and server +2. **UDP blocked** — Some networks block UDP entirely. Try enabling TURN relay +3. **Port blocked** — Try using port 443 or 8443 +4. **Version mismatch** — Client and server must be the same version + +### What ports does OSTP use? + +Default: UDP port 50000. This is configurable. + +### Does OSTP work over TCP? + +No. OSTP is UDP-only by design. For networks that block UDP, use the built-in TURN relay feature. + +## Performance + +### What is the expected overhead? + +Approximately 50-100 bytes per packet for AEAD encryption, nonce, and session header. On high-bandwidth connections, overhead is negligible (<1%). + +### How does multiplexing work? + +When enabled, the client creates multiple OSTP sessions to the server simultaneously. This can improve throughput on lossy networks by distributing traffic across sessions. + +## Security + +### What cryptography does OSTP use? + +- **Key Exchange**: Noise_NNpsk0 (X25519 + ChaChaPoly + BLAKE2s) +- **Key Derivation**: HKDF-SHA256 (RFC 5869) +- **Transport Encryption**: ChaCha20-Poly1305 AEAD +- **Obfuscation Masks**: HMAC-SHA256 + +### Can my ISP detect OSTP traffic? + +OSTP is designed to make detection as difficult as possible: +- All bytes on the wire are indistinguishable from random +- No static signatures or patterns +- Padding ranges vary per access key +- The binary contains no protocol-specific strings + +However, traffic analysis (timing, volume patterns) may still reveal tunnel usage. OSTP includes adaptive padding to mitigate this. + +### What does Kerckhoffs's principle mean for OSTP? + +It means that even with full access to the source code and binary, an adversary cannot build a DPI filter without knowing a valid access key. The protocol's security depends solely on the secrecy of the key. + +--- + +[← Building from Source](Building-from-Source) | [Home](Home) diff --git a/GUI-Client.md b/GUI-Client.md new file mode 100644 index 0000000..fcf3477 --- /dev/null +++ b/GUI-Client.md @@ -0,0 +1,59 @@ +# GUI Client + +## Overview + +The OSTP GUI is a Windows desktop application built with Tauri v2. It provides a visual interface for connecting to OSTP servers with support for both proxy and TUN tunnel modes. + +## Requirements + +- Windows 10/11 (x64 or ARM64) +- Administrator privileges (required for TUN mode) +- `wintun.dll` and `tun2socks.exe` in the same directory (included in release archive) + +## Features + +- One-click connection with power button +- Real-time upload/download metrics +- System proxy and TUN tunnel modes +- Import server configuration via `ostp://` share links +- Domain, IP/CIDR, and process exclusions +- Bilingual interface (English / Russian) + +## Modes + +### Proxy Mode + +Creates a local HTTP/SOCKS5 proxy (default: `127.0.0.1:1088`). Applications must be configured to use this proxy. + +### TUN Mode + +Creates a virtual network interface (`ostp_tun`) that captures all system traffic. No per-application configuration needed. + +**TUN mode requires:** +- Running as Administrator +- `wintun.dll` in the application directory +- `tun2socks.exe` in the application directory + +## Keyboard Shortcuts + +| Key | Action | +|---|---| +| Enter (in import field) | Import share link | + +## Troubleshooting + +### "tun2socks.exe is missing" + +Download from [tun2socks releases](https://github.com/xjasonlyu/tun2socks/releases) and place in the application directory. + +### TUN interface shows as "ostp_tun 2" + +This happens when the previous adapter wasn't cleaned up. The application now automatically removes stale adapters on startup. If the issue persists, manually delete the adapter in Network Connections. + +### Internet doesn't work after disconnecting + +If the tunnel crashes, routes may not be cleaned up. Restart the application — it cleans up routes on startup. + +--- + +[← Share Links](Share-Links) | [Building from Source →](Building-from-Source) diff --git a/Home.md b/Home.md index cd7adec..b58540e 100644 --- a/Home.md +++ b/Home.md @@ -1 +1,32 @@ -Welcome to the ostp wiki! +# OSTP — Obfuscated Secure Transport Protocol + +Welcome to the OSTP Wiki. + +## Quick Navigation + +| Page | Description | +|---|---| +| [Installation](Installation) | Server & client setup guide | +| [Configuration](Configuration) | Full configuration reference | +| [Protocol Design](Protocol-Design) | Wire format, cryptography, DPI resistance | +| [GUI Client](GUI-Client) | Windows desktop application guide | +| [Share Links](Share-Links) | `ostp://` URI format reference | +| [Building from Source](Building-from-Source) | Compilation guide for all platforms | +| [FAQ](FAQ) | Frequently asked questions | + +## What is OSTP? + +OSTP is a UDP-based encrypted tunneling protocol designed for maximum DPI/TSPU resistance. Every byte on the wire is cryptographically indistinguishable from random noise. + +### Key Features + +- **Full DPI resistance** — Kerckhoffs's principle compliant, no protocol fingerprints in binary +- **Per-session key derivation** — HKDF-SHA256 based, unique masks per packet +- **Noise_NNpsk0 handshake** — X25519 + ChaChaPoly + BLAKE2s +- **ARQ reliability** — Selective acknowledgments over UDP +- **Adaptive padding** — Key-derived, per-user packet size distributions +- **Cross-platform** — Windows, Linux, macOS, Android, FreeBSD, MIPS, RISC-V + +### Releases + +Download the latest release: [GitHub Releases](https://github.com/ospab/ostp/releases) diff --git a/Installation.md b/Installation.md new file mode 100644 index 0000000..44efd7c --- /dev/null +++ b/Installation.md @@ -0,0 +1,116 @@ +# Installation + +## Server + +### Quick Install (Linux) + +```bash +# Download latest release +curl -Lo ostp.tar.gz https://github.com/ospab/ostp/releases/latest/download/ostp-linux-amd64.tar.gz +tar xzf ostp.tar.gz +chmod +x ostp +``` + +### Configuration + +Create `config.json` in the same directory: + +```json +{ + "mode": "server", + "listen": "0.0.0.0:50000", + "access_keys": ["your-secret-key-here"], + "log_level": "info" +} +``` + +### Run + +```bash +./ostp +``` + +### Systemd Service + +```bash +sudo tee /etc/systemd/system/ostp.service << 'EOF' +[Unit] +Description=OSTP Server +After=network.target + +[Service] +Type=simple +WorkingDirectory=/opt/ostp +ExecStart=/opt/ostp/ostp +Restart=always +RestartSec=3 + +[Install] +WantedBy=multi-user.target +EOF + +sudo systemctl enable --now ostp +``` + +## Client + +### Windows (GUI) + +1. Download `ostp-windows-gui-x64.zip` from [Releases](https://github.com/ospab/ostp/releases) +2. Extract all files to a folder +3. Run `ostp-gui.exe` **as Administrator** (required for TUN mode) +4. Enter server address and access key in Settings +5. Press the power button to connect + +### Windows (CLI) + +1. Download `ostp-windows-amd64.zip` from Releases +2. Create `config.json`: + +```json +{ + "mode": "client", + "server": "your-server:50000", + "access_key": "your-secret-key" +} +``` + +3. Run: `ostp.exe` + +### Linux (CLI) + +```bash +# Download and configure +curl -Lo ostp.tar.gz https://github.com/ospab/ostp/releases/latest/download/ostp-linux-amd64.tar.gz +tar xzf ostp.tar.gz +chmod +x ostp + +# Create client config +cat > config.json << 'EOF' +{ + "mode": "client", + "server": "your-server:50000", + "access_key": "your-secret-key" +} +EOF + +./ostp +``` + +### macOS + +```bash +curl -Lo ostp.tar.gz https://github.com/ospab/ostp/releases/latest/download/ostp-darwin-arm64.tar.gz +tar xzf ostp.tar.gz +chmod +x ostp +# Same config.json as Linux +./ostp +``` + +### Android + +Use the OSTP JNI library with your Android VPN application. See [Building from Source](Building-from-Source) for JNI compilation. + +--- + +[← Home](Home) | [Configuration →](Configuration) diff --git a/Protocol-Design.md b/Protocol-Design.md new file mode 100644 index 0000000..b623765 --- /dev/null +++ b/Protocol-Design.md @@ -0,0 +1,120 @@ +# Protocol Design + +## Overview + +OSTP (Obfuscated Secure Transport Protocol) is a UDP-based encrypted tunnel designed for maximum resistance to Deep Packet Inspection (DPI) and Traffic Shaping (TSPU) systems. + +### Design Principles + +1. **Kerckhoffs's Principle** — Security depends solely on the access key. The binary contains no protocol-specific strings or magic constants. +2. **Per-packet indistinguishability** — Every byte on the wire is cryptographically random. No handshake signatures, version fields, or fixed patterns. +3. **Key-derived everything** — Obfuscation masks, PSK, and even padding ranges are derived from the access key via HKDF-SHA256. + +## Wire Format + +### Handshake Packet + +``` +[session_id:4][noise_len:2][noise_payload:N][random_padding:var] + ↑ XOR-masked ↑ Cleartext (used to derive mask) +``` + +- **session_id** (4 bytes) — Random per-session identifier, XOR-masked +- **noise_len** (2 bytes) — Length of Noise payload, XOR-masked +- **noise_payload** (N bytes) — Noise_NNpsk0 handshake message +- **random_padding** (key-derived range) — Random bytes to prevent size fingerprinting + +### Data Packet (Post-Handshake) + +``` +[session_id:4][nonce:8][AEAD_ciphertext:N] + ↑ XOR-masked ↑ XOR-masked ↑ ChaCha20-Poly1305 encrypted +``` + +### Obfuscation Mask Derivation + +The 6-byte header mask for handshake packets is derived from the Noise payload: + +``` +sample = packet[6..38] // First 32 bytes of payload +mask = HMAC-SHA256(obfuscation_key, sample)[0..6] +header ^= mask +``` + +For data packets, the mask is derived from the ciphertext: + +``` +sample = packet[12..44] // First 32 bytes of ciphertext +mask = HMAC-SHA256(obfuscation_key, sample)[0..12] +header ^= mask +``` + +Since the Noise ephemeral key is cryptographically random and the AEAD ciphertext is indistinguishable from random, the mask is unique per packet. + +## Key Derivation + +All secrets are derived from a single `access_key` using HKDF-SHA256 (RFC 5869): + +``` +key_hash = SHA-256(access_key) +salt = key_hash[0..16] +info = key_hash[16..32] +prk = HMAC-SHA256(salt, access_key) + +obfuscation_key = HKDF-Expand(prk, info || 0x01, 8) +psk = HKDF-Expand(prk, info || 0x02, 32) +pad_params = HKDF-Expand(prk, info || 0x03, 2) +``` + +The padding range is computed from `pad_params`: +- `pad_min = 16 + (pad_params[0] % 64)` → range [16, 79] +- `pad_max = pad_min + 48 + (pad_params[1] % 128)` → pad_min + [48, 175] + +Different access keys produce different padding distributions, making universal size-based filters impossible. + +## Noise Protocol + +OSTP uses the **Noise_NNpsk0** pattern: + +``` +Noise_NNpsk0(psk): + → psk, e + ← e, ee +``` + +- **NN** — No static keys (anonymous) +- **psk0** — Pre-shared key injected at position 0 +- **Primitives**: X25519, ChaChaPoly, BLAKE2s + +The PSK is derived from the access key, preventing unauthorized parties from completing the handshake. + +## ARQ (Automatic Repeat Request) + +OSTP includes a selective-acknowledgment ARQ layer over UDP: + +| Parameter | Default | Description | +|---|---|---| +| `max_reorder` | 16384 | Maximum gap between expected and received nonce | +| `reorder_buf` | 8192 | Maximum buffered out-of-order frames | +| `rto` | 100ms | Retransmission timeout | +| `max_retries` | 8 | Maximum retransmission attempts | + +## DPI Resistance Analysis + +### What a DPI system sees + +- **No magic bytes** — First bytes are XOR-masked with key-derived randomness +- **No fixed packet sizes** — Padding range varies per access key +- **No protocol strings in binary** — HKDF salt/info derived from key hash +- **No version fields** — Entire header is masked +- **UDP packets** — Indistinguishable from QUIC, WireGuard, or random UDP traffic + +### What remains identifiable + +- **UDP traffic on a fixed port** — Mitigated by using common ports (443, 8443) +- **Traffic patterns** — Mitigated by adaptive padding strategy +- **Noise pattern string in binary** — `"Noise_NNpsk0_25519_ChaChaPoly_BLAKE2s"` is standard and shared by thousands of projects + +--- + +[← Configuration](Configuration) | [Share Links →](Share-Links) diff --git a/Share-Links.md b/Share-Links.md new file mode 100644 index 0000000..69ad07f --- /dev/null +++ b/Share-Links.md @@ -0,0 +1,42 @@ +# Share Links + +## Format + +``` +ostp://ACCESS_KEY@HOST:PORT#LABEL +``` + +### Components + +| Component | Required | Description | +|---|---|---| +| `ACCESS_KEY` | ✅ | URL-encoded access key | +| `HOST` | ✅ | Server hostname or IP | +| `PORT` | ✅ | Server port | +| `LABEL` | ❌ | URL-encoded server label | + +### Examples + +``` +ostp://my-secret-key@example.com:50000#My%20Server +ostp://abc123@192.168.1.100:50000 +ostp://complex%2Fkey%3Dwith%20special@server.com:443#Production +``` + +### Parsing Rules + +1. Scheme must be `ostp://` +2. Access key is extracted from the `username` component of the URL +3. Host and port from the `host` component +4. Label (server name) from the `fragment` (`#`) + +### Client Import + +The OSTP GUI and CLI support importing share links: + +- **GUI**: Paste into the import field on the Settings screen +- **CLI**: `ostp --import "ostp://key@host:port"` + +--- + +[← Protocol Design](Protocol-Design) | [GUI Client →](GUI-Client) diff --git a/_Sidebar.md b/_Sidebar.md new file mode 100644 index 0000000..ae71509 --- /dev/null +++ b/_Sidebar.md @@ -0,0 +1,10 @@ +**OSTP Wiki** + +- [Home](Home) +- [Installation](Installation) +- [Configuration](Configuration) +- [Protocol Design](Protocol-Design) +- [Share Links](Share-Links) +- [GUI Client](GUI-Client) +- [Building from Source](Building-from-Source) +- [FAQ](FAQ)