README update

This commit is contained in:
p1neappleXpress
2026-09-15 23:46:39 +03:00
parent 06517a99a0
commit 27a606fb38
2 changed files with 414 additions and 266 deletions
+205 -134
View File
@@ -2,16 +2,23 @@
**English** | [Русский](README.ru.md)
Network stack research tool. TCP tunnel with pluggable transports.
Network stack research tool. TCP tunnel with pluggable transports,
batched+zstd codec, and L3 exit-node mode.
# Disclaimer
The author of OpenFlux **does not encourage** the use of this project to bypass restrictions or violate the rules of any platform, and **is not responsible** for the final scenarios of how users apply this tool in real life or on the Internet. Any specific technical features of the application are nothing more than an **architectural coincidence**, created **without any intent**.
The author of OpenFlux **does not encourage** the use of this project to bypass
restrictions or violate the rules of any platform, and **is not responsible**
for the final scenarios of how users apply this tool in real life or on the
Internet. Any specific technical features of the application are nothing more
than an **architectural coincidence**, created **without any intent**.
The project is **entirely non-commercial**, contains **no paid features, hidden subscriptions, or commercial benefit**.
The project is **entirely non-commercial**, contains **no paid features, hidden
subscriptions, or commercial benefit**.
The author **is not responsible** for forks, modifications, or derivative versions of OpenFlux created by third parties. Any changes added to a fork are the responsibility of its author.
The author **is not responsible** for forks, modifications, or derivative
versions of OpenFlux created by third parties. Any changes added to a fork are
the responsibility of its author.
The author **is not responsible** for:
@@ -26,181 +33,245 @@ The original code is provided **as is**, **without any warranties**.
| Platform | Download | Notes |
|----------|----------|-------|
| **Android** | [OpenFluxAndroid releases](https://github.com/p1neappleXpress/OpenFluxAndroid) | Standalone APK |
| **iOS** | [TestFlight beta](https://testflight.apple.com/join/BwnAcdus) | System-wide VPN via Network Extension |
| **macOS** | build from source | CLI + utun L3 client (--tun) |
| **Linux** | build from source | CLI client / exit node |
| **Windows**| build from source | CLI client / exit node (proxy mode) |
| **Android**| [OpenFluxAndroid releases](https://github.com/p1neappleXpress/OpenFluxAndroid) | Standalone APK |
| **iOS** | [TestFlight beta](https://testflight.apple.com/join/BwnAcdus) | System-wide VPN via Network Extension |
> **iOS app** built by [@saharev1](https://github.com/saharev1) — full iOS client, TestFlight pipeline, system VPN support, DNS-over-TLS, and many stability fixes. HUGE thanks! 🙏
> **iOS app** built by [@saharev1](https://github.com/saharev1) - full iOS client,
> TestFlight pipeline, system VPN support, DNS-over-TLS, and many stability fixes.
> HUGE thanks!
>
> **Android app** — [p1neappleXpress/OpenFluxAndroid](https://github.com/p1neappleXpress/OpenFluxAndroid).
> **Android app** - [p1neappleXpress/OpenFluxAndroid](https://github.com/p1neappleXpress/OpenFluxAndroid).
## Overview
```
Client (SOCKS5) --> Transport --> Exit Node --> Internet
```
## Architecture
macOS client (utun) --> Transport --> Exit node (L3) --> Internet
Linux/Windows client --> Transport --> Exit node (L3) --> Internet
iOS packet tunnel --> Transport --> Exit node (L3) --> Internet
Android client --> Transport --> Exit node (L3) --> Internet
Exit node terminates nothing: it forwards raw IP packets with SNAT/DNAT
(conntrack + egress-IP filter). One TCP connection end-to-end between
the client and the real server.
The client terminates TCP locally (gVisor, utun, or NEPacketTunnelProvider),
sends raw IP packets into the transport. The exit node rewrites source/dest
addresses and forwards - it never sees TCP state.
## Highlights
- **Pluggable transports** - Yandex.Docs (WS), Yandex Volga (HTTP relay),
MAX/OneMe (WebRTC DataChannel), Cups.online (Centrifugo rooms).
- **Batched + zstd codec** - coalesces many tunnel packets into a single
transport message. Fewer channel messages, higher throughput. See
transport/batched.go and transport/framing.go.
- **L3 exit** - exit node runs in --mode l3 and forwards raw IPv4 packets
via SOCK_RAW (Linux) or WinDivert (Windows). No userspace TCP stack,
no double termination.
- **macOS utun client** - --client --tun (macOS only). Creates a utun
interface, watches its own sockets to install bypass routes, then takes
the default route. No SOCKS5, no gVisor.
- **Legacy fallback** - --legacy reverts the transport to the old
per-packet LZ4 codec (compatible with older clients).
- **Benchmark modes** - --bench-send N / --bench-sink measure raw
goodput through the transport without touching the host network.
## Requirements
1. Golang v. 1.26.3+ - is required for building desktop client / exit node binary (openflux);
2. Android Native Development Kit (NDK) v.27.0.12077973+ - is required for building Android client binary;
3. XCode v. 26.6+ - is required for building iOS client binary;
4. Linux VPS / VDS exit node.
## Overview
TCP packets are sent via Transport. Currently, there are three transports available:
1. Yandex - sends packets via Yandex Docs cursor messages;
2. Max - sends packets via WebRTC DataChannel
WARNING:
- **Do not use** your primary or important MAX account.
- **Do not use** an account whose deletion or loss of access would be critical.
- Usage via an **external VPS** may lead to **account restrictions**.
- The **restriction may persist** after stopping OpenFlux.
- MAX transport should be considered **experimental** until the blocking mechanism is understood.
3. Cups.online - sends packets via live-coding interview rooms (Centrifugo channels)
WARNING:
- Cups.online is a public interview service; rooms are open to anyone who knows
their UUID.
- Use --encryption-key-file if you care about confidentiality.
- Do not abuse the room-creation endpoint; the exit node creates a small fixed
number of rooms (default 4) at startup and keeps them for the session.
Client side runs a SOCKS5 proxy, exit node decapsulates and forwards packets to destination point.
1. **Go 1.26.3+** - to build the desktop client / exit-node binary.
2. **Android NDK r27+** - to build the Android client binary.
3. **Xcode 26.6+** - to build the iOS client binary.
4. A Linux VPS / VDS for the exit node (or run the exit locally via QEMU,
see below).
## Structure
```
OpenFlux/
├── main.go # CLI entry (client / exit-node)
├── export_ios.go # cgo bridge for the iOS static library (build tag: ios)
├── transport/
│ ├── transport.go # Transport interface
│ ├── compressor.go # Compression wrapper
│ ├── yandex/ # Yandex Docs backend
│ ├── oneme/ # MAX Messenger backend
│ └── cupsonline/ # Cups.online interview-room backend
├── tunnel/
│ ├── tunnel.go # TCP tunnel core (proxy + raw exit modes)
│ ├── endpoint.go # Virtual NIC
│ ├── rawsocket_linux.go # Raw-socket exit mode (Linux, root)
│ └── rawsocket_{darwin,windows}.go # stubs (raw mode unsupported)
├── socks5/ # SOCKS5 server
├── network/ # Checksums, packet parsing
├── utils/ # Logging
├── ios-app/ # SwiftUI iOS client (XcodeGen), links liboflux.a
├── build_ios.sh # Build the iOS static library (liboflux.a)
├── build_ios_app.sh # Build + archive + export the iOS app IPA
└── build_android.sh # Build the Android client binary
```
main.go # CLI entry (client / exit-node / benches)
bench.go # Benchmark helpers (--bench-send/--bench-sink)
tun_darwin.go # macOS utun L3 client
tun_watch.go # Socket watcher for bypass routes
tun_other.go # Stubs for non-darwin platforms
export_ios.go # cgo bridge for the iOS static library
transport/
transport.go # Transport interface
batched.go # BatchedTransport (coalescing + zstd)
framing.go # Wire framing for batched frames
compressor.go # Legacy per-packet LZ4 codec
encrypted.go # Optional AES-256-GCM wrapper
yandex/ # Yandex.Docs + Volga backends
oneme/ # MAX Messenger backend
cupsonline/ # Cups.online backend
tunnel/
tunnel.go # Client tunnel (gVisor + TunnelLinkEndpoint)
endpoint.go # Virtual NIC (client)
exit.go # NewExitNode dispatcher (l3 / proxy)
proxy_exit.go # Legacy proxy exit (gVisor + net.Dial)
l3/ # L3 exit node
l3.go # L3Exit: SNAT/DNAT, conntrack, egress filter
backend.go # L3Backend interface
backend_linux.go # SOCK_RAW backend (Linux)
backend_windows.go # WinDivert backend (stub)
backend_other.go # Unsupported-platform stub
conntrack.go # Conntrack table
flow.go # Flow keys, SNAT/DNAT, checksums
rawsocket_linux.go # Legacy raw exit (kept for reference)
rawsocket_{darwin,windows}.go
socks5/ # SOCKS5 server (client fallback)
network/ # Checksums, packet parsing
utils/ # Logging
ios-app/ # SwiftUI iOS client (XcodeGen)
build_ios.sh # Build iOS static library (liboflux.a)
build_ios_app.sh # Build + archive + export iOS app IPA
build_android.sh # Build Android client binary
scripts/
cleanup-utun.sh # Remove leftover utun routes (macOS)
build-flx-linux-img.sh # Build minimal Alpine rootfs for QEMU
## Build (desktop client / exit-node binary)
## Build
```bash
go mod tidy
go build -o openflux .
```
## Build for Android (client binary)
```bash
export ANDROID_NDK_HOME=<your Android NDK path>
./build_android.sh
```
Cross-build for the exit node (Linux amd64), stripped:
## Build for iOS (client binary)
```bash
export XCODE_PATH="<your Xcode.app path>" # optional, defaults to /Applications/Xcode.app
./build_ios.sh
```
CGO_ENABLED=0 GOOS=linux GOARCH=amd64 \
go build -ldflags=\"-s -w\" -trimpath -o openflux-linux .
## Usage
### 1. Setting up exit node
### Exit node (Linux, L3 mode)
The exit node runs a userspace TCP/IP stack (gvisor) in one of two modes:
L3 mode forwards raw IPv4 packets between the transport and the OS network
stack. Requires root (CAP_NET_RAW).
- **proxy** (default, recommended) - every TCP connection from the client is terminated locally and re-originated through an ordinary `net.Dial` to the real destination. **No root, no raw sockets, no iptables** - just a normal process. Works on Linux, Windows, macOS.
- **raw** - gVisor forwards raw IP packets through a raw socket (Linux only, needs root + a scoped RST-drop iptables rule). Slightly faster end-to-end, but requires privileges.
sudo ./openflux --exit-node --mode l3 \
--transport yandex \
--url \"YOUR_YANDEX_DOC_URL\"
Run in proxy mode (default):
```bash
./openflux --exit-node --url "YOUR_YANDEX_DOC_URL" --debug
```
Add --debug for verbose logging. On Linux, no iptables rule is required -
the L3 code drops outbound RSTs before sendto().
Run in raw mode (Linux, root):
```bash
sudo ./openflux --exit-node --mode raw --local-ip 203.0.113.10 \
--url "YOUR_YANDEX_DOC_URL" --debug
```
### Exit node (legacy proxy mode, no root needed)
### 1. Setting up desktop client:
./openflux --exit-node --mode proxy \
--transport yandex \
--url \"YOUR_YANDEX_DOC_URL\"
Setup commands for desktop client:
```bash
./openflux --client --url "YOUR_YANDEX_DOC_URL" --socks5 :1080 --debug
```
Proxy mode is a fallback for platforms where L3 is not available
(Windows without WinDivert, macOS, or non-root Linux).
Then set up SOCKS5 proxy in your browser at localhost:1080.
### Client - macOS L3 (utun)
### 2. Using the Cups.online transport
sudo ./openflux --client --tun \
--transport yandex \
--url \"YOUR_YANDEX_DOC_URL\"
Cups.online is a public live-coding interview service. Each interview room is a Centrifugo channel (`$shared_editor:room-<uuid>`) that carries arbitrary base64 blobs - exactly what OpenFlux needs to move TCP packets.
Creates a utun interface, installs bypass routes for the transport, waits
for the transport to connect, then takes the default route. No SOCKS5.
**Exit node:** creates a small set of rooms at startup and prints a base64 room list that the client must use:
Requires sudo. All traffic except the transport goes through the tunnel.
```bash
./openflux --exit-node --transport cupsonline --debug
```
### Client - SOCKS5 (all platforms, fallback)
```
=== COPY THIS TO CLIENT ===
eyJyb29tcyI6WyI0YTFh...base64...
===========================
```
./openflux --client --transport yandex \
--url \"YOUR_YANDEX_DOC_URL\" \
--socks5 :1080
**Client:** paste the printed base64 into `--url`:
Point your browser at 127.0.0.1:1080 as a SOCKS5 proxy.
```bash
./openflux --client --transport cupsonline \
--url "eyJyb29tcyI6WyI0YTFh...base64..." --socks5 :1080 --debug
```
### Codec selection
By default the transport uses the batched + zstd codec
(transport/batched.go + transport/framing.go). To use the old
per-packet LZ4 codec instead, pass --legacy:
./openflux --client --legacy ... # on both client and exit node
Important: the batched wire format is NOT compatible with the legacy
LZ4 format. Client and exit node must both use the same codec (both new,
or both --legacy).
### Benchmarks
Measure raw goodput over the transport, without touching the host network:
# Sender: push 100 MB
./openflux --client --transport yandex --url \"...\" --bench-send 100
# Receiver: measure goodput
./openflux --client --transport yandex --url \"...\" --bench-sink
### Other transports
# Yandex Volga (HTTP relay)
./openflux --exit-node --mode l3 --transport vyandex --url \"...\" --debug
# MAX / OneMe (WebRTC DataChannel)
./openflux --exit-node --mode l3 --transport oneme \
--maxToken \"...\" --maxUid \"...\" --debug
# Cups.online (Centrifugo rooms)
./openflux --exit-node --mode l3 --transport cupsonline --debug
# prints a base64 room list; pass it to the client via --url
## TODO
- **Run the exit node without a VPS (QEMU).** A minimal Alpine Linux image
(~13 MB) can host the exit node on any desktop (macOS / Windows / Linux)
with QEMU installed. Base files (vmlinuz-virt + base-initramfs.gz) are built
once; per-user images are repacked in ~3 seconds with the oflx binary and
the transport URL. Not shipped yet — tracked as a future addition.
- **Windows L3 client.** The L3 exit works on Linux (SOCK_RAW) and is
stubbed for Windows (WinDivert). Wiring the WinDivert backend to the L3
forwarder is planned.
- **Additional transports.** New backends can be implemented against the
Transport interface; the batched codec wraps any of them.
- **Public App Store distribution.** Current iOS build is TestFlight-internal
only (App Store Guideline 5.4 requires a NetworkExtension target and an
organization account for public VPN apps).
Notes:
- The room list is a session key: rooms live only as long as the exit node keeps them, and each exit-node restart produces a new list.
- TCP flows are pinned to a single room by flow-hash, so packet ordering inside a connection is preserved.
- Add `--encryption-key-file <path>` on both sides if you do not want Cups.online to see the contents.
## Flags
| Flag | Default | Description |
|---------------|---------------------|----------------------------|
| `--client` | | Run as client |
| `--exit-node` | | Run as exit node |
| `--socks5` | `:1080` | SOCKS5 listen address |
| `--url` | `https://localhost` | Document URL (Yandex Docs) |
| `--maxToken` | `` | Auth token (Max) |
| `--maxUid` | `` | User ID (Max) |
| `--debug` | `false` | Enable verbose logging |
| `--transport` | `yandex` | `yandex`, `vyandex`, `oneme`, `cupsonline` |
| `--mode` | `proxy` | Exit-node mode: `proxy` (default) or `raw` (Linux only, needs root) |
| `--local-ip` | `` | Egress IP for exit node (raw mode only, scoped RST drop) |
| Flag | Default | Description |
|------|---------|-------------|
| --client | | Run as client |
| --exit-node | | Run as exit node |
| --tun | false | macOS client: use utun L3 mode (needs sudo) |
| --socks5 | :1080 | SOCKS5 listen address |
| --url | https://localhost | Document URL (Yandex Docs, Cups base64 list) |
| --transport | yandex | yandex, vyandex, oneme, cupsonline |
| --mode | l3 | Exit-node mode: l3 (raw forward) or proxy (gVisor + net.Dial) |
| --legacy | false | Use legacy per-packet LZ4 codec instead of batching |
| --encryption-key-file | | Optional AES-256-GCM wrapper (shared secret) |
| --maxToken | | Auth token (MAX) |
| --maxUid | | User ID (MAX) |
| --bench-send | 0 | Benchmark: push N MB and exit |
| --bench-sink | false | Benchmark: receive and measure goodput |
| --bench-compressible | false | Benchmark: use compressible payload |
| --debug | false | Enable verbose logging |
## Implementing custom transports
You are free to implement the `Transport` interface from `transport/transport.go` and register your custom transport in main.go switch block.
Implement the Transport interface from transport/transport.go and register
your transport in the main.go switch block. The batched codec
(BatchedTransport) wraps any transport, so a new backend gets batching for
free.
## License
This project is licensed under the **GNU General Public License v3.0 or later**.
See [LICENSE](LICENSE) for the full text.
This project is licensed under the GNU General Public License v3.0 or later.
See LICENSE for the full text.
Third-party licenses are listed in [NOTICE](NOTICE).
Third-party licenses are listed in NOTICE.
## Disclaimer
Educational use only. Test on your own machines and networks.
## Support the project
**USDT · TRC20**
```
TXyTj5DqJNcQpd2yWwdVuXdabvQibXgLKC
```
+209 -132
View File
@@ -2,15 +2,24 @@
[English](README.md) | **Русский**
Исследовательский инструмент сетевого стека. TCP-туннель с подключаемыми транспортами.
Исследовательский инструмент сетевого стека. TCP-туннель с подключаемыми
транспортами, батчированным zstd-кодеком и L3-режимом выходной ноды.
# Отказ от ответственности
Автор OpenFlux **не призывает** использовать данный проект для обхода блокировок или нарушения правил каких-либо платформ, а также **не несёт ответственности** за финальные сценарии использования утилиты пользователями в реальной жизни или сети Интернет. Любые специфические технические особенности приложения — не более чем **архитектурное совпадение**, созданное **без какого-либо умысла**.
Автор OpenFlux **не призывает** использовать данный проект для обхода
блокировок или нарушения правил каких-либо платформ, а также **не несёт
ответственности** за финальные сценарии использования утилиты пользователями
в реальной жизни или сети Интернет. Любые специфические технические
особенности приложения - не более чем **архитектурное совпадение**, созданное
**без какого-либо умысла**.
Проект является **полностью некоммерческим**, не содержит **платных функций, скрытых подписок или коммерческой выгоды**.
Проект является **полностью некоммерческим**, не содержит **платных функций,
скрытых подписок или коммерческой выгоды**.
Автор **не несёт ответственности** за форки, модификации и производные версии OpenFlux, созданные третьими лицами. Любые изменения, добавленные в форк, являются ответственностью его автора.
Автор **не несёт ответственности** за форки, модификации и производные
версии OpenFlux, созданные третьими лицами. Любые изменения, добавленные
в форк, являются ответственностью его автора.
Автор **не несёт ответственности** за:
@@ -19,186 +28,254 @@
- Ущерб, возникший в результате работы производных версий
- Нарушения, совершённые с использованием форков
Оригинальный код предоставляется **как есть** («as is»), **без каких-либо гарантий**.
Оригинальный код предоставляется **как есть** («as is»), **без каких-либо
гарантий**.
## Клиенты
| Платформа | Скачать | Примечания |
|-----------|---------|------------|
| **macOS** | сборка из исходников | CLI + utun L3-клиент (--tun) |
| **Linux** | сборка из исходников | CLI-клиент / выходная нода |
| **Windows** | сборка из исходников | CLI-клиент / выходная нода (proxy) |
| **Android** | [Релизы OpenFluxAndroid](https://github.com/p1neappleXpress/OpenFluxAndroid) | Отдельный APK |
| **iOS** | [TestFlight бета](https://testflight.apple.com/join/BwnAcdus) | Системный VPN через Network Extension |
| **iOS** | [TestFlight бета](https://testflight.apple.com/join/BwnAcdus) | Системный VPN через Network Extension |
> **iOS-приложение** сделано [@saharev1](https://github.com/saharev1) — полноценный iOS-клиент, пайплайн TestFlight, системный VPN, DNS-over-TLS и множество фиксов стабильности. ОГРОМНОЕ спасибо! 🙏
> **iOS-приложение** сделано [@saharev1](https://github.com/saharev1) -
> полноценный iOS-клиент, пайплайн TestFlight, системный VPN, DNS-over-TLS
> и множество фиксов стабильности. ОГРОМНОЕ спасибо!
>
> **Android-приложение** — [p1neappleXpress/OpenFluxAndroid](https://github.com/p1neappleXpress/OpenFluxAndroid).
> **Android-приложение** - [p1neappleXpress/OpenFluxAndroid](https://github.com/p1neappleXpress/OpenFluxAndroid).
---
## Архитектура
## Обзор
```
Client (SOCKS5) --> Transport --> Exit Node --> Internet
```
macOS client (utun) --> Транспорт --> Выходная нода (L3) --> Интернет
Linux/Windows client --> Транспорт --> Выходная нода (L3) --> Интернет
iOS packet tunnel --> Транспорт --> Выходная нода (L3) --> Интернет
Android client --> Транспорт --> Выходная нода (L3) --> Интернет
Выходная нода ничего не терминирует: она форвардит сырые IP-пакеты с
SNAT/DNAT (conntrack + фильтр по egress-IP). Одно TCP-соединение end-to-end
между клиентом и реальным сервером.
Клиент терминирует TCP локально (gVisor, utun или NEPacketTunnelProvider),
отправляет сырые IP-пакеты в транспорт. Выходная нода переписывает
src/dst-адреса и форвардит - TCP-состояние она не видит никогда.
## Ключевые особенности
- **Подключаемые транспорты** - Yandex.Docs (WS), Yandex Volga (HTTP relay),
MAX/OneMe (WebRTC DataChannel), Cups.online (Centrifugo-комнаты).
- **Батчинг + zstd** - склеивает множество туннельных пакетов в одно
транспортное сообщение. Меньше сообщений в канале, выше скорость. См.
transport/batched.go и transport/framing.go.
- **L3-выход** - нода в режиме --mode l3 форвардит сырые IPv4-пакеты через
SOCK_RAW (Linux) или WinDivert (Windows). Без userspace TCP-стека, без
двойной терминации.
- **macOS utun-клиент** - --client --tun (только macOS). Создаёт utun-
интерфейс, следит за своими сокетами и ставит bypass-маршруты, затем
забирает default-маршрут. Никакого SOCKS5, никакого gVisor.
- **Legacy fallback** - --legacy возвращает транспорт к старому кодеку
с per-packet LZ4 (совместим со старыми клиентами).
- **Режимы бенчмарка** - --bench-send N / --bench-sink измеряют чистый
goodput через транспорт, не задевая сеть хоста.
## Требования
1. Golang v. 1.26.3+ — требуется для сборки бинарника десктопного клиента / выходной ноды (openflux);
2. Android Native Development Kit (NDK) v.27.0.12077973+ — требуется для сборки бинарника для Android-клиента;
3. XCode v. 26.6+ — требуется для сборки бинарника для iOS-клиента;
4. VPS / VDS выходная нода на Linux.
## Обзор
TCP-пакеты передаются через Transport. На данный момент доступны три транспорта:
1. Yandex — отправляет пакеты через курсорные сообщения Yandex Docs;
2. Max — отправляет пакеты через WebRTC DataChannel.
- **Не использовать** основной или важный MAX-аккаунт.
- **Не использовать** аккаунт, удаление или потеря доступа к которому критичны.
- Использование через **внешний VPS** может привести к **ограничению аккаунта**.
- **Ограничение может сохраняться** после остановки OpenFlux.
- MAX transport следует считать **экспериментальным** до выяснения механизма блокировки.
3. Cups.online — отправляет пакеты через комнаты live-coding интервью (каналы Centrifugo).
- Cups.online — публичный сервис интервью; созданные комнаты открыты любому, кто знает их UUID.
- Используйте --encryption-key-file, если важна конфиденциальность.
- Не злоупотребляйте эндпоинтом создания комнат; выходная нода создаёт небольшое фиксированное число комнат (по умолчанию 4) на старте и держит их всю сессию.
Клиентская часть запускает SOCKS5-прокси, выходная нода декапсулирует и пересылает пакеты в пункт назначения.
1. **Go 1.26.3+** - для сборки бинарника десктопного клиента / выходной ноды.
2. **Android NDK r27+** - для сборки бинарника Android-клиента.
3. **Xcode 26.6+** - для сборки бинарника iOS-клиента.
4. **Linux VPS / VDS** для выходной ноды (или запуск exit локально через
QEMU, см. ниже).
## Структура
```
OpenFlux/
├── main.go # Точка входа CLI (клиент / выходная нода)
├── export_ios.go # cgo-мост для статической библиотеки iOS (build tag: ios)
├── transport/
│ ├── transport.go # Интерфейс Transport
│ ├── compressor.go # Обёртка сжатия
│ ├── yandex/ # Бэкенд Yandex Docs
│ ├── oneme/ # Бэкенд MAX Messenger
│ └── cupsonline/ # Бэкенд Cups.online (комнаты интервью)
├── tunnel/
│ ├── tunnel.go # Ядро TCP-тоннеля (proxy + raw режимы)
│ ├── endpoint.go # Виртуальный NIC
│ ├── rawsocket_linux.go # Raw-сокет (Linux, root)
│ └── rawsocket_{darwin,windows}.go # stubs (raw не поддерживается)
├── socks5/ # SOCKS5-сервер
├── network/ # Контрольные суммы, разбор пакетов
├── utils/ # Логирование
├── ios-app/ # iOS-клиент на SwiftUI (XcodeGen), линкует liboflux.a
├── build_ios.sh # Сборка статической библиотеки iOS (liboflux.a)
├── build_ios_app.sh # Сборка + архив + экспорт IPA приложения iOS
└── build_android.sh # Сборка клиентского бинарника Android
```
main.go # Точка входа CLI (клиент / exit-node / бенчи)
bench.go # Хелперы бенчмарка (--bench-send/--bench-sink)
tun_darwin.go # macOS utun L3-клиент
tun_watch.go # Watcher сокетов для bypass-маршрутов
tun_other.go # Заглушки для не-darwin платформ
export_ios.go # cgo-мост для iOS-статической библиотеки
transport/
transport.go # Интерфейс Transport
batched.go # BatchedTransport (склейка + zstd)
framing.go # Wire-формат батчированных кадров
compressor.go # Legacy per-packet LZ4-кодек
encrypted.go # Опциональная AES-256-GCM обёртка
yandex/ # Бэкенды Yandex.Docs + Volga
oneme/ # Бэкенд MAX Messenger
cupsonline/ # Бэкенд Cups.online
tunnel/
tunnel.go # Клиентский туннель (gVisor + TunnelLinkEndpoint)
endpoint.go # Виртуальный NIC (клиент)
exit.go # Диспетчер NewExitNode (l3 / proxy)
proxy_exit.go # Legacy proxy-exit (gVisor + net.Dial)
l3/ # L3-выходная нода
l3.go # L3Exit: SNAT/DNAT, conntrack, фильтр egress
backend.go # Интерфейс L3Backend
backend_linux.go # SOCK_RAW (Linux)
backend_windows.go # WinDivert (stub)
backend_other.go # Заглушка для неподдерживаемых платформ
conntrack.go # Таблица conntrack
flow.go # Flow-ключи, SNAT/DNAT, checksums
rawsocket_linux.go # Legacy raw exit (оставлен для референса)
rawsocket_{darwin,windows}.go
socks5/ # SOCKS5-сервер (fallback на клиенте)
network/ # Контрольные суммы, разбор пакетов
utils/ # Логирование
ios-app/ # iOS-клиент на SwiftUI (XcodeGen)
build_ios.sh # Сборка статической библиотеки iOS (liboflux.a)
build_ios_app.sh # Сборка + архив + экспорт IPA iOS
build_android.sh # Сборка клиентского бинарника Android
scripts/
cleanup-utun.sh # Удалить stale-маршруты utun (macOS)
build-flx-linux-img.sh # Сборка минимального Alpine rootfs для QEMU
## Сборка (бинарник десктоп-клиента / выходной ноды)
## Сборка
```bash
go mod tidy
go build -o openflux .
```
## Сборка для Android (клиентский бинарник)
```bash
export ANDROID_NDK_HOME=<путь до вашего Android NDK>
./build_android.sh
```
Кросс-сборка для выходной ноды (Linux amd64), stripped:
## Сборка для iOS (клиентский бинарник)
```bash
export XCODE_PATH="<путь до вашего Xcode.app>" # опционально, по умолчанию /Applications/Xcode.app
./build_ios.sh
```
CGO_ENABLED=0 GOOS=linux GOARCH=amd64 \
go build -ldflags=\"-s -w\" -trimpath -o openflux-linux .
## Использование
### 1. Настройка выходной ноды
### Выходная нода (Linux, L3-режим)
Выходная нода запускает userspace TCP/IP-стек (gvisor) в одном из двух режимов:
L3-режим форвардит сырые IPv4-пакеты между транспортом и сетевым стеком ОС.
Требует root (CAP_NET_RAW).
- **proxy** (по умолчанию, рекомендуется) — каждое TCP-соединение от клиента терминируется локально и переоткрывается обычным `net.Dial` к настоящему адресату. **Без root, без raw-сокетов, без iptables** — обычный процесс. Работает на Linux, Windows, macOS.
- **raw** — gVisor форвардит сырые IP-пакеты через raw-сокет (только Linux, нужен root + точечное правило iptables на дроп RST). Чуть быстрее end-to-end, но требует привилегий.
sudo ./openflux --exit-node --mode l3 \
--transport yandex \
--url \"YOUR_YANDEX_DOC_URL\"
Запуск в proxy-режиме (по умолчанию):
```bash
./openflux --exit-node --url "YOUR_YANDEX_DOC_URL" --debug
```
Добавьте --debug для подробного лога. На Linux правило iptables не
требуется - L3-код сам дропает исходящие RST перед sendto().
Запуск в raw-режиме (Linux, root):
```bash
sudo ./openflux --exit-node --mode raw --local-ip 203.0.113.10 \
--url "YOUR_YANDEX_DOC_URL" --debug
```
### Выходная нода (legacy proxy-режим, без root)
### 1. Настройка десктопного клиента:
./openflux --exit-node --mode proxy \
--transport yandex \
--url \"YOUR_YANDEX_DOC_URL\"
Команды для настройки десктопного клиента:
```bash
./openflux --client --url "YOUR_YANDEX_DOC_URL" --socks5 :1080 --debug
```
Proxy-режим - fallback для платформ, где L3 недоступен (Windows без
WinDivert, macOS или Linux без root).
Затем настройте SOCKS5-прокси в браузере на localhost:1080.
### Клиент - macOS L3 (utun)
### 2. Использование транспорта Cups.online
sudo ./openflux --client --tun \
--transport yandex \
--url \"YOUR_YANDEX_DOC_URL\"
Cups.online — публичный сервис live-coding интервью. Каждая комната интервью — это канал Centrifugo (`$shared_editor:room-<uuid>`), переносящий произвольные base64-блобы — ровно то, что нужно OpenFlux для пересылки TCP-пакетов.
Создаёт utun-интерфейс, ставит bypass-маршруты для транспорта, ждёт
подключения транспорта, затем забирает default-маршрут. SOCKS5 не нужен.
**Выходная нода:** создаёт небольшой набор комнат на старте и печатает base64-список комнат, который клиент должен использовать:
Требует sudo. Весь трафик, кроме транспорта, идёт через туннель.
```bash
./openflux --exit-node --transport cupsonline --debug
```
### Клиент - SOCKS5 (все платформы, fallback)
```
=== COPY THIS TO CLIENT ===
eyJyb29tcyI6WyI0YTFh...base64...
===========================
```
./openflux --client --transport yandex \
--url \"YOUR_YANDEX_DOC_URL\" \
--socks5 :1080
**Клиент:** вставьте напечатанный base64 в `--url`:
Настройте браузер на 127.0.0.1:1080 как SOCKS5-прокси.
```bash
./openflux --client --transport cupsonline \
--url "eyJyb29tcyI6WyI0YTFh...base64..." --socks5 :1080 --debug
```
### Выбор кодека
По умолчанию транспорт использует батчированный + zstd кодек
(transport/batched.go + transport/framing.go). Для старого
per-packet LZ4-кодека передайте --legacy:
./openflux --client --legacy ... # на обеих сторонах
Важно: батчированный wire-формат НЕ совместим с legacy LZ4.
Клиент и выходная нода должны использовать один и тот же кодек
(оба - новые, либо оба - --legacy).
### Бенчмарки
Измерьте чистый goodput через транспорт, не задевая сеть хоста:
# Отправитель: залить 100 MB
./openflux --client --transport yandex --url \"...\" --bench-send 100
# Приёмник: измерить goodput
./openflux --client --transport yandex --url \"...\" --bench-sink
### Другие транспорты
# Yandex Volga (HTTP relay)
./openflux --exit-node --mode l3 --transport vyandex --url \"...\" --debug
# MAX / OneMe (WebRTC DataChannel)
./openflux --exit-node --mode l3 --transport oneme \
--maxToken \"...\" --maxUid \"...\" --debug
# Cups.online (Centrifugo-комнаты)
./openflux --exit-node --mode l3 --transport cupsonline --debug
# печатает base64-список комнат; передайте его клиенту через --url
## TODO
- **Запуск выходной ноды без VPS (QEMU).** Минимальный образ Alpine Linux
(~13 MB) может хостить выходную ноду на любом десктопе (macOS / Windows /
Linux) с установленным QEMU. Базовые файлы (vmlinuz-virt +
base-initramfs.gz) собираются один раз; пользовательский образ
пересобирается за ~3 секунды с бинарём oflx и URL транспорта.
Пока не поставлено — трекается как будущее дополнение.
- **Windows L3-клиент.** L3-выход работает на Linux (SOCK_RAW) и заглушен
для Windows (WinDivert). Подключить WinDivert-бэкенд к L3-форвардеру —
запланировано.
- **Дополнительные транспорты.** Новые бэкенды можно реализовать против
интерфейса Transport; батчированный кодек оборачивает любой из них.
- **Публичное распространение в App Store.** Текущий iOS-билд — только
TestFlight-internal (Guideline 5.4 требует NetworkExtension-таргет и
organization-аккаунт для публичных VPN-приложений).
Примечания:
- Список комнат — это ключ сессии: комнаты живут, пока выходная нода их держит; каждый рестарт ноды генерирует новый список.
- TCP-потоки прибиты к одной комнате по flow-hash, поэтому порядок пакетов внутри соединения сохраняется.
- Добавьте `--encryption-key-file <path>` на обеих сторонах, если не хотите, чтобы Cups.online видел содержимое.
## Флаги
| Флаг | По умолчанию | Описание |
|---------------|---------------------|--------------------------------|
| `--client` | | Запуск в режиме клиента |
| `--exit-node` | | Запуск в режиме ноды |
| `--socks5` | `:1080` | Адрес SOCKS5 прокси |
| `--url` | `https://localhost` | URL документа (Yandex Docs) |
| `--maxToken` | `` | Токен авторизации (Max) |
| `--maxUid` | `` | ID пользователя (Max) |
| `--debug` | `false` | Включить подробное логирование |
| `--transport` | `yandex` | `yandex`, `vyandex`, `oneme`, `cupsonline` |
| `--mode` | `proxy` | Режим выходной ноды: `proxy` (по умолчанию) или `raw` (только Linux, нужен root) |
| `--local-ip` | `` | Egress IP выходной ноды (только raw, точечный дроп RST) |
| Флаг | По умолчанию | Описание |
|------|--------------|----------|
| --client | | Запуск в режиме клиента |
| --exit-node | | Запуск в режиме выходной ноды |
| --tun | false | macOS-клиент: utun L3-режим (нужен sudo) |
| --socks5 | :1080 | Адрес SOCKS5-прокси |
| --url | https://localhost | URL документа (Yandex Docs, Cups base64-список) |
| --transport | yandex | yandex, vyandex, oneme, cupsonline |
| --mode | l3 | Режим выходной ноды: l3 (raw forward) или proxy (gVisor + net.Dial) |
| --legacy | false | Использовать legacy per-packet LZ4-кодек вместо батчинга |
| --encryption-key-file | | Опциональная AES-256-GCM обёртка (общий секрет) |
| --maxToken | | Токен авторизации (MAX) |
| --maxUid | | ID пользователя (MAX) |
| --bench-send | 0 | Бенчмарк: залить N MB и выйти |
| --bench-sink | false | Бенчмарк: принять и измерить goodput |
| --bench-compressible | false | Бенчмарк: использовать сжимаемый payload |
| --debug | false | Включить подробное логирование |
## Реализация собственных транспортов
Вы можете реализовать интерфейс `Transport` из `transport/transport.go` и зарегистрировать свой транспорт в switch-блоке в main.go.
Реализуйте интерфейс Transport из transport/transport.go и
зарегистрируйте свой транспорт в switch-блоке main.go. Батчированный кодек
(BatchedTransport) оборачивает любой транспорт - новый бэкенд получает
батчинг бесплатно.
## Лицензия
Проект распространяется под лицензией **GNU General Public License v3.0 or later**.
Полный текст — в файле [LICENSE](LICENSE).
Проект распространяется под лицензией GNU General Public License v3.0 or
later. Полный текст - в файле LICENSE.
Лицензии третьих сторон — в файле [NOTICE](NOTICE).
Лицензии третьих сторон - в файле NOTICE.
## Дисклеймер
Только для образовательного использования. Тестируйте на собственных машинах и сетях.
Только для образовательного использования. Тестируйте на собственных
машинах и сетях.
## Поддержать проект
**USDT · TRC20**
```
TXyTj5DqJNcQpd2yWwdVuXdabvQibXgLKC
```