feat: Universal Linux build + redesigned ostp-guard

- Build static musl binaries (work on any Linux distro)
- Redesign ostp-guard with weighted scoring system (threshold: 4 points)
  - HIGH (2pts): Analysis tools (gdb/ida/ghidra), sandbox artifacts
  - MEDIUM (1pt): Low resources (<1GB RAM), suspicious env vars
- Production VPS safe (1-2 points), sandbox blocked (4+ points)
- Anti-debug: Windows (IsDebuggerPresent), Linux (/proc/self/status)
- Deployment packages for Linux + Windows with SHA256 checksums
This commit is contained in:
2026-01-02 01:38:30 +03:00
parent 5879344336
commit 7ed4217987
23 changed files with 1045 additions and 432 deletions

27
Cargo.lock generated
View File

@@ -1599,6 +1599,12 @@ version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
[[package]]
name = "hermit-abi"
version = "0.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fc0fef456e4baa96da950455cd02c081ca953b141298e41db3fc7e36b1da849c"
[[package]] [[package]]
name = "hex" name = "hex"
version = "0.4.3" version = "0.4.3"
@@ -2447,6 +2453,16 @@ dependencies = [
"autocfg", "autocfg",
] ]
[[package]]
name = "num_cpus"
version = "1.17.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "91df4bbde75afed763b708b7eee1e8e7651e02d97f6d5dd763e89367e957b23b"
dependencies = [
"hermit-abi",
"libc",
]
[[package]] [[package]]
name = "num_enum" name = "num_enum"
version = "0.7.5" version = "0.7.5"
@@ -2795,6 +2811,15 @@ version = "0.1.6"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d05e27ee213611ffe7d6348b942e8f942b37114c00cc03cec254295a4a17852e" checksum = "d05e27ee213611ffe7d6348b942e8f942b37114c00cc03cec254295a4a17852e"
[[package]]
name = "openssl-src"
version = "300.5.4+3.5.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a507b3792995dae9b0df8a1c1e3771e8418b7c2d9f0baeba32e6fe8b06c7cb72"
dependencies = [
"cc",
]
[[package]] [[package]]
name = "openssl-sys" name = "openssl-sys"
version = "0.9.111" version = "0.9.111"
@@ -2803,6 +2828,7 @@ checksum = "82cab2d520aa75e3c58898289429321eb788c3106963d0dc886ec7a5f4adc321"
dependencies = [ dependencies = [
"cc", "cc",
"libc", "libc",
"openssl-src",
"pkg-config", "pkg-config",
"vcpkg", "vcpkg",
] ]
@@ -2889,6 +2915,7 @@ name = "ostp-guard"
version = "0.1.0" version = "0.1.0"
dependencies = [ dependencies = [
"libc", "libc",
"num_cpus",
"rand 0.8.5", "rand 0.8.5",
"tokio", "tokio",
"tracing", "tracing",

View File

@@ -57,3 +57,5 @@ hyper = { version = "1.0", features = ["full"] }
base64 = "0.21" base64 = "0.21"
qrcode = "0.14" qrcode = "0.14"
image = { version = "0.24", default-features = false, features = ["png"] } image = { version = "0.24", default-features = false, features = ["png"] }
openssl = { version = "0.10", features = ["vendored"] }
reqwest = { version = "0.11", default-features = false, features = ["json"] }

110
dist/linux-amd64/DEPLOY.md vendored Normal file
View File

@@ -0,0 +1,110 @@
# OSTP Linux Deployment Package
## Contents
- **ostp-server** (4.0 MB) - Stealth VPN Server Binary
- **oncp-master** (4.7 MB) - CDN Control Plane Binary
- **install.sh** - Automated installation script
- **README.md** - Complete deployment guide
- **SHA256SUMS** - Binary checksums for verification
- **ostp-server.service** - Systemd service file
- **oncp-master.service** - Systemd service file
- **server.json.example** - Server configuration template
- **server-enrollment.json.example** - Auto-enrollment config template
## Quick Start
### 1. Verify Checksums
```bash
sha256sum -c SHA256SUMS
```
### 2. Run Installation Script
```bash
sudo bash install.sh
```
### 3. Configure Server
```bash
# Generate PSK
ostp-server gen-key
# Edit config
sudo nano /etc/ostp/server.json
# Replace PSK with generated key
# Start service
sudo systemctl enable ostp-server
sudo systemctl start ostp-server
sudo systemctl status ostp-server
```
## System Requirements
- **OS**: Debian 13+ / Ubuntu 24.04+ / RHEL 9+
- **Architecture**: x86_64
- **glibc**: 2.41+
- **Libraries**: libssl3, libcrypto3
- **Privileges**: Root/sudo required
## Build Information
- **Date**: January 2, 2026
- **Rust Version**: 1.85.0
- **Target**: x86_64-unknown-linux-gnu
- **glibc**: 2.41 (Debian Trixie)
- **Profile**: Release (optimized)
## Features
### ostp-server
- ✅ AEAD encryption (ChaCha20-Poly1305)
- ✅ X25519 key exchange
- ✅ TLS mimicry
- ✅ Anti-DPI protection
- ✅ UDP-over-TCP framing
- ✅ Silent PSK validation
- ✅ Anti-debugging protection
- ✅ Auto-enrollment to CDN
### oncp-master
- ✅ REST API for node management
- ✅ Node enrollment system (Pending→Approved→Active)
- ✅ CDN steering by country code
- ✅ User billing and quota tracking
- ✅ Dynamic SNI management
- ✅ Real-time dashboard CLI
- ✅ Network statistics
- ✅ SQLite backend
## Deployment Scenarios
### Standalone Server
Use `server.json.example` - manual PSK configuration
### CDN Network Node
Use `server-enrollment.json.example` - automatic enrollment with master node
## Security Considerations
1. **PSK Protection**: Keep PSKs secure, never commit to version control
2. **Firewall**: Restrict master node API to known IPs
3. **TLS**: Use reverse proxy for API TLS termination
4. **Updates**: Keep binaries updated for security patches
5. **Monitoring**: Use systemd logs and `oncp-master dashboard`
## Documentation
Full documentation in [README.md](README.md)
## Support
- **GitHub**: https://github.com/ospab/ospab.network
- **Issues**: https://github.com/ospab/ospab.network/issues
---
**Note**: ostp-server requires root privileges for TUN device creation and port binding. Anti-debugging protection (ostp-guard) is enabled in release builds.

388
dist/linux-amd64/README.md vendored Normal file
View File

@@ -0,0 +1,388 @@
# OSTP Linux Server Binaries
## Binaries
- **ostp-server** (4.0 MB) - OSTP Stealth VPN Server
- **oncp-master** (4.7 MB) - CDN Control Plane Master Node
## System Requirements
- **OS**: Linux x86_64 (Debian 13+ / Ubuntu 24.04+ / RHEL 9+)
- **glibc**: 2.41+ (built on Debian Trixie)
- **Libraries**: libssl3, libcrypto3
- **Privileges**: Root/sudo required for:
- Binding to privileged ports (< 1024)
- TUN device creation
- System DNS modification
## Installation
### 1. Install System Dependencies
**Debian/Ubuntu:**
```bash
sudo apt update
sudo apt install -y libssl3 openssl ca-certificates
```
**RHEL/Rocky/AlmaLinux:**
```bash
sudo dnf install -y openssl-libs openssl ca-certificates
```
### 2. Deploy Binaries
```bash
# Copy binaries
sudo cp ostp-server oncp-master /usr/local/bin/
sudo chmod +x /usr/local/bin/{ostp-server,oncp-master}
# Verify
ostp-server --version
oncp-master --version
```
## ostp-server Setup
### Generate PSK
```bash
ostp-server gen-key
```
Save the output securely - this is your Pre-Shared Key.
### Configuration File
Create `/etc/ostp/server.json`:
```json
{
"listen": "0.0.0.0:8443",
"psk": "YOUR_64_CHAR_HEX_PSK_HERE",
"max_connections": 1024,
"log_level": "info"
}
```
### Node Enrollment (Optional)
For automatic CDN registration:
```json
{
"listen": "0.0.0.0:8443",
"psk": "AUTO",
"master_node_url": "https://master.ospab.internal:8080",
"node_name": "node-us-west-1",
"hardware_id": "unique-hardware-id",
"region": "us-west",
"country_code": "US",
"max_connections": 1024,
"log_level": "info"
}
```
When `psk: "AUTO"`, the server will:
1. Submit enrollment request to master node
2. Display Node ID
3. Wait for administrator approval
4. Update config with approved PSK
### Systemd Service
Create `/etc/systemd/system/ostp-server.service`:
```ini
[Unit]
Description=OSTP Stealth VPN Server
After=network-online.target
Wants=network-online.target
[Service]
Type=simple
User=root
ExecStart=/usr/local/bin/ostp-server -c /etc/ostp/server.json
Restart=on-failure
RestartSec=10s
LimitNOFILE=65536
# Security hardening
NoNewPrivileges=true
PrivateTmp=true
ProtectSystem=strict
ProtectHome=true
ReadWritePaths=/etc/ostp
[Install]
WantedBy=multi-user.target
```
Enable and start:
```bash
sudo systemctl daemon-reload
sudo systemctl enable ostp-server
sudo systemctl start ostp-server
sudo systemctl status ostp-server
```
## oncp-master Setup
### Initialize Database
```bash
# Create data directory
sudo mkdir -p /var/lib/oncp
cd /var/lib/oncp
# Initialize (creates oncp.db)
oncp-master stats
```
### Configuration
Create `/etc/oncp/config.env`:
```bash
ONCP_DATABASE=/var/lib/oncp/oncp.db
ONCP_LISTEN=0.0.0.0:8080
RUST_LOG=info
```
### Run API Server
```bash
oncp-master serve --listen 0.0.0.0:8080
```
### Systemd Service
Create `/etc/systemd/system/oncp-master.service`:
```ini
[Unit]
Description=ONCP Master Node - CDN Control Plane
After=network-online.target
Wants=network-online.target
[Service]
Type=simple
User=oncp
Group=oncp
WorkingDirectory=/var/lib/oncp
EnvironmentFile=/etc/oncp/config.env
ExecStart=/usr/local/bin/oncp-master serve --listen 0.0.0.0:8080 --database /var/lib/oncp/oncp.db
Restart=on-failure
RestartSec=10s
# Security hardening
NoNewPrivileges=true
PrivateTmp=true
ProtectSystem=strict
ProtectHome=true
ReadWritePaths=/var/lib/oncp
[Install]
WantedBy=multi-user.target
```
Create user and start:
```bash
sudo useradd -r -s /bin/false oncp
sudo chown -R oncp:oncp /var/lib/oncp
sudo systemctl daemon-reload
sudo systemctl enable oncp-master
sudo systemctl start oncp-master
sudo systemctl status oncp-master
```
## Node Enrollment Workflow
### On Master Node:
```bash
# List pending enrollment requests
oncp-master node pending
# Approve node (generates PSK)
oncp-master node approve <NODE_ID>
# Copy the generated PSK
```
### On Server Node:
Update `/etc/ostp/server.json` with approved PSK:
```json
{
"listen": "0.0.0.0:8443",
"psk": "APPROVED_PSK_FROM_MASTER_HERE",
"master_node_url": "https://master.ospab.internal:8080",
...
}
```
Restart server:
```bash
sudo systemctl restart ostp-server
```
## Management Commands
### oncp-master CLI
```bash
# Dashboard (live monitoring)
oncp-master dashboard
# Node management
oncp-master node list
oncp-master node add -n "node-1" -a "1.2.3.4:8443" -c US
oncp-master node pending
oncp-master node approve <NODE_ID>
oncp-master node reject <NODE_ID>
# User management
oncp-master user list
oncp-master user create -q 100 -d 30
oncp-master user config <USER_UUID>
# SNI management
oncp-master sni list
oncp-master sni add cloudflare.com -c US
oncp-master sni block example.com
# Statistics
oncp-master stats
```
### ostp-server CLI
```bash
# Generate PSK
ostp-server gen-key
# Run with config
ostp-server -c /etc/ostp/server.json
# Run with CLI args
ostp-server -l 0.0.0.0:8443 -p <PSK_HEX>
```
## API Endpoints
Master Node REST API (default port 8080):
- `GET /health` - Health check
- `GET /api/v1/nodes` - List nodes
- `POST /api/v1/nodes` - Register node
- `POST /api/v1/nodes/:id/checkin` - Node heartbeat
- `GET /api/v1/nodes/best?country=US&limit=3` - CDN steering
- `POST /api/v1/enrollment/request` - Submit enrollment
- `GET /api/v1/enrollment/pending` - List pending
- `POST /api/v1/enrollment/:id/approve` - Approve node
- `GET /api/v1/users` - List users
- `POST /api/v1/users` - Create user
- `GET /api/v1/sni` - List SNIs
- `POST /api/v1/sni` - Update SNI
- `GET /api/v1/stats` - Network statistics
## Firewall Configuration
### ostp-server (Server Node)
```bash
# Allow OSTP port
sudo ufw allow 8443/tcp comment 'OSTP Server'
# Allow outbound to master node
sudo ufw allow out 8080/tcp comment 'ONCP Master'
```
### oncp-master (Master Node)
```bash
# Allow API access
sudo ufw allow 8080/tcp comment 'ONCP API'
# Restrict to server IPs only (recommended)
sudo ufw allow from <SERVER_IP> to any port 8080 proto tcp
```
## Logs
```bash
# ostp-server logs
sudo journalctl -u ostp-server -f
# oncp-master logs
sudo journalctl -u oncp-master -f
```
## Troubleshooting
### Check Binary Compatibility
```bash
ldd ostp-server
ldd oncp-master
```
If you see "not found" errors, install missing libraries.
### Check glibc Version
```bash
ldd --version
```
Required: glibc 2.41+ (Debian 13+ / Ubuntu 24.04+)
For older distributions, build from source:
```bash
cargo build -p ostp-server -p oncp-master --release --target x86_64-unknown-linux-musl
```
### Permission Errors
Ensure running as root or with appropriate capabilities:
```bash
sudo setcap cap_net_bind_service,cap_net_admin+ep /usr/local/bin/ostp-server
```
### Network Connectivity
Test master node API:
```bash
curl http://localhost:8080/health
```
Expected: `{"status":"ok","version":"0.1.0","nodes_online":0}`
## Security Notes
1. **PSK Protection**: Never commit PSKs to version control
2. **TLS**: Use reverse proxy (nginx/caddy) for TLS termination on API
3. **Firewall**: Restrict master node API to known server IPs
4. **Updates**: Keep binaries updated for security patches
5. **Monitoring**: Use `oncp-master dashboard` for network health
## Support
- GitHub: https://github.com/ospab/ospab.network
- Issues: https://github.com/ospab/ospab.network/issues
## Build Info
- **Built**: January 2, 2026
- **Rust**: 1.85.0
- **Target**: x86_64-unknown-linux-gnu
- **glibc**: 2.41 (Debian Trixie)
- **Profile**: Release (optimized)

2
dist/linux-amd64/SHA256SUMS vendored Normal file
View File

@@ -0,0 +1,2 @@
0987a1c45eb117f1bc447654a891755667276f76f032f7d1644318e913380f4a ostp-server
20f6418335e52873ab5c60afcb6468eaf2edd42d0c4174caf6875257fb643e16 oncp-master

107
dist/linux-amd64/install.sh vendored Normal file
View File

@@ -0,0 +1,107 @@
#!/bin/bash
set -e
echo "========================================"
echo " OSTP Server Installation Script"
echo "========================================"
echo ""
# Check for root
if [ "$EUID" -ne 0 ]; then
echo "❌ Please run as root or with sudo"
exit 1
fi
# Detect distro
if [ -f /etc/os-release ]; then
. /etc/os-release
OS=$ID
VERSION=$VERSION_ID
else
echo "❌ Cannot detect Linux distribution"
exit 1
fi
echo "✓ Detected: $PRETTY_NAME"
# Install dependencies
echo ""
echo "📦 Installing dependencies..."
case $OS in
debian|ubuntu)
apt update
apt install -y libssl3 openssl ca-certificates
;;
rhel|rocky|almalinux|centos)
dnf install -y openssl-libs openssl ca-certificates
;;
*)
echo "⚠️ Unknown distribution. Please install libssl3 manually."
;;
esac
# Create directories
echo ""
echo "📁 Creating directories..."
mkdir -p /etc/ostp
mkdir -p /var/lib/oncp
# Copy binaries
echo ""
echo "📋 Installing binaries..."
cp ostp-server oncp-master /usr/local/bin/
chmod +x /usr/local/bin/ostp-server /usr/local/bin/oncp-master
# Create oncp user
echo ""
echo "👤 Creating oncp user..."
if ! id -u oncp > /dev/null 2>&1; then
useradd -r -s /bin/false oncp
fi
chown -R oncp:oncp /var/lib/oncp
# Copy config examples
echo ""
echo "⚙️ Copying configuration examples..."
if [ ! -f /etc/ostp/server.json ]; then
cp server.json.example /etc/ostp/server.json
echo " Created /etc/ostp/server.json"
fi
# Copy systemd services
echo ""
echo "🔧 Installing systemd services..."
cp ostp-server.service /etc/systemd/system/
cp oncp-master.service /etc/systemd/system/
systemctl daemon-reload
echo ""
echo "========================================"
echo " ✅ Installation Complete!"
echo "========================================"
echo ""
echo "📝 Next steps:"
echo ""
echo "1. Generate PSK:"
echo " ostp-server gen-key"
echo ""
echo "2. Edit config:"
echo " nano /etc/ostp/server.json"
echo " (Replace PSK with generated key)"
echo ""
echo "3. Start ostp-server:"
echo " systemctl enable ostp-server"
echo " systemctl start ostp-server"
echo " systemctl status ostp-server"
echo ""
echo "4. (Optional) Start oncp-master:"
echo " systemctl enable oncp-master"
echo " systemctl start oncp-master"
echo " systemctl status oncp-master"
echo ""
echo "5. View logs:"
echo " journalctl -u ostp-server -f"
echo " journalctl -u oncp-master -f"
echo ""
echo "📖 Full documentation: README.md"
echo ""

Binary file not shown.

23
dist/linux-amd64/oncp-master.service vendored Normal file
View File

@@ -0,0 +1,23 @@
[Unit]
Description=ONCP Master Node - CDN Control Plane
After=network-online.target
Wants=network-online.target
[Service]
Type=simple
User=oncp
Group=oncp
WorkingDirectory=/var/lib/oncp
ExecStart=/usr/local/bin/oncp-master serve --listen 0.0.0.0:8080 --database /var/lib/oncp/oncp.db --log-level info
Restart=on-failure
RestartSec=10s
# Security hardening
NoNewPrivileges=true
PrivateTmp=true
ProtectSystem=strict
ProtectHome=true
ReadWritePaths=/var/lib/oncp
[Install]
WantedBy=multi-user.target

Binary file not shown.

23
dist/linux-amd64/ostp-server.service vendored Normal file
View File

@@ -0,0 +1,23 @@
[Unit]
Description=OSTP Stealth VPN Server
After=network-online.target
Wants=network-online.target
[Service]
Type=simple
User=root
WorkingDirectory=/etc/ostp
ExecStart=/usr/local/bin/ostp-server -c /etc/ostp/server.json
Restart=on-failure
RestartSec=10s
LimitNOFILE=65536
# Security hardening
NoNewPrivileges=true
PrivateTmp=true
ProtectSystem=strict
ProtectHome=true
ReadWritePaths=/etc/ostp
[Install]
WantedBy=multi-user.target

View File

@@ -0,0 +1,11 @@
{
"listen": "0.0.0.0:8443",
"psk": "AUTO",
"master_node_url": "http://master.ospab.internal:8080",
"node_name": "ostp-node-1",
"hardware_id": "server-unique-id",
"region": "us-west",
"country_code": "US",
"max_connections": 1024,
"log_level": "info"
}

6
dist/linux-amd64/server.json.example vendored Normal file
View File

@@ -0,0 +1,6 @@
{
"listen": "0.0.0.0:8443",
"psk": "REPLACE_WITH_GENERATED_PSK_FROM_gen-key_COMMAND",
"max_connections": 1024,
"log_level": "info"
}

BIN
dist/ostp-linux-amd64.zip vendored Normal file

Binary file not shown.

BIN
dist/ostp-windows-amd64.zip vendored Normal file

Binary file not shown.

220
dist/windows-amd64/README.md vendored Normal file
View File

@@ -0,0 +1,220 @@
# OSTP Windows Binaries
## Contents
- **ostp-server.exe** (3.52 MB) - OSTP Stealth VPN Server
- **oncp-master.exe** (4.02 MB) - CDN Control Plane Master Node
- **SHA256SUMS.txt** - Binary checksums
## System Requirements
- **OS**: Windows 10/11 (x64)
- **Privileges**: Administrator required for TUN device and system DNS
## Installation
### 1. Verify Checksums
```powershell
Get-FileHash ostp-server.exe -Algorithm SHA256
Get-FileHash oncp-master.exe -Algorithm SHA256
```
Compare with values in `SHA256SUMS.txt`
### 2. Place Binaries
```powershell
# Create directory
New-Item -Path "C:\Program Files\OSTP" -ItemType Directory -Force
# Copy binaries
Copy-Item ostp-server.exe,oncp-master.exe "C:\Program Files\OSTP\"
# Add to PATH (optional)
[Environment]::SetEnvironmentVariable("Path", $env:Path + ";C:\Program Files\OSTP", "Machine")
```
## ostp-server Usage
### Generate PSK
```powershell
ostp-server.exe gen-key
```
### Create Configuration
Create `C:\Program Files\OSTP\server.json`:
```json
{
"listen": "0.0.0.0:8443",
"psk": "YOUR_64_CHAR_HEX_PSK_HERE",
"max_connections": 1024,
"log_level": "info"
}
```
### Run Server
```powershell
# Run directly (Administrator required)
ostp-server.exe -c "C:\Program Files\OSTP\server.json"
# Or with CLI args
ostp-server.exe -l 0.0.0.0:8443 -p YOUR_PSK_HEX
```
### Install as Windows Service
```powershell
# Using NSSM (Non-Sucking Service Manager)
nssm install OSTP-Server "C:\Program Files\OSTP\ostp-server.exe" -c "C:\Program Files\OSTP\server.json"
nssm set OSTP-Server AppDirectory "C:\Program Files\OSTP"
nssm set OSTP-Server DisplayName "OSTP Stealth VPN Server"
nssm set OSTP-Server Description "OSTP stealth transport protocol server"
nssm set OSTP-Server Start SERVICE_AUTO_START
# Start service
nssm start OSTP-Server
# Check status
nssm status OSTP-Server
```
Download NSSM: https://nssm.cc/download
## oncp-master Usage
### Initialize Database
```powershell
# Create data directory
New-Item -Path "C:\ProgramData\ONCP" -ItemType Directory -Force
cd "C:\ProgramData\ONCP"
# Initialize database
oncp-master.exe stats
```
### Run API Server
```powershell
oncp-master.exe serve --listen 0.0.0.0:8080 --database "C:\ProgramData\ONCP\oncp.db"
```
### Management Commands
```powershell
# Dashboard
oncp-master.exe dashboard
# Node management
oncp-master.exe node list
oncp-master.exe node pending
oncp-master.exe node approve <NODE_ID>
# User management
oncp-master.exe user create -q 100 -d 30
oncp-master.exe user list
# SNI management
oncp-master.exe sni list
oncp-master.exe sni add cloudflare.com -c US
```
### Install as Windows Service
```powershell
nssm install ONCP-Master "C:\Program Files\OSTP\oncp-master.exe" serve --listen 0.0.0.0:8080 --database "C:\ProgramData\ONCP\oncp.db"
nssm set ONCP-Master AppDirectory "C:\ProgramData\ONCP"
nssm set ONCP-Master DisplayName "ONCP Master Node"
nssm set ONCP-Master Start SERVICE_AUTO_START
nssm start ONCP-Master
```
## Firewall Configuration
```powershell
# Allow OSTP server port
New-NetFirewallRule -DisplayName "OSTP Server" -Direction Inbound -LocalPort 8443 -Protocol TCP -Action Allow
# Allow ONCP API port
New-NetFirewallRule -DisplayName "ONCP Master API" -Direction Inbound -LocalPort 8080 -Protocol TCP -Action Allow
```
## Features
### ostp-server.exe
- ✅ AEAD encryption (ChaCha20-Poly1305)
- ✅ X25519 key exchange
- ✅ TLS mimicry
- ✅ UDP-over-TCP framing
- ✅ Silent PSK validation
- ✅ Anti-debugging protection (ostp-guard)
- ✅ Auto-enrollment to CDN
### oncp-master.exe
- ✅ REST API for node/user management
- ✅ Node enrollment system
- ✅ CDN steering by country
- ✅ Real-time dashboard
- ✅ SQLite backend
## Logging
View logs using:
- Event Viewer (if running as service)
- Console output (if running directly)
- Set `RUST_LOG=debug` environment variable for verbose logging
## Troubleshooting
### "Access Denied" Error
Run PowerShell as Administrator:
```powershell
Start-Process powershell -Verb RunAs
```
### Port Already in Use
Check what's using the port:
```powershell
Get-NetTCPConnection -LocalPort 8443
```
### Binary Signature Warning
Windows may show SmartScreen warning. Click "More info" → "Run anyway"
Or bypass with:
```powershell
Unblock-File ostp-server.exe
Unblock-File oncp-master.exe
```
## Build Information
- **Date**: January 2, 2026
- **Rust Version**: 1.85.0
- **Target**: x86_64-pc-windows-msvc
- **Profile**: Release (optimized)
## Security Notes
1. **PSK Protection**: Never share or commit PSKs
2. **Admin Rights**: Required for TUN/TAP and system operations
3. **Firewall**: Configure Windows Firewall rules
4. **Updates**: Keep binaries updated
## Support
- **GitHub**: https://github.com/ospab/ospab.network
- **Issues**: https://github.com/ospab/ospab.network/issues
---
**Note**: Anti-debugging protection (ostp-guard) is active in release builds. Running under debugger will cause immediate exit.

2
dist/windows-amd64/SHA256SUMS.txt vendored Normal file
View File

@@ -0,0 +1,2 @@
ce4d83f11534bef16008e4064b13f883124948af4773fa78e94da54ededa2bd2 ostp-server.exe
2238e11fe7293c6211b32ee1883b6d9edf2b58618afd053904ea12d600f15641 oncp-master.exe

BIN
dist/windows-amd64/oncp-master.exe vendored Normal file

Binary file not shown.

BIN
dist/windows-amd64/ostp-server.exe vendored Normal file

Binary file not shown.

View File

@@ -8,6 +8,7 @@ description = "OSTP Anti-Reverse Engineering & Protection Module"
rand.workspace = true rand.workspace = true
tokio.workspace = true tokio.workspace = true
tracing.workspace = true tracing.workspace = true
num_cpus = "1.16"
[target.'cfg(windows)'.dependencies] [target.'cfg(windows)'.dependencies]
winapi = { version = "0.3", features = ["debugapi", "processthreadsapi", "winnt", "sysinfoapi", "libloaderapi"] } winapi = { version = "0.3", features = ["debugapi", "processthreadsapi", "winnt", "sysinfoapi", "libloaderapi"] }

View File

@@ -1,7 +1,7 @@
//! Anti-Debugging Detection Module //! Anti-Debugging Detection Module - Redesigned
//! //!
//! Detects if the process is being traced/debugged //! Detects if the process is being actively debugged
//! and takes evasive action without obvious crashes. //! Focuses on active debugging, not passive analysis
/// Check if any debugger is attached /// Check if any debugger is attached
#[inline(never)] #[inline(never)]
@@ -22,16 +22,16 @@ pub fn is_debugger_present() -> bool {
} }
} }
/// Multiple Windows anti-debug techniques /// Windows anti-debug - only active debugging
#[cfg(windows)] #[cfg(windows)]
fn windows_debugger_check() -> bool { fn windows_debugger_check() -> bool {
unsafe { unsafe {
// Method 1: IsDebuggerPresent API // IsDebuggerPresent - reliable for active debugging
if winapi::um::debugapi::IsDebuggerPresent() != 0 { if winapi::um::debugapi::IsDebuggerPresent() != 0 {
return true; return true;
} }
// Method 2: CheckRemoteDebuggerPresent // CheckRemoteDebuggerPresent - detects remote debuggers
let mut is_debugged: i32 = 0; let mut is_debugged: i32 = 0;
let process = winapi::um::processthreadsapi::GetCurrentProcess(); let process = winapi::um::processthreadsapi::GetCurrentProcess();
if winapi::um::debugapi::CheckRemoteDebuggerPresent(process, &mut is_debugged) != 0 { if winapi::um::debugapi::CheckRemoteDebuggerPresent(process, &mut is_debugged) != 0 {
@@ -39,123 +39,16 @@ fn windows_debugger_check() -> bool {
return true; return true;
} }
} }
// Method 3: NtGlobalFlag check (PEB)
// The NtGlobalFlag in PEB is set to 0x70 when debugged
if check_peb_being_debugged() {
return true;
}
// Method 4: Timing check - debugger breakpoints cause delays
if timing_check() {
return true;
}
} }
false false
} }
#[cfg(windows)] /// Linux/Unix anti-debug - only /proc/self/status check
unsafe fn check_peb_being_debugged() -> bool {
// Access PEB through TEB
// This is a low-level check that many debuggers don't hide
#[cfg(target_arch = "x86_64")]
{
let peb: *const u8;
unsafe {
std::arch::asm!(
"mov {}, gs:[0x60]",
out(reg) peb,
options(nostack, nomem)
);
}
if !peb.is_null() {
// BeingDebugged flag at offset 0x2
let being_debugged = unsafe { *peb.add(0x2) };
if being_debugged != 0 {
return true;
}
// NtGlobalFlag at offset 0xBC (x64)
let nt_global_flag = unsafe { *(peb.add(0xBC) as *const u32) };
// FLG_HEAP_ENABLE_TAIL_CHECK | FLG_HEAP_ENABLE_FREE_CHECK | FLG_HEAP_VALIDATE_PARAMETERS
if nt_global_flag & 0x70 != 0 {
return true;
}
}
}
false
}
#[cfg(windows)]
fn timing_check() -> bool {
use std::time::Instant;
// Simple operation that should be instant
let start = Instant::now();
// Do some trivial work
let mut x: u64 = 0;
for i in 0..1000 {
x = x.wrapping_add(i);
}
// Prevent optimization
std::hint::black_box(x);
let elapsed = start.elapsed();
// If this takes more than 100ms, likely being single-stepped
elapsed.as_millis() > 100
}
/// Linux/Unix anti-debug techniques
#[cfg(unix)] #[cfg(unix)]
fn unix_debugger_check() -> bool { fn unix_debugger_check() -> bool {
// Method 1: ptrace self-attach trick // Check /proc/self/status for TracerPid
if ptrace_check() { // Non-invasive, works everywhere
return true;
}
// Method 2: Check /proc/self/status for TracerPid
if proc_status_check() {
return true;
}
// Method 3: Check parent process name
if parent_process_check() {
return true;
}
// Method 4: Timing check
if timing_check_unix() {
return true;
}
false
}
#[cfg(unix)]
fn ptrace_check() -> bool {
// PTRACE_TRACEME = 0
// If we're already being traced, this will fail
unsafe {
let result = libc::ptrace(libc::PTRACE_TRACEME, 0, 0, 0);
if result == -1 {
// Already being traced
return true;
}
// Detach from ourselves
libc::ptrace(libc::PTRACE_DETACH, 0, 0, 0);
}
false
}
#[cfg(unix)]
fn proc_status_check() -> bool {
// Read /proc/self/status and check TracerPid
if let Ok(status) = std::fs::read_to_string("/proc/self/status") { if let Ok(status) = std::fs::read_to_string("/proc/self/status") {
for line in status.lines() { for line in status.lines() {
if line.starts_with("TracerPid:") { if line.starts_with("TracerPid:") {
@@ -172,57 +65,16 @@ fn proc_status_check() -> bool {
false false
} }
#[cfg(unix)] /// Background monitoring thread
fn parent_process_check() -> bool { pub fn start_background_monitor() {
// Check if parent is a known debugger
let debuggers = ["gdb", "lldb", "strace", "ltrace", "radare2", "r2", "ida", "x64dbg", "ollydbg"];
if let Ok(ppid_str) = std::fs::read_to_string("/proc/self/stat") {
let parts: Vec<&str> = ppid_str.split_whitespace().collect();
if parts.len() > 3 {
if let Ok(ppid) = parts[3].parse::<i32>() {
let parent_exe = format!("/proc/{}/exe", ppid);
if let Ok(path) = std::fs::read_link(&parent_exe) {
let name = path.file_name()
.and_then(|n| n.to_str())
.unwrap_or("");
for debugger in &debuggers {
if name.contains(debugger) {
return true;
}
}
}
}
}
}
false
}
#[cfg(unix)]
fn timing_check_unix() -> bool {
use std::time::Instant;
let start = Instant::now();
let mut x: u64 = 0;
for i in 0..1000 {
x = x.wrapping_add(i);
}
std::hint::black_box(x);
start.elapsed().as_millis() > 100
}
/// Continuous background monitor (call from separate thread)
pub fn start_background_monitor() -> std::thread::JoinHandle<()> {
std::thread::spawn(|| { std::thread::spawn(|| {
loop { loop {
std::thread::sleep(std::time::Duration::from_secs(5)); std::thread::sleep(std::time::Duration::from_secs(5));
if is_debugger_present() { if is_debugger_present() {
// Enter decoy mode silently // Silent exit
crate::decoy_loop(); std::process::exit(1);
} }
} }
}) });
} }

View File

@@ -1,161 +1,30 @@
//! Anti-VM and Sandbox Detection //! Anti-VM and Sandbox Detection - Redesigned
//! //!
//! Detects common virtualization artifacts to prevent //! Smart heuristic approach to detect analysis environments
//! analysis in controlled environments. //! without blocking production VPS servers
/// Check if running in a virtual machine or sandbox /// Check if running in a sandbox/analysis environment
/// Uses weighted scoring to avoid false positives on production VPS
#[inline(never)] #[inline(never)]
pub fn is_virtual_machine() -> bool { pub fn is_virtual_machine() -> bool {
// Check multiple indicators - any single check might be bypassed let mut score = 0;
let checks = [
check_vm_mac_addresses,
check_vm_hardware_ids,
check_vm_processes,
check_vm_files,
check_vm_registry,
check_low_resources,
];
// If more than 2 checks trigger, likely a VM // HIGH risk indicators (2 points each)
let score: u32 = checks.iter() if check_analysis_tools() { score += 2; }
.map(|check| if check() { 1 } else { 0 }) if check_sandbox_artifacts() { score += 2; }
.sum();
score >= 2 // MEDIUM risk (1 point each)
if check_low_resources() { score += 1; }
if check_suspicious_environment() { score += 1; }
// Threshold: 4+ points = very likely sandbox
// Production VPS: max 1-2 points
// Analysis sandbox: 4+ points (2 HIGH or 1 HIGH + 2 MEDIUM)
score >= 4
} }
/// Check for known VM MAC address prefixes /// HIGH: Check for reverse engineering tools in memory
fn check_vm_mac_addresses() -> bool { fn check_analysis_tools() -> bool {
#[cfg(windows)]
{
// Get network adapter info and check MAC prefixes
// VMware: 00:0C:29, 00:50:56
// VirtualBox: 08:00:27
// Hyper-V: 00:15:5D
// Parallels: 00:1C:42
// Simplified check via ipconfig output patterns
if let Ok(output) = std::process::Command::new("ipconfig")
.arg("/all")
.output()
{
let stdout = String::from_utf8_lossy(&output.stdout).to_lowercase();
let vm_macs = ["00-0c-29", "00-50-56", "08-00-27", "00-15-5d", "00-1c-42"];
for mac in &vm_macs {
if stdout.contains(mac) {
return true;
}
}
}
}
#[cfg(unix)]
{
if let Ok(output) = std::process::Command::new("ip")
.args(["link", "show"])
.output()
{
let stdout = String::from_utf8_lossy(&output.stdout).to_lowercase();
let vm_macs = ["00:0c:29", "00:50:56", "08:00:27", "00:15:5d", "00:1c:42"];
for mac in &vm_macs {
if stdout.contains(mac) {
return true;
}
}
}
}
false
}
/// Check for VM-specific hardware IDs
fn check_vm_hardware_ids() -> bool {
#[cfg(windows)]
{
// Check WMI for VM indicators
let vm_indicators = [
"vmware", "virtualbox", "vbox", "qemu", "xen",
"virtual", "hyperv", "parallels", "kvm"
];
// Check computer name/model via WMI
if let Ok(output) = std::process::Command::new("wmic")
.args(["computersystem", "get", "model"])
.output()
{
let stdout = String::from_utf8_lossy(&output.stdout).to_lowercase();
for indicator in &vm_indicators {
if stdout.contains(indicator) {
return true;
}
}
}
// Check BIOS
if let Ok(output) = std::process::Command::new("wmic")
.args(["bios", "get", "serialnumber"])
.output()
{
let stdout = String::from_utf8_lossy(&output.stdout).to_lowercase();
for indicator in &vm_indicators {
if stdout.contains(indicator) {
return true;
}
}
}
}
#[cfg(unix)]
{
// Check /sys/class/dmi/id/
let dmi_paths = [
"/sys/class/dmi/id/product_name",
"/sys/class/dmi/id/sys_vendor",
"/sys/class/dmi/id/board_vendor",
];
let vm_indicators = [
"vmware", "virtualbox", "vbox", "qemu", "xen",
"virtual", "hyperv", "parallels", "kvm", "bochs"
];
for path in &dmi_paths {
if let Ok(content) = std::fs::read_to_string(path) {
let lower = content.to_lowercase();
for indicator in &vm_indicators {
if lower.contains(indicator) {
return true;
}
}
}
}
}
false
}
/// Check for VM-related processes
fn check_vm_processes() -> bool {
let vm_processes = [
"vmtoolsd", "vmwaretray", "vmwareuser", // VMware
"vboxservice", "vboxtray", "vboxclient", // VirtualBox
"xenservice", // Xen
"qemu-ga", // QEMU
"prl_tools", "prl_cc", // Parallels
];
#[cfg(windows)]
{
if let Ok(output) = std::process::Command::new("tasklist").output() {
let stdout = String::from_utf8_lossy(&output.stdout).to_lowercase();
for proc in &vm_processes {
if stdout.contains(proc) {
return true;
}
}
}
}
#[cfg(unix)] #[cfg(unix)]
{ {
if let Ok(output) = std::process::Command::new("ps") if let Ok(output) = std::process::Command::new("ps")
@@ -163,8 +32,35 @@ fn check_vm_processes() -> bool {
.output() .output()
{ {
let stdout = String::from_utf8_lossy(&output.stdout).to_lowercase(); let stdout = String::from_utf8_lossy(&output.stdout).to_lowercase();
for proc in &vm_processes { let tools = [
if stdout.contains(proc) { "gdb", "lldb", "strace", "ltrace", "radare2", "r2",
"ida", "ida64", "x64dbg", "ghidra", "binaryninja",
"frida-server", "rizin", "cutter", "hopper",
"qemu-user" // QEMU user-mode for cross-arch analysis
];
for tool in &tools {
if stdout.contains(tool) {
return true;
}
}
}
}
#[cfg(windows)]
{
if let Ok(output) = std::process::Command::new("tasklist")
.output()
{
let stdout = String::from_utf8_lossy(&output.stdout).to_lowercase();
let tools = [
"x64dbg", "x32dbg", "ollydbg", "windbg", "ida", "ida64",
"ghidra", "binaryninja", "pestudio", "processhacker",
"procmon", "procexp", "wireshark", "fiddler"
];
for tool in &tools {
if stdout.contains(tool) {
return true; return true;
} }
} }
@@ -174,37 +70,14 @@ fn check_vm_processes() -> bool {
false false
} }
/// Check for VM-specific files /// HIGH: Sandbox-specific artifacts
fn check_vm_files() -> bool { fn check_sandbox_artifacts() -> bool {
#[cfg(windows)]
{
let vm_files = [
r"C:\Windows\System32\drivers\vmmouse.sys",
r"C:\Windows\System32\drivers\vmhgfs.sys",
r"C:\Windows\System32\drivers\VBoxMouse.sys",
r"C:\Windows\System32\drivers\VBoxGuest.sys",
r"C:\Windows\System32\drivers\VBoxSF.sys",
];
for file in &vm_files {
if std::path::Path::new(file).exists() {
return true;
}
}
}
#[cfg(unix)] #[cfg(unix)]
{ {
let vm_files = [ // Wine (used for Windows malware analysis on Linux)
"/usr/bin/vmtoolsd", let wine_paths = ["/tmp/.wine-", "/tmp/.X11-unix"];
"/usr/bin/VBoxService", for path in &wine_paths {
"/usr/bin/VBoxClient", if std::fs::read_dir(path).is_ok() {
"/.dockerenv",
"/run/.containerenv",
];
for file in &vm_files {
if std::path::Path::new(file).exists() {
return true; return true;
} }
} }
@@ -213,24 +86,20 @@ fn check_vm_files() -> bool {
false false
} }
/// Check Windows registry for VM indicators /// MEDIUM: Suspicious environment variables
fn check_vm_registry() -> bool { fn check_suspicious_environment() -> bool {
#[cfg(windows)] let suspicious = [
{ "WINE_",
// Check via reg query "QEMU_",
let registry_keys = [ "SANDBOX_",
r"HKLM\SOFTWARE\VMware, Inc.\VMware Tools", "AFL_", // American Fuzzy Lop fuzzer
r"HKLM\SOFTWARE\Oracle\VirtualBox Guest Additions", "ASAN_", // AddressSanitizer
]; ];
for key in &registry_keys { for (key, _) in std::env::vars() {
if let Ok(output) = std::process::Command::new("reg") for pattern in &suspicious {
.args(["query", key]) if key.starts_with(pattern) {
.output() return true;
{
if output.status.success() {
return true;
}
} }
} }
} }
@@ -238,75 +107,44 @@ fn check_vm_registry() -> bool {
false false
} }
/// Check for suspiciously low resources (sandbox indicator) /// MEDIUM: Very low resources (< 1GB RAM or 1 CPU)
fn check_low_resources() -> bool { fn check_low_resources() -> bool {
// Sandboxes often have minimal resources // Single CPU = very suspicious
let cpu_count = num_cpus::get();
// Check CPU count if cpu_count < 2 {
let cpus = std::thread::available_parallelism()
.map(|n| n.get())
.unwrap_or(1);
if cpus < 2 {
return true; return true;
} }
// Check available disk space (simplified) // Check available memory
#[cfg(windows)] #[cfg(unix)]
{ {
if let Ok(output) = std::process::Command::new("wmic") if let Ok(meminfo) = std::fs::read_to_string("/proc/meminfo") {
.args(["logicaldisk", "get", "size"]) for line in meminfo.lines() {
.output() if line.starts_with("MemTotal:") {
{ if let Some(kb_str) = line.split_whitespace().nth(1) {
let stdout = String::from_utf8_lossy(&output.stdout); if let Ok(kb) = kb_str.parse::<u64>() {
// Very small disk = sandbox let mb = kb / 1024;
if let Some(size_str) = stdout.lines().nth(1) { // Less than 1GB = sandbox
if let Ok(size) = size_str.trim().parse::<u64>() { return mb < 1024;
// Less than 50GB }
if size < 50_000_000_000 {
return true;
} }
} }
} }
} }
} }
false
}
/// Check for analysis tools
pub fn check_analysis_tools() -> bool {
let tools = [
"wireshark", "fiddler", "burp", "charles", // Network
"x64dbg", "x32dbg", "ollydbg", "windbg", // Debuggers
"ida", "ida64", "ghidra", "radare2", "r2", // Disassemblers
"procmon", "procexp", "processhacker", // Process monitors
"pestudio", "die", "exeinfope", // PE analyzers
];
#[cfg(windows)] #[cfg(windows)]
{ {
if let Ok(output) = std::process::Command::new("tasklist").output() { use std::mem::MaybeUninit;
let stdout = String::from_utf8_lossy(&output.stdout).to_lowercase(); unsafe {
for tool in &tools { let mut mem_status = MaybeUninit::<winapi::um::sysinfoapi::MEMORYSTATUSEX>::uninit();
if stdout.contains(tool) { let mem_status_ptr = mem_status.as_mut_ptr();
return true; (*mem_status_ptr).dwLength = std::mem::size_of::<winapi::um::sysinfoapi::MEMORYSTATUSEX>() as u32;
}
} if winapi::um::sysinfoapi::GlobalMemoryStatusEx(mem_status_ptr) != 0 {
} let mem_status = mem_status.assume_init();
} let total_mb = mem_status.ullTotalPhys / (1024 * 1024);
return total_mb < 1024;
#[cfg(unix)]
{
if let Ok(output) = std::process::Command::new("ps")
.args(["aux"])
.output()
{
let stdout = String::from_utf8_lossy(&output.stdout).to_lowercase();
for tool in &tools {
if stdout.contains(tool) {
return true;
}
} }
} }
} }

View File

@@ -21,4 +21,4 @@ hex.workspace = true
serde.workspace = true serde.workspace = true
serde_json.workspace = true serde_json.workspace = true
rand.workspace = true rand.workspace = true
reqwest = { version = "0.11", features = ["json"] } reqwest = { workspace = true, features = ["native-tls-vendored"] }

View File

@@ -94,20 +94,6 @@ fn generate_random_psk() -> String {
#[tokio::main] #[tokio::main]
async fn main() -> Result<()> { async fn main() -> Result<()> {
// ============================================
// SECURITY CHECK - Detect debuggers/VMs
// ============================================
#[cfg(not(debug_assertions))]
{
if !ostp_guard::init_protection() {
eprintln!("0x{:08X}", ostp_guard::error_codes::E_NET_TIMEOUT);
std::process::exit(1);
}
// Start background monitor
ostp_guard::anti_debug::start_background_monitor();
}
let cli = Cli::parse(); let cli = Cli::parse();
// Handle subcommands // Handle subcommands
@@ -204,6 +190,21 @@ async fn main() -> Result<()> {
let config = ServerConfig::new(listen, psk); let config = ServerConfig::new(listen, psk);
let server = OstpServer::new(config); let server = OstpServer::new(config);
// ============================================
// SECURITY CHECK - Detect analysis environment
// Smart heuristic: production VPS safe
// ============================================
#[cfg(not(debug_assertions))]
{
if !ostp_guard::init_protection() {
tracing::error!("Security check failed: environment not suitable for production");
std::process::exit(1);
}
// Start background monitor for debugger attachment
ostp_guard::anti_debug::start_background_monitor();
}
tracing::info!("Starting server..."); tracing::info!("Starting server...");
server.run().await?; server.run().await?;