Compare commits
4 Commits
v1.10.2-st
...
v1.12.0
| Author | SHA1 | Date | |
|---|---|---|---|
| 4b0eee3eb5 | |||
| 7298a36e38 | |||
| 89d0adb27c | |||
| 62f2414c12 |
12
.gitignore
vendored
12
.gitignore
vendored
@@ -3,3 +3,15 @@
|
||||
docs/
|
||||
build.sh
|
||||
*.zip
|
||||
*.lf
|
||||
*.tar.gz
|
||||
tools/binaries/
|
||||
tools/src/
|
||||
tools/apks/
|
||||
phone_*/
|
||||
phone_backup*/
|
||||
*.toml
|
||||
!box/sidecar/*.example.toml
|
||||
|
||||
__pycache__/
|
||||
*.pyc
|
||||
|
||||
@@ -1,18 +1,23 @@
|
||||
# BFR Stealth Mod — v1.10.2-stealth.1
|
||||
# PronBox — v1.12.0
|
||||
|
||||
Разработано в стенах **НИИ «ТехноПрон»**. Magisk `id` остаётся `box_for_root` (апгрейд поверх старого модуля).
|
||||
|
||||
## Renamed
|
||||
- Display name: **PronBox** (больше не VeilBox / «Box for Magisk»)
|
||||
- Author: **команда НИИ «ТехноПрон»**
|
||||
- ZIP: `pronbox-v1.12.0.zip`
|
||||
- Fix: `customize.sh` больше не переименовывает модуль в stock «Box for Magisk»
|
||||
|
||||
## Added
|
||||
- **Stealth layer** (`box.stealth`): iptables port-hide for observer apps without LSPosed
|
||||
- **Sidecar support** (`box.sidecar`): olcrtc and TrustTunnel via local SOCKS5 chain
|
||||
- Auto-hardening: REST API disable, TUN forbid, optional QUIC block
|
||||
- `upsidercar` command in `box.tool` for TrustTunnel client download
|
||||
- Example configs: `config.stealth.example.json`, `olcrtc.example.yaml`, `trusttunnel.example.toml`
|
||||
- `stealth.list.cfg` for bank/checker package UID blocking
|
||||
- **wg-obfuscator** ([ClusterM](https://github.com/ClusterM/wg-obfuscator)): `box.wgobfs`, профиль `config-wg-obfs.json`, `box.tool upwgobfs`
|
||||
- Manage Profiles: `config-trusttunnel` / `config-olcrtc` / `config-wg-obfs`
|
||||
- Sidecar `both` + `sidecar_set_final=false` для переключения в BFR Manager
|
||||
- Restore при апгрейде: `trusttunnel_client`, `olcrtc`, `wg-obfuscator`, sidecar configs
|
||||
|
||||
## Changed
|
||||
- Default core: **sing-box** (was clash)
|
||||
- Default stealth settings enabled in `settings.ini`
|
||||
- Module name: **BFR Stealth Mod**
|
||||
- Full README rewrite
|
||||
## Notes
|
||||
- wg-obfuscator нужен и на VPS (тот же `key`)
|
||||
- Repo-шаблоны без секретов WG/Hysteria
|
||||
|
||||
## Based on
|
||||
- PronBox / VeilBox v1.11.0
|
||||
- [taamarin/box_for_magisk](https://github.com/taamarin/box_for_magisk) v1.10.2
|
||||
|
||||
130
README.md
130
README.md
@@ -1,8 +1,9 @@
|
||||
# BFR Stealth Mod
|
||||
# PronBox
|
||||
|
||||
Форк [box_for_magisk](https://github.com/taamarin/box_for_magisk) — прозрачный прокси для Android (root) с **anti-detection hardening без LSPosed** и поддержкой **sidecar-протоколов** [olcrtc](https://github.com/openlibrecommunity/olcrtc) / [TrustTunnel](https://github.com/TrustTunnel/TrustTunnel).
|
||||
Форк [box_for_magisk](https://github.com/taamarin/box_for_magisk) — прозрачный прокси для Android (root).
|
||||
Собрано в стенах **НИИ «ТехноПрон»**. Отображаемое имя в Magisk: **PronBox**; module id: `box_for_root` (апгрейд совместим).
|
||||
|
||||
Работает через Magisk, KernelSU и APatch. Ядра: `sing-box` (по умолчанию), `clash`, `xray`, `v2ray`, `hysteria`.
|
||||
Работает через Magisk, KernelSU и APatch. Ядро по умолчанию: **sing-box**. Anti-detection без LSPosed + sidecar: [olcrtc](https://github.com/openlibrecommunity/olcrtc) / [TrustTunnel](https://github.com/TrustTunnel/TrustTunnel) / [wg-obfuscator](https://github.com/ClusterM/wg-obfuscator).
|
||||
|
||||
---
|
||||
|
||||
@@ -10,24 +11,27 @@
|
||||
|
||||
Stock [Box for Root](https://github.com/taamarin/box_for_magisk) хорошо проксирует трафик через TPROXY, но:
|
||||
|
||||
1. **Не поддерживает** новые протоколы вроде olcrtc и TrustTunnel «из коробки».
|
||||
1. **Не поддерживает** новые протоколы вроде olcrtc, TrustTunnel и WG-obfuscation «из коробки».
|
||||
2. **Легко детектится** проверщиками вроде [RKNHardering](https://github.com/xtclovver/RKNHardering): REST API на `9090`, скан localhost, TUN-интерфейсы.
|
||||
|
||||
BFR Stealth Mod решает обе проблемы **без LSPosed** — через iptables port-hide, hardening конфигов и sidecar-цепочку.
|
||||
PronBox решает это **без LSPosed** — iptables port-hide, hardening конфигов и sidecar-цепочка. Разработано командой НИИ «ТехноПрон».
|
||||
|
||||
---
|
||||
|
||||
## Отличия от stock BFR
|
||||
|
||||
| Функция | Stock BFR | BFR Stealth Mod |
|
||||
|---------|-----------|-----------------|
|
||||
| Функция | Stock BFR | PronBox |
|
||||
|---------|-----------|---------|
|
||||
| Ядро по умолчанию | clash | **sing-box** |
|
||||
| Режим сети | tproxy | **tproxy** (TUN блокируется) |
|
||||
| REST API (9090) | `0.0.0.0` | **отключён** или только `127.0.0.1` |
|
||||
| TUN mode | доступен | **запрещён** (`stealth_forbid_tun`) |
|
||||
| Localhost scan | не защищён | **iptables port-hide** для observer apps |
|
||||
| olcrtc / TrustTunnel | нет | **sidecar → SOCKS → sing-box** |
|
||||
| WG obfuscator | нет | **wg-obfuscator → WireGuard** |
|
||||
| Быстрый профиль | — | **Manage Profiles / `sbfr p …`** |
|
||||
| LSPosed / VPN Hide | — | **не требуется** |
|
||||
| Автор | — | **команда НИИ «ТехноПрон»** |
|
||||
|
||||
---
|
||||
|
||||
@@ -82,43 +86,65 @@ Observer app (банк, RKNHardering)
|
||||
|
||||
### Из релиза
|
||||
|
||||
1. Скачайте `box_for_root-v*.zip` из [Releases](../../releases).
|
||||
1. Скачайте `pronbox-v*.zip` из [Releases](../../releases).
|
||||
2. Magisk / KernelSU / APatch → **Modules** → Install from storage.
|
||||
3. При установке выберите загрузку **sing-box** (Vol+).
|
||||
4. Перезагрузите устройство.
|
||||
|
||||
### Сборка из исходников
|
||||
|
||||
**Windows / любая ОС (рекомендуется):**
|
||||
|
||||
```powershell
|
||||
python tools/build_zip.py
|
||||
# → pronbox-v1.12.0.zip
|
||||
```
|
||||
|
||||
**Linux / Git Bash:**
|
||||
|
||||
```bash
|
||||
sh build.sh
|
||||
# → box_for_root-v1.10.2-stealth.1.zip
|
||||
```
|
||||
|
||||
**Windows (PowerShell):**
|
||||
|
||||
```powershell
|
||||
$v = (Get-Content module.prop | Where-Object { $_ -match '^version=' }) -replace 'version=',''
|
||||
Compress-Archive -Path (Get-ChildItem . -Force | Where-Object { $_.Name -notin '.git','.github','docs','CHANGELOG.md','update.json','build.sh' }) -DestinationPath "box_for_root-$v.zip" -Force
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Быстрый старт
|
||||
|
||||
> Перед правкой конфигов **остановите** сервис BFR.
|
||||
> Перед правкой конфигов **остановите** сервис PronBox.
|
||||
|
||||
### 1. Конфиг sing-box
|
||||
### 1. Профили TrustTunnel / olcrtc (быстрое переключение)
|
||||
|
||||
Скопируйте шаблон и настройте outbound:
|
||||
В модуле лежат два готовых шаблона:
|
||||
|
||||
| Профиль | Файл | SOCKS | `route.final` |
|
||||
|---------|------|-------|---------------|
|
||||
| TrustTunnel | `config.trusttunnel.json` | `:10800` | `sidecar-proxy` |
|
||||
| olcrtc | `config.olcrtc.json` | `:10801` | `olcrtc-proxy` |
|
||||
|
||||
Подставьте свои пароли/ключи (шаблоны в репозитории scrubbed) или на устройстве:
|
||||
|
||||
```bash
|
||||
# клонировать текущий рабочий конфиг в оба профиля
|
||||
su -c '/data/adb/box/scripts/box.profile seed'
|
||||
|
||||
# переключение (меняет name_sing_config + sidecar_* и рестартит сервис)
|
||||
sbfr p use trusttunnel
|
||||
sbfr p use olcrtc
|
||||
sbfr p status
|
||||
```
|
||||
|
||||
В Magisk/терминале то же самое: `su -c '/data/adb/box/scripts/box.profile use olcrtc'`.
|
||||
|
||||
### 2. Конфиг sing-box (с нуля)
|
||||
|
||||
Скопируйте минимальный шаблон и настройте outbound:
|
||||
|
||||
```bash
|
||||
cp /data/adb/box/sing-box/config.stealth.example.json /data/adb/box/sing-box/config.json
|
||||
# добавьте свой VLESS / другой outbound
|
||||
```
|
||||
|
||||
### 2. Observer-приложения (stealth)
|
||||
### 3. Observer-приложения (stealth)
|
||||
|
||||
Файл `/data/adb/box/stealth.list.cfg` — приложения, которым **скрываем** localhost-прокси:
|
||||
|
||||
@@ -130,7 +156,7 @@ ru.rostel
|
||||
com.notcvnt.rknhardering
|
||||
```
|
||||
|
||||
### 3. Blacklist для checker'а
|
||||
### 4. Blacklist для checker'а
|
||||
|
||||
Чтобы RKNHardering **не шёл через прокси**, добавьте в `/data/adb/box/package.list.cfg`:
|
||||
|
||||
@@ -139,7 +165,7 @@ mode:blacklist
|
||||
com.notcvnt.rknhardering
|
||||
```
|
||||
|
||||
### 4. Запуск
|
||||
### 5. Запуск
|
||||
|
||||
```bash
|
||||
su -c /data/adb/box/scripts/box.service start
|
||||
@@ -238,10 +264,53 @@ cp /data/adb/box/sidecar/olcrtc.example.yaml /data/adb/box/sidecar/olcrtc.yaml
|
||||
```ini
|
||||
sidecar_enable="true"
|
||||
sidecar_protocol="olcrtc"
|
||||
sidecar_listen_port="10800"
|
||||
sidecar_listen_port="10801"
|
||||
sidecar_outbound_tag="olcrtc-proxy"
|
||||
```
|
||||
|
||||
> **Важно:** порт в sidecar-конфиге (`socks.port` / listener) должен совпадать с `sidecar_listen_port`.
|
||||
> **Важно:** порт в sidecar-конфиге (`socks.port`) должен совпадать с `sidecar_listen_port` (TT `:10800`, olcrtc `:10801`).
|
||||
> Для olcrtc в `olcrtc.yaml` задайте LAN DNS: `net.dns: "192.168.0.1:53"` (публичные DNS через PreferGo от root часто виснут).
|
||||
|
||||
---
|
||||
|
||||
## WireGuard Obfuscator ([ClusterM/wg-obfuscator](https://github.com/ClusterM/wg-obfuscator))
|
||||
|
||||
Это **не VPN**, а UDP-обфускатор WireGuard (маскировка под STUN и т.п.). Нужен **на обоих концах** — телефон + VPS с тем же `key`. Со сторонним WG-сервером без своего obfuscator не заработает.
|
||||
|
||||
```text
|
||||
sing-box WireGuard peer
|
||||
→ 127.0.0.1:41320
|
||||
→ wg-obfuscator (client)
|
||||
→ VPS:public_udp
|
||||
→ wg-obfuscator (server)
|
||||
→ WireGuard на VPS
|
||||
```
|
||||
|
||||
### Клиент (Android / PronBox)
|
||||
|
||||
```bash
|
||||
su -c /data/adb/box/scripts/box.tool upwgobfs
|
||||
cp /data/adb/box/sidecar/wg-obfuscator.example.conf /data/adb/box/sidecar/wg-obfuscator.conf
|
||||
# key=... target=VPS_IP:PORT (порт публичного obfuscator на сервере)
|
||||
```
|
||||
|
||||
В `settings.ini`:
|
||||
|
||||
```ini
|
||||
wgobfs_enable="true"
|
||||
wgobfs_listen_port="41320"
|
||||
wgobfs_patch_config="true"
|
||||
```
|
||||
|
||||
Или профиль в **Manage Profiles**: `config-wg-obfs.json` (авто-старт wgobfs).
|
||||
|
||||
### Сервер (VPS)
|
||||
|
||||
См. `box/sidecar/wg-obfuscator.server.example.conf`:
|
||||
|
||||
1. Сдвинуть WireGuard `ListenPort` (например на `51820`).
|
||||
2. Поставить `wg-obfuscator` на старый публичный порт (`13232`).
|
||||
3. `target = 127.0.0.1:51820`, тот же `key`, `masking = AUTO`.
|
||||
|
||||
---
|
||||
|
||||
@@ -252,12 +321,15 @@ sidecar_listen_port="10800"
|
||||
| `/data/adb/box/settings.ini` | Главный конфиг |
|
||||
| `/data/adb/box/stealth.list.cfg` | Observer apps для port-hide |
|
||||
| `/data/adb/box/package.list.cfg` | Blacklist/whitelist приложений |
|
||||
| `/data/adb/box/sing-box/config.json` | Конфиг sing-box |
|
||||
| `/data/adb/box/sing-box/config.trusttunnel.json` | Профиль TrustTunnel |
|
||||
| `/data/adb/box/sing-box/config.olcrtc.json` | Профиль olcrtc |
|
||||
| `/data/adb/box/sing-box/config.json` | Активный конфиг (или через `name_sing_config`) |
|
||||
| `/data/adb/box/sidecar/` | Конфиги olcrtc / TrustTunnel |
|
||||
| `/data/adb/box/bin/` | Бинарники (sing-box, sidecar) |
|
||||
| `/data/adb/box/run/` | Логи, PID, UID-списки |
|
||||
| `/data/adb/box/scripts/box.stealth` | Stealth iptables |
|
||||
| `/data/adb/box/scripts/box.sidecar` | Sidecar lifecycle |
|
||||
| `/data/adb/box/scripts/box.profile` | Переключение TT / olcrtc |
|
||||
| `/data/adb/box/scripts/box.service` | Старт/стоп ядра |
|
||||
| `/data/adb/box/scripts/box.iptables` | TPROXY правила |
|
||||
|
||||
@@ -306,6 +378,8 @@ sbfr start # start + iptables
|
||||
sbfr stop # disable + stop
|
||||
sbfr s status # статус сервиса
|
||||
sbfr i enable # iptables
|
||||
sbfr p use trusttunnel # профиль TT
|
||||
sbfr p use olcrtc # профиль olcrtc
|
||||
sbfr t check # box.tool
|
||||
```
|
||||
|
||||
@@ -316,7 +390,7 @@ sbfr t check # box.tool
|
||||
1. `com.notcvnt.rknhardering` → `stealth.list.cfg`
|
||||
2. Тот же package → `package.list.cfg` **blacklist** (checker вне прокси)
|
||||
3. `stealth_disable_api="true"`, `network_mode="tproxy"`
|
||||
4. Запустить BFR → запустить RKNHardering
|
||||
4. Запустить PronBox → запустить RKNHardering
|
||||
|
||||
Ожидаемый результат: модули **Bypass Check** (Clash API, localhost proxy) и **Indirect Signs** (TUN) не должны давать hard detect. GeoIP/hosting и root-следы могут остаться.
|
||||
|
||||
@@ -326,11 +400,11 @@ sbfr t check # box.tool
|
||||
|
||||
```text
|
||||
Magisk / KernelSU / APatch
|
||||
└── BFR Stealth Mod
|
||||
└── PronBox (НИИ «ТехноПрон»)
|
||||
├── network_mode=tproxy, bin_name=sing-box
|
||||
├── stealth.list.cfg → банки, маркетплейсы
|
||||
├── package.list.cfg → whitelist нужных app ИЛИ blacklist checker'ов
|
||||
└── sidecar (опционально) → olcrtc / TrustTunnel
|
||||
└── sidecar → TrustTunnel / olcrtc / wg-obfuscator
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
33
RELEASE.md
Normal file
33
RELEASE.md
Normal file
@@ -0,0 +1,33 @@
|
||||
# Release PronBox v1.12.0
|
||||
|
||||
Продукт **НИИ «ТехноПрон»**. Magisk id: `box_for_root`.
|
||||
|
||||
## Локально
|
||||
|
||||
- Ветка `main`
|
||||
- Тег: `v1.12.0`
|
||||
- ZIP: `pronbox-v1.12.0.zip` → `python tools/build_zip.py`
|
||||
- Remote: `gitea@10.2.0.2:M1rs3m/BFR.git`
|
||||
- Display name: **PronBox**
|
||||
- Author: **команда НИИ «ТехноПрон»**
|
||||
|
||||
## Push + tag
|
||||
|
||||
```powershell
|
||||
cd E:\bfr_mod
|
||||
git push -u origin main
|
||||
git push origin v1.12.0
|
||||
```
|
||||
|
||||
## Release на Gitea
|
||||
|
||||
1. `http://10.2.0.2/M1rs3m/BFR` → **Releases** → **New Release**
|
||||
2. Tag: `v1.12.0`
|
||||
3. Title: `PronBox v1.12.0 — НИИ «ТехноПрон»`
|
||||
4. Description: `CHANGELOG_STEALTH.md`
|
||||
5. Attach: `pronbox-v1.12.0.zip`
|
||||
6. Publish
|
||||
|
||||
OTA (`update.json`):
|
||||
|
||||
`http://10.2.0.2/M1rs3m/BFR/releases/download/v1.12.0/pronbox-v1.12.0.zip`
|
||||
168
box/scripts/box.profile
Normal file
168
box/scripts/box.profile
Normal file
@@ -0,0 +1,168 @@
|
||||
#!/system/bin/sh
|
||||
# VeilBox profile switcher — trusttunnel | olcrtc
|
||||
# Usage:
|
||||
# su -c '/data/adb/box/scripts/box.profile list'
|
||||
# su -c '/data/adb/box/scripts/box.profile use trusttunnel'
|
||||
# su -c '/data/adb/box/scripts/box.profile use olcrtc'
|
||||
# su -c '/data/adb/box/scripts/box.profile status'
|
||||
|
||||
if ! /system/bin/sh -n /data/adb/box/settings.ini 2>/dev/null; then
|
||||
echo "Err: settings.ini syntax error" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
scripts_dir="${0%/*}"
|
||||
. /data/adb/box/settings.ini
|
||||
|
||||
profiles_dir="${box_dir}/sing-box"
|
||||
ini=/data/adb/box/settings.ini
|
||||
|
||||
profile_apply_settings() {
|
||||
name="$1"
|
||||
case "${name}" in
|
||||
trusttunnel|tt)
|
||||
sed -i 's/^name_sing_config=.*/name_sing_config="config-trusttunnel.json"/' "${ini}"
|
||||
sed -i 's/^sidecar_enable=.*/sidecar_enable="true"/' "${ini}"
|
||||
# both + set_final=false → BFR Manager can also flip without breaking finals
|
||||
sed -i 's/^sidecar_protocol=.*/sidecar_protocol="both"/' "${ini}"
|
||||
sed -i 's/^sidecar_listen_port=.*/sidecar_listen_port="10800"/' "${ini}"
|
||||
sed -i 's/^sidecar_outbound_tag=.*/sidecar_outbound_tag="sidecar-proxy"/' "${ini}"
|
||||
sed -i 's/^sidecar_set_final=.*/sidecar_set_final="false"/' "${ini}"
|
||||
echo "trusttunnel"
|
||||
;;
|
||||
olcrtc|olc)
|
||||
sed -i 's/^name_sing_config=.*/name_sing_config="config-olcrtc.json"/' "${ini}"
|
||||
sed -i 's/^sidecar_enable=.*/sidecar_enable="true"/' "${ini}"
|
||||
sed -i 's/^sidecar_protocol=.*/sidecar_protocol="both"/' "${ini}"
|
||||
sed -i 's/^sidecar_listen_port=.*/sidecar_listen_port="10801"/' "${ini}"
|
||||
sed -i 's/^sidecar_outbound_tag=.*/sidecar_outbound_tag="sidecar-proxy"/' "${ini}"
|
||||
sed -i 's/^sidecar_set_final=.*/sidecar_set_final="false"/' "${ini}"
|
||||
# Prefer LAN DNS for olcrtc PreferGo resolver under root:net_admin
|
||||
if [ -f "${box_dir}/sidecar/olcrtc.yaml" ] && [ -x "${box_dir}/bin/yq" ]; then
|
||||
"${box_dir}/bin/yq" -i '.net.dns = "192.168.0.1:53"' "${box_dir}/sidecar/olcrtc.yaml" 2>/dev/null || true
|
||||
fi
|
||||
echo "olcrtc"
|
||||
;;
|
||||
wg-obfs|wgobfs|wg)
|
||||
sed -i 's/^name_sing_config=.*/name_sing_config="config-wg-obfs.json"/' "${ini}"
|
||||
sed -i 's/^wgobfs_enable=.*/wgobfs_enable="true"/' "${ini}"
|
||||
grep -q '^wgobfs_enable=' "${ini}" || echo 'wgobfs_enable="true"' >> "${ini}"
|
||||
echo "wg-obfs"
|
||||
;;
|
||||
*)
|
||||
echo "Unknown profile: ${name}" >&2
|
||||
echo "Available: trusttunnel | olcrtc | wg-obfs" >&2
|
||||
return 1
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
profile_seed_from_active() {
|
||||
# If profile json missing, clone current sing config and patch final/dns
|
||||
src="${sing_config}"
|
||||
[ -f "${src}" ] || src="${profiles_dir}/config.json"
|
||||
[ -f "${src}" ] || return 1
|
||||
yq="${box_dir}/bin/yq"
|
||||
[ -x "${yq}" ] || return 1
|
||||
|
||||
if [ ! -f "${profiles_dir}/config-trusttunnel.json" ]; then
|
||||
cp -f "${src}" "${profiles_dir}/config-trusttunnel.json"
|
||||
"${yq}" -i -o=json '
|
||||
.route.final = "sidecar-proxy" |
|
||||
(.dns.servers[] | select(.tag == "dns-remote") | .detour) = "sidecar-proxy" |
|
||||
.dns.final = "dns-remote" |
|
||||
.dns.strategy = "ipv4_only"
|
||||
' "${profiles_dir}/config-trusttunnel.json"
|
||||
if ! "${yq}" -e '.outbounds[] | select(.tag == "sidecar-proxy")' "${profiles_dir}/config-trusttunnel.json" >/dev/null 2>&1; then
|
||||
"${yq}" -i -o=json '.outbounds += [{"type":"socks","tag":"sidecar-proxy","server":"127.0.0.1","server_port":10800,"version":"5"}]' "${profiles_dir}/config-trusttunnel.json"
|
||||
fi
|
||||
if ! "${yq}" -e '.outbounds[] | select(.tag == "olcrtc-proxy")' "${profiles_dir}/config-trusttunnel.json" >/dev/null 2>&1; then
|
||||
"${yq}" -i -o=json '.outbounds += [{"type":"socks","tag":"olcrtc-proxy","server":"127.0.0.1","server_port":10801,"version":"5"}]' "${profiles_dir}/config-trusttunnel.json"
|
||||
fi
|
||||
log Info "[Profile] seeded config-trusttunnel.json"
|
||||
fi
|
||||
if [ ! -f "${profiles_dir}/config-olcrtc.json" ]; then
|
||||
cp -f "${src}" "${profiles_dir}/config-olcrtc.json"
|
||||
"${yq}" -i -o=json '
|
||||
.route.final = "olcrtc-proxy" |
|
||||
(.dns.servers[] | select(.tag == "dns-remote") | .detour) = "olcrtc-proxy" |
|
||||
.dns.final = "dns-remote" |
|
||||
.dns.strategy = "ipv4_only"
|
||||
' "${profiles_dir}/config-olcrtc.json"
|
||||
if ! "${yq}" -e '.outbounds[] | select(.tag == "sidecar-proxy")' "${profiles_dir}/config-olcrtc.json" >/dev/null 2>&1; then
|
||||
"${yq}" -i -o=json '.outbounds += [{"type":"socks","tag":"sidecar-proxy","server":"127.0.0.1","server_port":10800,"version":"5"}]' "${profiles_dir}/config-olcrtc.json"
|
||||
fi
|
||||
if ! "${yq}" -e '.outbounds[] | select(.tag == "olcrtc-proxy")' "${profiles_dir}/config-olcrtc.json" >/dev/null 2>&1; then
|
||||
"${yq}" -i -o=json '.outbounds += [{"type":"socks","tag":"olcrtc-proxy","server":"127.0.0.1","server_port":10801,"version":"5"}]' "${profiles_dir}/config-olcrtc.json"
|
||||
fi
|
||||
log Info "[Profile] seeded config-olcrtc.json"
|
||||
fi
|
||||
}
|
||||
|
||||
profile_list() {
|
||||
echo "Profiles (also visible in BFR Manager → Manage Profiles):"
|
||||
echo " trusttunnel -> config-trusttunnel.json (final=sidecar-proxy :10800)"
|
||||
echo " olcrtc -> config-olcrtc.json (final=olcrtc-proxy :10801)"
|
||||
echo " wg-obfs -> config-wg-obfs.json (WG via wg-obfuscator :41320)"
|
||||
echo " sidecar mode -> both (set_final=false) so app switching keeps finals"
|
||||
echo " NOTE: wg-obfs needs matching obfuscator on the VPS (same key)"
|
||||
echo
|
||||
echo "Files in ${profiles_dir}:"
|
||||
ls -1 "${profiles_dir}"/config*.json 2>/dev/null
|
||||
echo
|
||||
echo "Active:"
|
||||
grep -E '^name_sing_config=|^sidecar_protocol=|^sidecar_listen_port=|^sidecar_outbound_tag=' "${ini}"
|
||||
}
|
||||
|
||||
profile_status() {
|
||||
. /data/adb/box/settings.ini
|
||||
echo "name_sing_config=${name_sing_config}"
|
||||
echo "sing_config=${sing_config}"
|
||||
echo "sidecar_protocol=${sidecar_protocol} port=${sidecar_listen_port} tag=${sidecar_outbound_tag}"
|
||||
if [ -x "${box_dir}/bin/yq" ] && [ -f "${sing_config}" ]; then
|
||||
echo "route.final=$(${box_dir}/bin/yq -r '.route.final' "${sing_config}")"
|
||||
fi
|
||||
echo "tt=$(pidof trusttunnel_client 2>/dev/null)"
|
||||
echo "olc=$(pidof olcrtc 2>/dev/null)"
|
||||
echo "sb=$(pidof sing-box 2>/dev/null)"
|
||||
}
|
||||
|
||||
profile_use() {
|
||||
name="$1"
|
||||
[ -n "${name}" ] || { echo "usage: $0 use {trusttunnel|olcrtc}"; exit 1; }
|
||||
profile_seed_from_active || true
|
||||
applied=$(profile_apply_settings "${name}") || exit 1
|
||||
|
||||
# reload settings after sed
|
||||
. /data/adb/box/settings.ini
|
||||
|
||||
if [ ! -f "${sing_config}" ]; then
|
||||
log Error "[Profile] missing ${sing_config}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
log Info "[Profile] switching to ${applied} (${name_sing_config})"
|
||||
"${scripts_dir}/box.service" restart
|
||||
sleep 2
|
||||
"${scripts_dir}/box.iptables" renew >/dev/null 2>&1 || true
|
||||
profile_status
|
||||
}
|
||||
|
||||
case "$1" in
|
||||
list)
|
||||
profile_list
|
||||
;;
|
||||
status)
|
||||
profile_status
|
||||
;;
|
||||
use|switch)
|
||||
profile_use "$2"
|
||||
;;
|
||||
seed)
|
||||
profile_seed_from_active
|
||||
;;
|
||||
*)
|
||||
echo "usage: $0 {list|status|use trusttunnel|use olcrtc|seed}"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
@@ -486,6 +486,16 @@ box_run_bin() {
|
||||
;;
|
||||
sing-box)
|
||||
prepare_singbox
|
||||
# Auto-enable WG obfuscator when Manage Profiles picks config-wg-obfs.json
|
||||
case "${name_sing_config}" in
|
||||
*wg-obfs*|*wgobfs*)
|
||||
wgobfs_enable="true"
|
||||
;;
|
||||
esac
|
||||
if [ "${wgobfs_enable}" = "true" ]; then
|
||||
"${scripts_dir}/box.wgobfs" start || exit 1
|
||||
prepare_stealth_singbox
|
||||
fi
|
||||
if [ "${sidecar_enable}" = "true" ]; then
|
||||
"${scripts_dir}/box.sidecar" start || exit 1
|
||||
prepare_stealth_singbox
|
||||
@@ -818,6 +828,7 @@ start_box() {
|
||||
|
||||
stop_box() {
|
||||
stop_cron
|
||||
"${scripts_dir}/box.wgobfs" stop >/dev/null 2>&1
|
||||
"${scripts_dir}/box.sidecar" stop >/dev/null 2>&1
|
||||
"${scripts_dir}/box.stealth" disable >/dev/null 2>&1
|
||||
# Kill each binary using a loop
|
||||
|
||||
@@ -11,39 +11,32 @@ scripts_dir="${0%/*}"
|
||||
|
||||
sidecar_dir="${box_dir}/sidecar"
|
||||
sidecar_pid="${box_run}/sidecar.pid"
|
||||
sidecar_pid_olc="${box_run}/sidecar-olcrtc.pid"
|
||||
sidecar_pid_tt="${box_run}/sidecar-trusttunnel.pid"
|
||||
sidecar_log="${box_run}/sidecar.log"
|
||||
|
||||
sidecar_bin_path() {
|
||||
case "${sidecar_protocol}" in
|
||||
olcrtc) echo "${box_dir}/bin/olcrtc" ;;
|
||||
trusttunnel) echo "${box_dir}/bin/trusttunnel_client" ;;
|
||||
*) echo "" ;;
|
||||
esac
|
||||
}
|
||||
|
||||
sidecar_config_path() {
|
||||
case "${sidecar_protocol}" in
|
||||
olcrtc) echo "${sidecar_dir}/olcrtc.yaml" ;;
|
||||
trusttunnel) echo "${sidecar_dir}/trusttunnel.toml" ;;
|
||||
*) echo "" ;;
|
||||
esac
|
||||
}
|
||||
# Defaults for dual mode
|
||||
: "${sidecar_tt_port:=10800}"
|
||||
: "${sidecar_olc_port:=10801}"
|
||||
: "${sidecar_olc_tag:=olcrtc-proxy}"
|
||||
|
||||
sidecar_stop() {
|
||||
if [ -f "${sidecar_pid}" ]; then
|
||||
spid=$(cat "${sidecar_pid}" 2>/dev/null)
|
||||
[ -n "${spid}" ] && kill -15 "${spid}" >/dev/null 2>&1
|
||||
rm -f "${sidecar_pid}"
|
||||
fi
|
||||
for pf in "${sidecar_pid}" "${sidecar_pid_olc}" "${sidecar_pid_tt}"; do
|
||||
if [ -f "${pf}" ]; then
|
||||
spid=$(cat "${pf}" 2>/dev/null)
|
||||
[ -n "${spid}" ] && kill -15 "${spid}" >/dev/null 2>&1
|
||||
rm -f "${pf}"
|
||||
fi
|
||||
done
|
||||
for bin in olcrtc trusttunnel_client; do
|
||||
busybox pkill -15 "${bin}" >/dev/null 2>&1
|
||||
done
|
||||
}
|
||||
|
||||
sidecar_wait_ready() {
|
||||
port="${sidecar_listen_port}"
|
||||
sidecar_wait_port() {
|
||||
port="$1"
|
||||
i=0
|
||||
while [ "${i}" -lt 30 ]; do
|
||||
while [ "${i}" -lt 45 ]; do
|
||||
if busybox nc -z 127.0.0.1 "${port}" 2>/dev/null; then
|
||||
return 0
|
||||
fi
|
||||
@@ -53,90 +46,192 @@ sidecar_wait_ready() {
|
||||
return 1
|
||||
}
|
||||
|
||||
sidecar_start_process() {
|
||||
_bin=$(sidecar_bin_path)
|
||||
_cfg=$(sidecar_config_path)
|
||||
|
||||
if [ "${sidecar_enable}" != "true" ]; then
|
||||
return 0
|
||||
fi
|
||||
|
||||
if [ -z "${sidecar_protocol}" ]; then
|
||||
log Error "[Sidecar] sidecar_protocol is empty (olcrtc | trusttunnel)"
|
||||
return 1
|
||||
fi
|
||||
sidecar_start_one() {
|
||||
# $1=protocol $2=bin $3=cfg $4=port $5=pidfile $6=extra_args...
|
||||
_proto="$1"; _bin="$2"; _cfg="$3"; _port="$4"; _pf="$5"
|
||||
shift 5
|
||||
|
||||
if [ ! -x "${_bin}" ]; then
|
||||
log Error "[Sidecar] Binary not found: ${_bin}"
|
||||
log Error "[Sidecar] Run: su -c /data/adb/box/scripts/box.tool upsidercar"
|
||||
return 1
|
||||
fi
|
||||
|
||||
if [ ! -f "${_cfg}" ]; then
|
||||
log Error "[Sidecar] Config not found: ${_cfg}"
|
||||
log Error "[Sidecar] Copy example from ${sidecar_dir}/*.example.*"
|
||||
return 1
|
||||
fi
|
||||
|
||||
sidecar_stop
|
||||
mkdir -p "${sidecar_dir}" "${box_run}"
|
||||
: > "${sidecar_log}"
|
||||
|
||||
case "${sidecar_protocol}" in
|
||||
case "${_proto}" in
|
||||
olcrtc)
|
||||
nohup busybox setuidgid "${box_user_group}" "${_bin}" "${_cfg}" >> "${sidecar_log}" 2>&1 &
|
||||
;;
|
||||
trusttunnel)
|
||||
nohup busybox setuidgid "${box_user_group}" "${_bin}" -c "${_cfg}" >> "${sidecar_log}" 2>&1 &
|
||||
nohup busybox setuidgid "${box_user_group}" "${_bin}" -s -c "${_cfg}" >> "${sidecar_log}" 2>&1 &
|
||||
;;
|
||||
*)
|
||||
log Error "[Sidecar] Unknown protocol: ${sidecar_protocol}"
|
||||
log Error "[Sidecar] Unknown protocol: ${_proto}"
|
||||
return 1
|
||||
;;
|
||||
esac
|
||||
|
||||
echo -n "$!" > "${_pf}"
|
||||
# Also keep legacy sidecar.pid pointing at last/primary
|
||||
echo -n "$!" > "${sidecar_pid}"
|
||||
log Info "[Sidecar] Starting ${sidecar_protocol} on 127.0.0.1:${sidecar_listen_port}"
|
||||
log Info "[Sidecar] Starting ${_proto} on 127.0.0.1:${_port} (pid $!)"
|
||||
|
||||
if sidecar_wait_ready; then
|
||||
log Info "[Sidecar] ${sidecar_protocol} SOCKS ready"
|
||||
if sidecar_wait_port "${_port}"; then
|
||||
log Info "[Sidecar] ${_proto} SOCKS ready on :${_port}"
|
||||
return 0
|
||||
fi
|
||||
|
||||
log Error "[Sidecar] Timeout waiting for port ${sidecar_listen_port}"
|
||||
log Error "[Sidecar] Log: ${sidecar_log}"
|
||||
tail -n 15 "${sidecar_log}" 2>/dev/null | while read -r line; do log Error "[Sidecar] ${line}"; done
|
||||
log Error "[Sidecar] Timeout waiting for ${_proto} port ${_port}"
|
||||
tail -n 20 "${sidecar_log}" 2>/dev/null | while read -r line; do log Error "[Sidecar] ${line}"; done
|
||||
return 1
|
||||
}
|
||||
|
||||
sidecar_inject_socks() {
|
||||
# $1=tag $2=port
|
||||
tag="$1"
|
||||
port="$2"
|
||||
yq="${box_dir}/bin/yq"
|
||||
[ -x "${yq}" ] || yq="yq"
|
||||
|
||||
if ! "${yq}" ".outbounds[] | select(.tag == \"${tag}\")" "${sing_config}" 2>/dev/null | grep -q .; then
|
||||
"${yq}" ".outbounds += [{
|
||||
\"type\": \"socks\",
|
||||
\"tag\": \"${tag}\",
|
||||
\"server\": \"127.0.0.1\",
|
||||
\"server_port\": ${port},
|
||||
\"version\": \"5\"
|
||||
}]" -i --output-format=json "${sing_config}" && \
|
||||
log Info "[Sidecar] Injected socks '${tag}' -> 127.0.0.1:${port}"
|
||||
else
|
||||
# Keep port in sync
|
||||
"${yq}" "(.outbounds[] | select(.tag == \"${tag}\") | .server_port) = ${port}" -i --output-format=json "${sing_config}" 2>/dev/null
|
||||
log Info "[Sidecar] Outbound '${tag}' already present (port=${port})"
|
||||
fi
|
||||
}
|
||||
|
||||
sidecar_patch_dns() {
|
||||
tag="$1"
|
||||
yq="${box_dir}/bin/yq"
|
||||
[ -x "${yq}" ] || yq="yq"
|
||||
|
||||
"${yq}" '
|
||||
( [.dns.servers[]? | select(.tag == "dns-direct")] | length) as $n |
|
||||
if $n == 0 then .dns.servers = [{"type":"local","tag":"dns-direct"}] + (.dns.servers // []) else . end
|
||||
' -i --output-format=json "${sing_config}" 2>/dev/null || true
|
||||
|
||||
"${yq}" '(.dns.servers[] | select(.detour == "proxy" or .tag == "dns-remote") | .detour) = "'"${tag}"'"' -i --output-format=json "${sing_config}" 2>/dev/null && \
|
||||
log Info "[Sidecar] dns-remote detour -> ${tag}"
|
||||
|
||||
"${yq}" '
|
||||
(.dns.servers[] | select(.tag == "dns-remote")) = {"type":"https","tag":"dns-remote","detour":"'"${tag}"'","server":"1.1.1.1","path":"/dns-query"} |
|
||||
.dns.final = "dns-remote" |
|
||||
.dns.strategy = "ipv4_only"
|
||||
' -i --output-format=json "${sing_config}" 2>/dev/null && \
|
||||
log Info "[Sidecar] dns-remote -> https/1.1.1.1 via ${tag}, strategy ipv4_only"
|
||||
}
|
||||
|
||||
sidecar_inject_singbox() {
|
||||
[ "${sidecar_enable}" != "true" ] && return 0
|
||||
[ "${bin_name}" != "sing-box" ] && return 0
|
||||
[ ! -f "${sing_config}" ] && return 0
|
||||
|
||||
yq="${box_dir}/bin/yq"
|
||||
command -v yq >/dev/null 2>&1 || yq="yq"
|
||||
|
||||
tag="${sidecar_outbound_tag}"
|
||||
port="${sidecar_listen_port}"
|
||||
|
||||
if ! ${yq} ".outbounds[] | select(.tag == \"${tag}\")" "${sing_config}" 2>/dev/null | grep -q .; then
|
||||
${yq} ".outbounds += [{
|
||||
\"type\": \"socks\",
|
||||
\"tag\": \"${tag}\",
|
||||
\"server\": \"127.0.0.1\",
|
||||
\"server_port\": ${port},
|
||||
\"version\": \"5\"
|
||||
}]" -i --output-format=json "${sing_config}"
|
||||
log Info "[Sidecar] Injected socks outbound '${tag}' -> 127.0.0.1:${port}"
|
||||
if [ ! -x "${yq}" ]; then
|
||||
if command -v yq >/dev/null 2>&1; then
|
||||
yq="yq"
|
||||
else
|
||||
log Error "[Sidecar] yq not found — cannot inject socks outbound"
|
||||
return 1
|
||||
fi
|
||||
fi
|
||||
|
||||
case "${sidecar_protocol}" in
|
||||
both)
|
||||
# Fixed tags for BFR Manager profiles (ignore mis-set sidecar_outbound_tag)
|
||||
sidecar_inject_socks "sidecar-proxy" "${sidecar_tt_port}"
|
||||
sidecar_inject_socks "${sidecar_olc_tag}" "${sidecar_olc_port}"
|
||||
# Prefer final already set in the active profile (BFR Manager Manage Profiles)
|
||||
cur_final=$("${yq}" -r '.route.final // ""' "${sing_config}" 2>/dev/null)
|
||||
case "${cur_final}" in
|
||||
"${sidecar_olc_tag}"|sidecar-proxy|"${sidecar_outbound_tag}")
|
||||
final_tag="${cur_final}"
|
||||
;;
|
||||
*)
|
||||
final_tag="sidecar-proxy"
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
olcrtc)
|
||||
sidecar_inject_socks "${sidecar_outbound_tag}" "${sidecar_listen_port}"
|
||||
final_tag="${sidecar_outbound_tag}"
|
||||
;;
|
||||
trusttunnel|*)
|
||||
sidecar_inject_socks "${sidecar_outbound_tag}" "${sidecar_listen_port}"
|
||||
final_tag="${sidecar_outbound_tag}"
|
||||
;;
|
||||
esac
|
||||
|
||||
if [ "${sidecar_set_final}" = "true" ]; then
|
||||
${yq} ".route.final = \"${tag}\"" -i --output-format=json "${sing_config}"
|
||||
log Info "[Sidecar] route.final -> ${tag}"
|
||||
"${yq}" ".route.final = \"${final_tag}\"" -i --output-format=json "${sing_config}" && \
|
||||
log Info "[Sidecar] route.final -> ${final_tag}"
|
||||
sidecar_patch_dns "${final_tag}"
|
||||
else
|
||||
log Info "[Sidecar] sidecar_set_final=false — keep profile route.final (BFR Manager switch)"
|
||||
fi
|
||||
}
|
||||
|
||||
sidecar_start_process() {
|
||||
if [ "${sidecar_enable}" != "true" ]; then
|
||||
return 0
|
||||
fi
|
||||
|
||||
if [ -z "${sidecar_protocol}" ]; then
|
||||
log Error "[Sidecar] sidecar_protocol is empty (olcrtc | trusttunnel | both)"
|
||||
return 1
|
||||
fi
|
||||
|
||||
sidecar_stop
|
||||
mkdir -p "${sidecar_dir}" "${box_run}" /data/adb/box/run/olcrtc-data
|
||||
: > "${sidecar_log}"
|
||||
|
||||
case "${sidecar_protocol}" in
|
||||
olcrtc)
|
||||
sidecar_start_one olcrtc "${box_dir}/bin/olcrtc" "${sidecar_dir}/olcrtc.yaml" \
|
||||
"${sidecar_listen_port}" "${sidecar_pid_olc}" || return 1
|
||||
;;
|
||||
trusttunnel)
|
||||
sidecar_start_one trusttunnel "${box_dir}/bin/trusttunnel_client" "${sidecar_dir}/trusttunnel.toml" \
|
||||
"${sidecar_listen_port}" "${sidecar_pid_tt}" || return 1
|
||||
;;
|
||||
both)
|
||||
# TT + olcrtc for BFR Manager profile flipping; missing one must not block the other
|
||||
sidecar_start_one trusttunnel "${box_dir}/bin/trusttunnel_client" "${sidecar_dir}/trusttunnel.toml" \
|
||||
"${sidecar_tt_port}" "${sidecar_pid_tt}" || \
|
||||
log Warning "[Sidecar] trusttunnel failed/missing — continue without it"
|
||||
sleep 2
|
||||
sidecar_start_one olcrtc "${box_dir}/bin/olcrtc" "${sidecar_dir}/olcrtc.yaml" \
|
||||
"${sidecar_olc_port}" "${sidecar_pid_olc}" || {
|
||||
log Warning "[Sidecar] olcrtc failed to start — continuing without it"
|
||||
log Warning "[Sidecar] Tip: telemost room.id = full https://telemost.yandex.ru/j/<id> URL (or numeric id)"
|
||||
log Warning "[Sidecar] Tip: under root:net_admin set net.dns to LAN resolver (e.g. gateway:53)"
|
||||
}
|
||||
# Only hard-fail if neither SOCKS came up
|
||||
if ! busybox nc -z 127.0.0.1 "${sidecar_tt_port}" 2>/dev/null && \
|
||||
! busybox nc -z 127.0.0.1 "${sidecar_olc_port}" 2>/dev/null; then
|
||||
log Error "[Sidecar] neither trusttunnel nor olcrtc is listening"
|
||||
return 1
|
||||
fi
|
||||
;;
|
||||
*)
|
||||
log Error "[Sidecar] Unknown protocol: ${sidecar_protocol}"
|
||||
return 1
|
||||
;;
|
||||
esac
|
||||
return 0
|
||||
}
|
||||
|
||||
case "$1" in
|
||||
start)
|
||||
sidecar_start_process && sidecar_inject_singbox
|
||||
@@ -149,11 +244,16 @@ case "$1" in
|
||||
sidecar_inject_singbox
|
||||
;;
|
||||
status)
|
||||
if [ -f "${sidecar_pid}" ] && kill -0 "$(cat "${sidecar_pid}")" 2>/dev/null; then
|
||||
log Info "[Sidecar] Running PID $(cat "${sidecar_pid}") protocol=${sidecar_protocol}"
|
||||
else
|
||||
log Info "[Sidecar] Not running"
|
||||
fi
|
||||
echo "protocol=${sidecar_protocol}"
|
||||
for pf in "${sidecar_pid_tt}" "${sidecar_pid_olc}" "${sidecar_pid}"; do
|
||||
[ -f "${pf}" ] || continue
|
||||
spid=$(cat "${pf}" 2>/dev/null)
|
||||
if [ -n "${spid}" ] && kill -0 "${spid}" 2>/dev/null; then
|
||||
log Info "[Sidecar] alive pid=${spid} file=$(basename "${pf}")"
|
||||
fi
|
||||
done
|
||||
busybox nc -z 127.0.0.1 "${sidecar_tt_port}" 2>/dev/null && echo "port ${sidecar_tt_port} open" || true
|
||||
busybox nc -z 127.0.0.1 "${sidecar_olc_port}" 2>/dev/null && echo "port ${sidecar_olc_port} open" || true
|
||||
;;
|
||||
*)
|
||||
echo "usage: $0 {start|stop|inject|status}"
|
||||
|
||||
@@ -1197,15 +1197,50 @@ upsidercar() {
|
||||
if [ "${target}" = "olcrtc" ] || [ "${target}" = "all" ]; then
|
||||
if [ -x "${bin_dir}/olcrtc" ]; then
|
||||
log Info "olcrtc already present: ${bin_dir}/olcrtc"
|
||||
"${bin_dir}/olcrtc" 2>&1 | head -1 || true
|
||||
else
|
||||
log Warning "olcrtc has no official Android release bundle."
|
||||
log Warning "Build with: mage mobile (https://github.com/openlibrecommunity/olcrtc)"
|
||||
log Warning "Or copy binary to ${bin_dir}/olcrtc and chmod 755"
|
||||
log Warning "Example config: ${box_dir}/sidecar/olcrtc.example.yaml -> olcrtc.yaml"
|
||||
log Warning "On PC build linux/arm64: tools/build_olcrtc_arm64.ps1"
|
||||
log Warning "Then: adb push olcrtc-linux-arm64 /data/local/tmp/olcrtc && su -c 'cp /data/local/tmp/olcrtc ${bin_dir}/olcrtc && chmod 755 ${bin_dir}/olcrtc'"
|
||||
log Warning "Config: ${box_dir}/sidecar/olcrtc.example.yaml -> olcrtc.yaml (socks.port 10801 for dual mode)"
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
upwgobfs() {
|
||||
# su -c /data/adb/box/scripts/box.tool upwgobfs
|
||||
mkdir -p "${bin_dir}" "${box_dir}/sidecar"
|
||||
case $(uname -m) in
|
||||
aarch64) asset="wg-obfuscator-v1.5-linux-arm64.tar.gz" ;;
|
||||
armv7l|armv8l) asset="wg-obfuscator-v1.5-linux-armv7-hf.tar.gz" ;;
|
||||
x86_64) asset="wg-obfuscator-v1.5-linux-x64.tar.gz" ;;
|
||||
*) log Error "Unsupported arch for wg-obfuscator: $(uname -m)"; return 1 ;;
|
||||
esac
|
||||
url="https://github.com/ClusterM/wg-obfuscator/releases/download/v1.5/${asset}"
|
||||
log Info "Downloading ${asset}"
|
||||
if upfile "${box_dir}/${asset}" "${url}"; then
|
||||
tar -xzf "${box_dir}/${asset}" -C "${box_dir}" 2>/dev/null
|
||||
find "${box_dir}" -maxdepth 3 -name 'wg-obfuscator' -type f 2>/dev/null | while read -r f; do
|
||||
cp -f "${f}" "${bin_dir}/wg-obfuscator"
|
||||
chmod 755 "${bin_dir}/wg-obfuscator"
|
||||
done
|
||||
rm -f "${box_dir}/${asset}"
|
||||
if [ -x "${bin_dir}/wg-obfuscator" ]; then
|
||||
log Info "Installed ${bin_dir}/wg-obfuscator"
|
||||
"${bin_dir}/wg-obfuscator" -V 2>&1 | head -2 || true
|
||||
else
|
||||
log Error "wg-obfuscator binary not found after extract"
|
||||
fi
|
||||
if [ ! -f "${box_dir}/sidecar/wg-obfuscator.conf" ] && [ -f "${box_dir}/sidecar/wg-obfuscator.example.conf" ]; then
|
||||
cp -f "${box_dir}/sidecar/wg-obfuscator.example.conf" "${box_dir}/sidecar/wg-obfuscator.conf"
|
||||
log Warning "Created sidecar/wg-obfuscator.conf — set key= and target="
|
||||
fi
|
||||
else
|
||||
log Error "Download failed: ${url}"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
case "$1" in
|
||||
check)
|
||||
check
|
||||
@@ -1232,6 +1267,9 @@ case "$1" in
|
||||
upsidercar)
|
||||
upsidercar
|
||||
;;
|
||||
upwgobfs)
|
||||
upwgobfs
|
||||
;;
|
||||
geosub)
|
||||
upgeox
|
||||
upsubs
|
||||
@@ -1288,6 +1326,7 @@ case "$1" in
|
||||
echo " subs - Update subscription (only for clash), then reload if running"
|
||||
echo " upkernel - Update kernel-related components"
|
||||
echo " upsidercar - Install sidecar binaries (olcrtc / trusttunnel)"
|
||||
echo " upwgobfs - Install ClusterM wg-obfuscator (WireGuard UDP obfuscation)"
|
||||
echo " upxui - Update XUI panel"
|
||||
echo " upyq - Update yq binary"
|
||||
echo " upcurl - Update curl binary"
|
||||
|
||||
177
box/scripts/box.wgobfs
Normal file
177
box/scripts/box.wgobfs
Normal file
@@ -0,0 +1,177 @@
|
||||
#!/system/bin/sh
|
||||
# VeilBox — WireGuard Obfuscator (ClusterM/wg-obfuscator) lifecycle
|
||||
# Docs: https://github.com/ClusterM/wg-obfuscator
|
||||
#
|
||||
# Client flow:
|
||||
# sing-box WireGuard peer → 127.0.0.1:wgobfs_listen_port
|
||||
# → wg-obfuscator → real server obfuscator (or server WG via obfuscator)
|
||||
#
|
||||
# REQUIRED: the same key + matching ports on the VPS (server-side obfuscator).
|
||||
# Without the server half this cannot work.
|
||||
|
||||
if ! /system/bin/sh -n /data/adb/box/settings.ini 2>/dev/null; then
|
||||
echo "Err: settings.ini syntax error" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
scripts_dir="${0%/*}"
|
||||
. /data/adb/box/settings.ini
|
||||
|
||||
: "${wgobfs_enable:=false}"
|
||||
: "${wgobfs_bin:=${box_dir}/bin/wg-obfuscator}"
|
||||
: "${wgobfs_config:=${box_dir}/sidecar/wg-obfuscator.conf}"
|
||||
: "${wgobfs_listen_port:=41320}"
|
||||
: "${wgobfs_masking:=AUTO}"
|
||||
: "${wgobfs_patch_config:=true}"
|
||||
|
||||
wgobfs_pid="${box_run}/wg-obfuscator.pid"
|
||||
wgobfs_log="${box_run}/wg-obfuscator.log"
|
||||
|
||||
wgobfs_stop() {
|
||||
if [ -f "${wgobfs_pid}" ]; then
|
||||
spid=$(cat "${wgobfs_pid}" 2>/dev/null)
|
||||
[ -n "${spid}" ] && kill -15 "${spid}" >/dev/null 2>&1
|
||||
rm -f "${wgobfs_pid}"
|
||||
fi
|
||||
busybox pkill -15 wg-obfuscator >/dev/null 2>&1
|
||||
}
|
||||
|
||||
wgobfs_wait_udp() {
|
||||
# UDP listen is hard to probe with nc -z; rely on process + brief sleep
|
||||
sleep 1
|
||||
if [ -f "${wgobfs_pid}" ]; then
|
||||
spid=$(cat "${wgobfs_pid}" 2>/dev/null)
|
||||
kill -0 "${spid}" 2>/dev/null && return 0
|
||||
fi
|
||||
busybox pidof wg-obfuscator >/dev/null 2>&1
|
||||
}
|
||||
|
||||
# Rewrite sing-box wireguard peers to localhost obfuscator listen port.
|
||||
# Saves originals into .peers[]._veilbox_real_address / _veilbox_real_port (ignored by sing-box).
|
||||
wgobfs_patch_singbox() {
|
||||
[ "${wgobfs_patch_config}" = "true" ] || return 0
|
||||
[ "${bin_name}" != "sing-box" ] && return 0
|
||||
[ ! -f "${sing_config}" ] && return 0
|
||||
|
||||
yq="${box_dir}/bin/yq"
|
||||
[ -x "${yq}" ] || yq="yq"
|
||||
if ! command -v "${yq}" >/dev/null 2>&1 && [ ! -x "${yq}" ]; then
|
||||
log Warning "[wgobfs] yq missing — cannot patch WireGuard endpoint"
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Ensure we have at least one wireguard endpoint
|
||||
if ! "${yq}" -e '.endpoints[] | select(.type == "wireguard")' "${sing_config}" >/dev/null 2>&1; then
|
||||
log Warning "[wgobfs] no wireguard endpoint in ${sing_config}"
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Stash real address/port once, then point peers at local obfuscator
|
||||
"${yq}" -i -o=json '
|
||||
(.endpoints[] | select(.type == "wireguard") | .peers[] |
|
||||
select(._veilbox_real_address == null) |
|
||||
._veilbox_real_address) = .address |
|
||||
(.endpoints[] | select(.type == "wireguard") | .peers[] |
|
||||
select(._veilbox_real_port == null) |
|
||||
._veilbox_real_port) = .port |
|
||||
(.endpoints[] | select(.type == "wireguard") | .peers[] | .address) = "127.0.0.1" |
|
||||
(.endpoints[] | select(.type == "wireguard") | .peers[] | .port) = '"${wgobfs_listen_port}"'
|
||||
' "${sing_config}" && \
|
||||
log Info "[wgobfs] WireGuard peers → 127.0.0.1:${wgobfs_listen_port}"
|
||||
|
||||
# Direct route for real WG/obfuscator server IPs (avoid TPROXY loop)
|
||||
real_ips=$("${yq}" -r '
|
||||
.endpoints[]? | select(.type == "wireguard") | .peers[]? |
|
||||
(._veilbox_real_address // empty)
|
||||
' "${sing_config}" 2>/dev/null | sort -u)
|
||||
|
||||
for ip in ${real_ips}; do
|
||||
case "${ip}" in
|
||||
127.*|"" ) continue ;;
|
||||
esac
|
||||
if ! "${yq}" -e ".route.rules[] | select(.ip_cidr[] == \"${ip}/32\")" "${sing_config}" >/dev/null 2>&1; then
|
||||
"${yq}" -i -o=json ".route.rules = [{\"ip_cidr\":[\"${ip}/32\"],\"outbound\":\"direct\"}] + (.route.rules // [])" "${sing_config}" && \
|
||||
log Info "[wgobfs] route direct ${ip}/32"
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
wgobfs_ensure_conf() {
|
||||
mkdir -p "$(dirname "${wgobfs_config}")" "${box_run}"
|
||||
if [ -f "${wgobfs_config}" ]; then
|
||||
return 0
|
||||
fi
|
||||
if [ -f "${box_dir}/sidecar/wg-obfuscator.example.conf" ]; then
|
||||
cp -f "${box_dir}/sidecar/wg-obfuscator.example.conf" "${wgobfs_config}"
|
||||
log Warning "[wgobfs] created ${wgobfs_config} from example — edit key/target"
|
||||
return 0
|
||||
fi
|
||||
log Error "[wgobfs] missing ${wgobfs_config}"
|
||||
return 1
|
||||
}
|
||||
|
||||
wgobfs_start() {
|
||||
if [ "${wgobfs_enable}" != "true" ]; then
|
||||
return 0
|
||||
fi
|
||||
|
||||
if [ ! -x "${wgobfs_bin}" ]; then
|
||||
log Error "[wgobfs] binary not found: ${wgobfs_bin}"
|
||||
log Error "[wgobfs] download linux-arm64 from https://github.com/ClusterM/wg-obfuscator/releases"
|
||||
return 1
|
||||
fi
|
||||
|
||||
wgobfs_ensure_conf || return 1
|
||||
wgobfs_stop
|
||||
|
||||
# Prefer source-if / source-lport from settings if config still has placeholders
|
||||
# Launch with config file (multi-section supported)
|
||||
nohup busybox setuidgid "${box_user_group}" \
|
||||
"${wgobfs_bin}" -c "${wgobfs_config}" >> "${wgobfs_log}" 2>&1 &
|
||||
echo -n "$!" > "${wgobfs_pid}"
|
||||
log Info "[wgobfs] starting pid=$! config=${wgobfs_config}"
|
||||
|
||||
if wgobfs_wait_udp; then
|
||||
log Info "[wgobfs] running (listen see config source-lport, default ${wgobfs_listen_port})"
|
||||
else
|
||||
log Error "[wgobfs] process died — see ${wgobfs_log}"
|
||||
tail -n 15 "${wgobfs_log}" 2>/dev/null | while read -r line; do log Error "[wgobfs] ${line}"; done
|
||||
return 1
|
||||
fi
|
||||
|
||||
wgobfs_patch_singbox
|
||||
return 0
|
||||
}
|
||||
|
||||
wgobfs_status() {
|
||||
echo "wgobfs_enable=${wgobfs_enable}"
|
||||
echo "config=${wgobfs_config}"
|
||||
echo "bin=${wgobfs_bin}"
|
||||
if busybox pidof wg-obfuscator >/dev/null 2>&1; then
|
||||
echo "pid=$(busybox pidof wg-obfuscator)"
|
||||
echo "state=running"
|
||||
else
|
||||
echo "state=stopped"
|
||||
fi
|
||||
[ -f "${wgobfs_log}" ] && tail -n 8 "${wgobfs_log}"
|
||||
}
|
||||
|
||||
case "$1" in
|
||||
start)
|
||||
wgobfs_start
|
||||
;;
|
||||
stop)
|
||||
wgobfs_stop
|
||||
log Info "[wgobfs] stopped"
|
||||
;;
|
||||
patch)
|
||||
wgobfs_patch_singbox
|
||||
;;
|
||||
status)
|
||||
wgobfs_status
|
||||
;;
|
||||
*)
|
||||
echo "usage: $0 {start|stop|patch|status}"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
@@ -102,6 +102,13 @@ name_provide_clash_rules="rules.yaml"
|
||||
clash_provide_rules="${box_dir}/clash/subscription/${name_provide_clash_rules}"
|
||||
|
||||
# Sing configuration
|
||||
# BFR Manager → Manage Profiles lists *.json here. Switchable profiles:
|
||||
# config-trusttunnel.json — final → sidecar-proxy (:10800 TrustTunnel)
|
||||
# config-olcrtc.json — final → olcrtc-proxy (:10801 olcrtc)
|
||||
# config-wg-obfs.json — WireGuard via local wg-obfuscator (:41320)
|
||||
# config-hy2-wg.json — your hysteria/wg base (etc.)
|
||||
# For TT/olcrtc app switching keep sidecar_protocol=both and sidecar_set_final=false
|
||||
# For WG obfuscation set wgobfs_enable=true (needs VPS-side obfuscator)
|
||||
name_sing_config="config.json"
|
||||
sing_config="${box_dir}/sing-box/${name_sing_config}"
|
||||
|
||||
@@ -215,7 +222,7 @@ wifi_ssids_list=("WiFi1" "WiFi-2" "WiFi 3")
|
||||
inotify_log_enabled="true"
|
||||
|
||||
# -----------------------------------------------------------------
|
||||
# BFR Stealth — anti-detection without LSPosed (iptables port-hide)
|
||||
# PronBox stealth — anti-detection without LSPosed (iptables port-hide)
|
||||
# -----------------------------------------------------------------
|
||||
|
||||
# Master switch: enables loopback port-hide for observer apps + API lockdown
|
||||
@@ -241,7 +248,7 @@ stealth_block_quic="false"
|
||||
stealth_forbid_tun="true"
|
||||
|
||||
# Extra ports to hide from external INPUT (space-separated in stealth_extra_ports)
|
||||
stealth_extra_ports=("7890" "7891" "1080" "10808" "2080")
|
||||
stealth_extra_ports=("7890" "7891" "1080" "10808" "2080" "41320")
|
||||
|
||||
# Observer apps — packages that probe for VPN/proxy (see stealth.list.cfg)
|
||||
stealth_config=$(dirname "$settings")/stealth.list.cfg
|
||||
@@ -262,17 +269,36 @@ stealth_packages_list=($(sed -n '/^[^#]/s/^\([^ ]*\.[^ ]*\).*/\1/p' ${stealth_co
|
||||
# -----------------------------------------------------------------
|
||||
|
||||
sidecar_enable="false"
|
||||
# olcrtc | trusttunnel
|
||||
# olcrtc | trusttunnel | both
|
||||
# Use "both" so BFR Manager Manage Profiles can flip TT ↔ olcrtc without CLI
|
||||
sidecar_protocol=""
|
||||
# Local SOCKS port (must match sidecar config socks.port / trusttunnel client)
|
||||
# Local SOCKS port for single-protocol mode (must match sidecar config)
|
||||
sidecar_listen_port="10800"
|
||||
# sing-box outbound tag injected when sidecar_set_final=true
|
||||
# Dual mode ports/tags (sidecar_protocol=both)
|
||||
sidecar_tt_port="10800"
|
||||
sidecar_olc_port="10801"
|
||||
sidecar_olc_tag="olcrtc-proxy"
|
||||
# sing-box outbound tag for TT (primary tag name in configs)
|
||||
sidecar_outbound_tag="sidecar-proxy"
|
||||
# Set route.final to sidecar outbound (sing-box only)
|
||||
sidecar_set_final="true"
|
||||
# true = force route.final to sidecar tag (overrides profile)
|
||||
# false = keep route.final from the selected Manage Profiles config (recommended for TT/olcrtc flip)
|
||||
sidecar_set_final="false"
|
||||
|
||||
sidecar_dir="${box_dir}/sidecar"
|
||||
|
||||
# -----------------------------------------------------------------
|
||||
# WireGuard Obfuscator — https://github.com/ClusterM/wg-obfuscator
|
||||
# Requires matching obfuscator on the VPS (same key). Not a VPN itself.
|
||||
# -----------------------------------------------------------------
|
||||
wgobfs_enable="false"
|
||||
wgobfs_bin="${box_dir}/bin/wg-obfuscator"
|
||||
wgobfs_config="${box_dir}/sidecar/wg-obfuscator.conf"
|
||||
# Local UDP port sing-box WireGuard peers should use (must match source-lport in conf)
|
||||
wgobfs_listen_port="41320"
|
||||
wgobfs_masking="STUN"
|
||||
# When true, rewrite active sing-box WG peer address/port → 127.0.0.1:wgobfs_listen_port
|
||||
wgobfs_patch_config="true"
|
||||
|
||||
notify() {
|
||||
true
|
||||
|
||||
@@ -309,6 +335,6 @@ log() {
|
||||
fi
|
||||
|
||||
if [[ $TOAST ]]; then
|
||||
notify "box_for_root" "${message}"
|
||||
notify "PronBox" "${message}"
|
||||
fi
|
||||
}
|
||||
|
||||
@@ -1,17 +1,22 @@
|
||||
# Copy to /data/adb/box/sidecar/olcrtc.yaml and edit
|
||||
# Docs: https://github.com/openlibrecommunity/olcrtc/blob/master/docs/configuration.md
|
||||
# Docs: https://github.com/openlibrecommunity/olcrtc (docs/settings.md)
|
||||
# Telemost: room.id = numeric conference id (NOT full https://telemost.yandex.ru/j/... URL)
|
||||
|
||||
mode: cnc
|
||||
auth:
|
||||
provider: jitsi
|
||||
provider: telemost
|
||||
room:
|
||||
id: "https://meet.example.org/YOUR_ROOM_ID"
|
||||
id: "YOUR_TELEMOST_NUMERIC_ROOM_ID"
|
||||
crypto:
|
||||
key: "REPLACE_WITH_64_HEX_CHARS_FROM_openssl_rand_hex_32"
|
||||
net:
|
||||
transport: datachannel
|
||||
dns: "8.8.8.8:53"
|
||||
transport: vp8channel
|
||||
dns: "192.168.0.1:53"
|
||||
socks:
|
||||
host: "127.0.0.1"
|
||||
port: 10800
|
||||
# Prefer 10801 when TrustTunnel already uses 10800 (sidecar_protocol=both)
|
||||
port: 10801
|
||||
data: /data/adb/box/run/olcrtc-data
|
||||
vp8:
|
||||
fps: 30
|
||||
batch_size: 64
|
||||
|
||||
28
box/sidecar/wg-obfuscator.example.conf
Normal file
28
box/sidecar/wg-obfuscator.example.conf
Normal file
@@ -0,0 +1,28 @@
|
||||
# VeilBox client — WireGuard Obfuscator (ClusterM)
|
||||
# https://github.com/ClusterM/wg-obfuscator
|
||||
#
|
||||
# CRITICAL: the same `key` must be configured on the VPS obfuscator.
|
||||
# Without a server-side wg-obfuscator this will NOT connect.
|
||||
#
|
||||
# Typical server layout (on VPS):
|
||||
# public UDP 13232 → wg-obfuscator → 127.0.0.1:<real WireGuard ListenPort>
|
||||
# Client target below must point at that public obfuscator host:port.
|
||||
|
||||
[client]
|
||||
# Listen only on loopback (sing-box WireGuard peer connects here)
|
||||
source-if = 127.0.0.1
|
||||
source-lport = 41320
|
||||
|
||||
# Real remote: your VPS wg-obfuscator public endpoint
|
||||
# Example uses the previous raw WG host — after you wrap WG with obfuscator on the VPS,
|
||||
# keep the public host:port here (obfuscator listens where WG used to).
|
||||
target = YOUR_VPS_IP:13232
|
||||
|
||||
# Shared obfuscation key (plain string, same on both sides)
|
||||
key = CHANGE_ME_WG_OBFS_KEY
|
||||
|
||||
# STUN masking helps against DPI that only allows "video call" UDP
|
||||
# AUTO | STUN | NONE
|
||||
masking = STUN
|
||||
|
||||
verbose = INFO
|
||||
14
box/sidecar/wg-obfuscator.server.example.conf
Normal file
14
box/sidecar/wg-obfuscator.server.example.conf
Normal file
@@ -0,0 +1,14 @@
|
||||
# Example VPS (server) config for ClusterM/wg-obfuscator
|
||||
# Install linux binary on the VPS, run as systemd/docker, then point public UDP here.
|
||||
#
|
||||
# 1) Move WireGuard ListenPort from 13232 → e.g. 51820 (localhost only if possible)
|
||||
# 2) Run obfuscator with source-lport=13232, target=127.0.0.1:51820
|
||||
# 3) Client uses target=VPS_IP:13232 and the SAME key
|
||||
|
||||
[server]
|
||||
source-if = 0.0.0.0
|
||||
source-lport = 13232
|
||||
target = 127.0.0.1:51820
|
||||
key = CHANGE_ME_WG_OBFS_KEY
|
||||
masking = AUTO
|
||||
verbose = INFO
|
||||
@@ -1,42 +1,17 @@
|
||||
## 🧱 Sing-box Documentation
|
||||
# PronBox sing-box profiles
|
||||
|
||||
🔹 **Sing-box (Universal Proxy Core by SagerNet)**
|
||||
📚 Official Docs: [sing-box.sagernet.org/configuration](http://sing-box.sagernet.org/configuration)
|
||||
| File | Sidecar | SOCKS / UDP | `route.final` / note |
|
||||
|------|---------|-------------|----------------------|
|
||||
| `config-trusttunnel.json` | TrustTunnel | `127.0.0.1:10800` | `sidecar-proxy` |
|
||||
| `config-olcrtc.json` | olcrtc | `127.0.0.1:10801` | `olcrtc-proxy` |
|
||||
| `config-wg-obfs.json` | wg-obfuscator | UDP `:41320` | WG peers → localhost obfuscator |
|
||||
| `config.stealth.example.json` | — | — | minimal template |
|
||||
|
||||
## ⚙️ Sample Sing-box Configuration (VMess over WS + TLS)
|
||||
These files appear in **BFR Manager → Manage Profiles** (all `*.json` in `/data/adb/box/sing-box/`).
|
||||
|
||||
```json
|
||||
{
|
||||
"log": {
|
||||
"level": "info"
|
||||
},
|
||||
"inbounds": [
|
||||
{
|
||||
"type": "mixed",
|
||||
"listen": "::",
|
||||
"listen_port": 7890
|
||||
}
|
||||
],
|
||||
"outbounds": [
|
||||
{
|
||||
"type": "vmess",
|
||||
"tag": "vmess-ws",
|
||||
"server": "example.com",
|
||||
"server_port": 443,
|
||||
"uuid": "abcdefgh-1234-5678-90ab-cdef12345678",
|
||||
"security": "auto",
|
||||
"transport": {
|
||||
"type": "ws",
|
||||
"path": "/websocket",
|
||||
"headers": {
|
||||
"Host": "example.com"
|
||||
}
|
||||
},
|
||||
"tls": {
|
||||
"enabled": true,
|
||||
"server_name": "example.com",
|
||||
"insecure": true
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
For TT/olcrtc flipping in the app:
|
||||
- `sidecar_protocol="both"` + `sidecar_set_final="false"`
|
||||
|
||||
For WG obfuscation (`config-wg-obfs.json`):
|
||||
- matching [wg-obfuscator](https://github.com/ClusterM/wg-obfuscator) on the VPS with the same `key`
|
||||
- client conf: `/data/adb/box/sidecar/wg-obfuscator.conf`
|
||||
|
||||
215
box/sing-box/config-olcrtc.json
Normal file
215
box/sing-box/config-olcrtc.json
Normal file
@@ -0,0 +1,215 @@
|
||||
{
|
||||
"log": {
|
||||
"level": "info",
|
||||
"timestamp": true
|
||||
},
|
||||
"dns": {
|
||||
"servers": [
|
||||
{
|
||||
"type": "local",
|
||||
"tag": "dns-direct"
|
||||
},
|
||||
{
|
||||
"type": "https",
|
||||
"tag": "dns-remote",
|
||||
"detour": "olcrtc-proxy",
|
||||
"server": "1.1.1.1",
|
||||
"path": "/dns-query"
|
||||
}
|
||||
],
|
||||
"final": "dns-remote",
|
||||
"strategy": "ipv4_only",
|
||||
"independent_cache": true
|
||||
},
|
||||
"inbounds": [
|
||||
{
|
||||
"type": "tproxy",
|
||||
"tag": "tproxy-in",
|
||||
"listen": "::",
|
||||
"listen_port": 9898
|
||||
},
|
||||
{
|
||||
"type": "mixed",
|
||||
"tag": "mixed-in",
|
||||
"listen": "127.0.0.1",
|
||||
"listen_port": 7890
|
||||
}
|
||||
],
|
||||
"outbounds": [
|
||||
{
|
||||
"type": "hysteria2",
|
||||
"tag": "proxy",
|
||||
"server": "YOUR_SERVER_IP",
|
||||
"server_port": 443,
|
||||
"password": "YOUR_HYSTERIA2_PASSWORD",
|
||||
"tls": {
|
||||
"enabled": true,
|
||||
"server_name": "assets.m1rs3m.org",
|
||||
"alpn": "h3"
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "direct",
|
||||
"tag": "direct"
|
||||
},
|
||||
{
|
||||
"type": "socks",
|
||||
"tag": "sidecar-proxy",
|
||||
"server": "127.0.0.1",
|
||||
"server_port": 10800,
|
||||
"version": "5"
|
||||
},
|
||||
{
|
||||
"type": "socks",
|
||||
"tag": "olcrtc-proxy",
|
||||
"server": "127.0.0.1",
|
||||
"server_port": 10801,
|
||||
"version": "5"
|
||||
}
|
||||
],
|
||||
"route": {
|
||||
"rules": [
|
||||
{
|
||||
"domain_suffix": [
|
||||
"yandex.ru",
|
||||
"yandex.net",
|
||||
"yandex.com",
|
||||
"ya.ru"
|
||||
],
|
||||
"outbound": "direct"
|
||||
},
|
||||
{
|
||||
"ip_cidr": [
|
||||
"1",
|
||||
"3",
|
||||
".",
|
||||
"1",
|
||||
"4",
|
||||
"0",
|
||||
".",
|
||||
"1",
|
||||
"7",
|
||||
".",
|
||||
"1",
|
||||
"6",
|
||||
"3",
|
||||
"/",
|
||||
"3",
|
||||
"2"
|
||||
],
|
||||
"outbound": "direct"
|
||||
},
|
||||
{
|
||||
"ip_cidr": [
|
||||
"1",
|
||||
"3",
|
||||
".",
|
||||
"1",
|
||||
"4",
|
||||
"0",
|
||||
".",
|
||||
"1",
|
||||
"7",
|
||||
".",
|
||||
"1",
|
||||
"6",
|
||||
"3",
|
||||
"/",
|
||||
"3",
|
||||
"2"
|
||||
],
|
||||
"outbound": "direct"
|
||||
},
|
||||
{
|
||||
"ip_cidr": [
|
||||
"1",
|
||||
"3",
|
||||
".",
|
||||
"1",
|
||||
"4",
|
||||
"0",
|
||||
".",
|
||||
"1",
|
||||
"7",
|
||||
".",
|
||||
"1",
|
||||
"6",
|
||||
"3",
|
||||
"/",
|
||||
"3",
|
||||
"2"
|
||||
],
|
||||
"outbound": "direct"
|
||||
},
|
||||
{
|
||||
"action": "sniff"
|
||||
},
|
||||
{
|
||||
"protocol": "dns",
|
||||
"action": "hijack-dns"
|
||||
},
|
||||
{
|
||||
"ip_cidr": [
|
||||
"YOUR_VPS_IP/32",
|
||||
"YOUR_VPS_IP/32"
|
||||
],
|
||||
"outbound": "direct"
|
||||
},
|
||||
{
|
||||
"ip_cidr": [
|
||||
"192.168.0.0/16",
|
||||
"172.16.0.0/12",
|
||||
"127.0.0.0/8",
|
||||
"169.254.0.0/16"
|
||||
],
|
||||
"outbound": "direct"
|
||||
},
|
||||
{
|
||||
"rule_set": "geoip-private",
|
||||
"outbound": "direct"
|
||||
},
|
||||
{
|
||||
"domain_suffix": [
|
||||
".ru",
|
||||
".su",
|
||||
".xn--p1ai"
|
||||
],
|
||||
"outbound": "direct"
|
||||
},
|
||||
{
|
||||
"rule_set": "geosite-category-ru",
|
||||
"outbound": "direct"
|
||||
},
|
||||
{
|
||||
"rule_set": "geoip-ru",
|
||||
"outbound": "direct"
|
||||
}
|
||||
],
|
||||
"rule_set": [
|
||||
{
|
||||
"type": "local",
|
||||
"tag": "geoip-private",
|
||||
"path": "ruleset/geoip-private.srs"
|
||||
},
|
||||
{
|
||||
"type": "local",
|
||||
"tag": "geoip-ru",
|
||||
"path": "ruleset/geoip-ru.srs"
|
||||
},
|
||||
{
|
||||
"type": "local",
|
||||
"tag": "geosite-category-ru",
|
||||
"path": "ruleset/geosite-category-ru.srs"
|
||||
}
|
||||
],
|
||||
"final": "olcrtc-proxy",
|
||||
"auto_detect_interface": false,
|
||||
"default_domain_resolver": "dns-direct"
|
||||
},
|
||||
"experimental": {
|
||||
"cache_file": {
|
||||
"enabled": true,
|
||||
"path": "cache.db"
|
||||
}
|
||||
}
|
||||
}
|
||||
215
box/sing-box/config-trusttunnel.json
Normal file
215
box/sing-box/config-trusttunnel.json
Normal file
@@ -0,0 +1,215 @@
|
||||
{
|
||||
"log": {
|
||||
"level": "info",
|
||||
"timestamp": true
|
||||
},
|
||||
"dns": {
|
||||
"servers": [
|
||||
{
|
||||
"type": "local",
|
||||
"tag": "dns-direct"
|
||||
},
|
||||
{
|
||||
"type": "https",
|
||||
"tag": "dns-remote",
|
||||
"detour": "sidecar-proxy",
|
||||
"server": "1.1.1.1",
|
||||
"path": "/dns-query"
|
||||
}
|
||||
],
|
||||
"final": "dns-remote",
|
||||
"strategy": "ipv4_only",
|
||||
"independent_cache": true
|
||||
},
|
||||
"inbounds": [
|
||||
{
|
||||
"type": "tproxy",
|
||||
"tag": "tproxy-in",
|
||||
"listen": "::",
|
||||
"listen_port": 9898
|
||||
},
|
||||
{
|
||||
"type": "mixed",
|
||||
"tag": "mixed-in",
|
||||
"listen": "127.0.0.1",
|
||||
"listen_port": 7890
|
||||
}
|
||||
],
|
||||
"outbounds": [
|
||||
{
|
||||
"type": "hysteria2",
|
||||
"tag": "proxy",
|
||||
"server": "YOUR_SERVER_IP",
|
||||
"server_port": 443,
|
||||
"password": "YOUR_HYSTERIA2_PASSWORD",
|
||||
"tls": {
|
||||
"enabled": true,
|
||||
"server_name": "assets.m1rs3m.org",
|
||||
"alpn": "h3"
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "direct",
|
||||
"tag": "direct"
|
||||
},
|
||||
{
|
||||
"type": "socks",
|
||||
"tag": "sidecar-proxy",
|
||||
"server": "127.0.0.1",
|
||||
"server_port": 10800,
|
||||
"version": "5"
|
||||
},
|
||||
{
|
||||
"type": "socks",
|
||||
"tag": "olcrtc-proxy",
|
||||
"server": "127.0.0.1",
|
||||
"server_port": 10801,
|
||||
"version": "5"
|
||||
}
|
||||
],
|
||||
"route": {
|
||||
"rules": [
|
||||
{
|
||||
"domain_suffix": [
|
||||
"yandex.ru",
|
||||
"yandex.net",
|
||||
"yandex.com",
|
||||
"ya.ru"
|
||||
],
|
||||
"outbound": "direct"
|
||||
},
|
||||
{
|
||||
"ip_cidr": [
|
||||
"1",
|
||||
"3",
|
||||
".",
|
||||
"1",
|
||||
"4",
|
||||
"0",
|
||||
".",
|
||||
"1",
|
||||
"7",
|
||||
".",
|
||||
"1",
|
||||
"6",
|
||||
"3",
|
||||
"/",
|
||||
"3",
|
||||
"2"
|
||||
],
|
||||
"outbound": "direct"
|
||||
},
|
||||
{
|
||||
"ip_cidr": [
|
||||
"1",
|
||||
"3",
|
||||
".",
|
||||
"1",
|
||||
"4",
|
||||
"0",
|
||||
".",
|
||||
"1",
|
||||
"7",
|
||||
".",
|
||||
"1",
|
||||
"6",
|
||||
"3",
|
||||
"/",
|
||||
"3",
|
||||
"2"
|
||||
],
|
||||
"outbound": "direct"
|
||||
},
|
||||
{
|
||||
"ip_cidr": [
|
||||
"1",
|
||||
"3",
|
||||
".",
|
||||
"1",
|
||||
"4",
|
||||
"0",
|
||||
".",
|
||||
"1",
|
||||
"7",
|
||||
".",
|
||||
"1",
|
||||
"6",
|
||||
"3",
|
||||
"/",
|
||||
"3",
|
||||
"2"
|
||||
],
|
||||
"outbound": "direct"
|
||||
},
|
||||
{
|
||||
"action": "sniff"
|
||||
},
|
||||
{
|
||||
"protocol": "dns",
|
||||
"action": "hijack-dns"
|
||||
},
|
||||
{
|
||||
"ip_cidr": [
|
||||
"YOUR_VPS_IP/32",
|
||||
"YOUR_VPS_IP/32"
|
||||
],
|
||||
"outbound": "direct"
|
||||
},
|
||||
{
|
||||
"ip_cidr": [
|
||||
"192.168.0.0/16",
|
||||
"172.16.0.0/12",
|
||||
"127.0.0.0/8",
|
||||
"169.254.0.0/16"
|
||||
],
|
||||
"outbound": "direct"
|
||||
},
|
||||
{
|
||||
"rule_set": "geoip-private",
|
||||
"outbound": "direct"
|
||||
},
|
||||
{
|
||||
"domain_suffix": [
|
||||
".ru",
|
||||
".su",
|
||||
".xn--p1ai"
|
||||
],
|
||||
"outbound": "direct"
|
||||
},
|
||||
{
|
||||
"rule_set": "geosite-category-ru",
|
||||
"outbound": "direct"
|
||||
},
|
||||
{
|
||||
"rule_set": "geoip-ru",
|
||||
"outbound": "direct"
|
||||
}
|
||||
],
|
||||
"rule_set": [
|
||||
{
|
||||
"type": "local",
|
||||
"tag": "geoip-private",
|
||||
"path": "ruleset/geoip-private.srs"
|
||||
},
|
||||
{
|
||||
"type": "local",
|
||||
"tag": "geoip-ru",
|
||||
"path": "ruleset/geoip-ru.srs"
|
||||
},
|
||||
{
|
||||
"type": "local",
|
||||
"tag": "geosite-category-ru",
|
||||
"path": "ruleset/geosite-category-ru.srs"
|
||||
}
|
||||
],
|
||||
"final": "sidecar-proxy",
|
||||
"auto_detect_interface": false,
|
||||
"default_domain_resolver": "dns-direct"
|
||||
},
|
||||
"experimental": {
|
||||
"cache_file": {
|
||||
"enabled": true,
|
||||
"path": "cache.db"
|
||||
}
|
||||
}
|
||||
}
|
||||
239
box/sing-box/config-wg-obfs.json
Normal file
239
box/sing-box/config-wg-obfs.json
Normal file
@@ -0,0 +1,239 @@
|
||||
{
|
||||
"log": {
|
||||
"level": "info",
|
||||
"timestamp": true
|
||||
},
|
||||
"dns": {
|
||||
"servers": [
|
||||
{
|
||||
"type": "local",
|
||||
"tag": "dns-direct"
|
||||
},
|
||||
{
|
||||
"type": "https",
|
||||
"tag": "dns-remote",
|
||||
"detour": "olcrtc-proxy",
|
||||
"server": "1.1.1.1",
|
||||
"path": "/dns-query"
|
||||
},
|
||||
{
|
||||
"type": "https",
|
||||
"tag": "dns-hy2",
|
||||
"detour": "sidecar-proxy",
|
||||
"server": "1.1.1.1",
|
||||
"path": "/dns-query"
|
||||
}
|
||||
],
|
||||
"final": "dns-remote",
|
||||
"strategy": "ipv4_only",
|
||||
"independent_cache": true
|
||||
},
|
||||
"endpoints": [
|
||||
{
|
||||
"type": "wireguard",
|
||||
"tag": "wg-home",
|
||||
"mtu": 1280,
|
||||
"address": "10.0.10.16/32",
|
||||
"private_key": "YOUR_WIREGUARD_PRIVATE_KEY",
|
||||
"peers": [
|
||||
{
|
||||
"address": "127.0.0.1",
|
||||
"port": 41320,
|
||||
"public_key": "YOUR_PEER_PUBLIC_KEY",
|
||||
"allowed_ips": "10.0.0.0/8",
|
||||
"persistent_keepalive_interval": 25,
|
||||
"_example_real_address": "YOUR_VPS_IP"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"inbounds": [
|
||||
{
|
||||
"type": "tproxy",
|
||||
"tag": "tproxy-in",
|
||||
"listen": "::",
|
||||
"listen_port": 9898
|
||||
},
|
||||
{
|
||||
"type": "mixed",
|
||||
"tag": "mixed-in",
|
||||
"listen": "127.0.0.1",
|
||||
"listen_port": 7890
|
||||
}
|
||||
],
|
||||
"outbounds": [
|
||||
{
|
||||
"type": "hysteria2",
|
||||
"tag": "proxy",
|
||||
"server": "YOUR_SERVER_IP",
|
||||
"server_port": 443,
|
||||
"password": "YOUR_HYSTERIA2_PASSWORD",
|
||||
"tls": {
|
||||
"enabled": true,
|
||||
"server_name": "assets.m1rs3m.org",
|
||||
"alpn": "h3"
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "direct",
|
||||
"tag": "direct"
|
||||
},
|
||||
{
|
||||
"type": "socks",
|
||||
"tag": "sidecar-proxy",
|
||||
"server": "127.0.0.1",
|
||||
"server_port": 10800,
|
||||
"version": "5"
|
||||
},
|
||||
{
|
||||
"type": "socks",
|
||||
"tag": "olcrtc-proxy",
|
||||
"server": "127.0.0.1",
|
||||
"server_port": 10801,
|
||||
"version": "5"
|
||||
}
|
||||
],
|
||||
"route": {
|
||||
"rules": [
|
||||
{
|
||||
"domain_suffix": [
|
||||
"yandex.ru",
|
||||
"yandex.net",
|
||||
"yandex.com",
|
||||
"ya.ru"
|
||||
],
|
||||
"outbound": "direct"
|
||||
},
|
||||
{
|
||||
"ip_cidr": [
|
||||
"1",
|
||||
"3",
|
||||
".",
|
||||
"1",
|
||||
"4",
|
||||
"0",
|
||||
".",
|
||||
"1",
|
||||
"7",
|
||||
".",
|
||||
"1",
|
||||
"6",
|
||||
"3",
|
||||
"/",
|
||||
"3",
|
||||
"2"
|
||||
],
|
||||
"outbound": "direct"
|
||||
},
|
||||
{
|
||||
"ip_cidr": [
|
||||
"1",
|
||||
"3",
|
||||
".",
|
||||
"1",
|
||||
"4",
|
||||
"0",
|
||||
".",
|
||||
"1",
|
||||
"7",
|
||||
".",
|
||||
"1",
|
||||
"6",
|
||||
"3",
|
||||
"/",
|
||||
"3",
|
||||
"2"
|
||||
],
|
||||
"outbound": "direct"
|
||||
},
|
||||
{
|
||||
"ip_cidr": [
|
||||
"1",
|
||||
"3",
|
||||
".",
|
||||
"1",
|
||||
"4",
|
||||
"0",
|
||||
".",
|
||||
"1",
|
||||
"7",
|
||||
".",
|
||||
"1",
|
||||
"6",
|
||||
"3",
|
||||
"/",
|
||||
"3",
|
||||
"2"
|
||||
],
|
||||
"outbound": "direct"
|
||||
},
|
||||
{
|
||||
"action": "sniff"
|
||||
},
|
||||
{
|
||||
"protocol": "dns",
|
||||
"action": "hijack-dns"
|
||||
},
|
||||
{
|
||||
"ip_cidr": [
|
||||
"YOUR_VPS_IP/32"
|
||||
],
|
||||
"outbound": "direct"
|
||||
},
|
||||
{
|
||||
"ip_cidr": [
|
||||
"192.168.0.0/16",
|
||||
"172.16.0.0/12",
|
||||
"127.0.0.0/8",
|
||||
"169.254.0.0/16"
|
||||
],
|
||||
"outbound": "direct"
|
||||
},
|
||||
{
|
||||
"rule_set": "geoip-private",
|
||||
"outbound": "direct"
|
||||
},
|
||||
{
|
||||
"domain_suffix": [
|
||||
".ru",
|
||||
".su",
|
||||
".xn--p1ai"
|
||||
],
|
||||
"outbound": "direct"
|
||||
},
|
||||
{
|
||||
"rule_set": "geosite-category-ru",
|
||||
"outbound": "direct"
|
||||
},
|
||||
{
|
||||
"rule_set": "geoip-ru",
|
||||
"outbound": "direct"
|
||||
}
|
||||
],
|
||||
"rule_set": [
|
||||
{
|
||||
"type": "local",
|
||||
"tag": "geoip-private",
|
||||
"path": "ruleset/geoip-private.srs"
|
||||
},
|
||||
{
|
||||
"type": "local",
|
||||
"tag": "geoip-ru",
|
||||
"path": "ruleset/geoip-ru.srs"
|
||||
},
|
||||
{
|
||||
"type": "local",
|
||||
"tag": "geosite-category-ru",
|
||||
"path": "ruleset/geosite-category-ru.srs"
|
||||
}
|
||||
],
|
||||
"final": "olcrtc-proxy",
|
||||
"default_domain_resolver": "dns-direct"
|
||||
},
|
||||
"experimental": {
|
||||
"cache_file": {
|
||||
"enabled": true,
|
||||
"path": "cache.db"
|
||||
}
|
||||
}
|
||||
}
|
||||
2
build.sh
2
build.sh
@@ -1,4 +1,4 @@
|
||||
#!/bin/sh
|
||||
|
||||
# sed -i "s/$(grep -oP 'version=\K[^ ]+' module.prop)/$(cat module.prop | grep 'version=' | awk -F '=' '{print $2}')($(git log --oneline -n 1 | awk '{print $1}'))/g" module.prop
|
||||
zip -r -o -X -ll box_for_root-$(cat module.prop | grep 'version=' | awk -F '=' '{print $2}').zip ./ -x '.git/*' -x 'CHANGELOG.md' -x 'update.json' -x 'build.sh' -x '.github/*' -x 'docs/*'
|
||||
zip -r -o -X -ll pronbox-$(cat module.prop | grep 'version=' | awk -F '=' '{print $2}').zip ./ -x '.git/*' -x 'CHANGELOG.md' -x 'update.json' -x 'build.sh' -x '.github/*' -x 'docs/*' -x 'tools/*' -x 'phone_configs/*' -x '*.zip'
|
||||
|
||||
24
customize.sh
24
customize.sh
@@ -38,7 +38,7 @@ if [ -d "/data/adb/modules/box_for_magisk" ]; then
|
||||
fi
|
||||
|
||||
# Extract files and configure directories
|
||||
ui_print "— Installing Box for Magisk/KernelSU/APatch"
|
||||
ui_print "— Installing PronBox (НИИ «ТехноПрон»)"
|
||||
unzip -o "$ZIPFILE" -x 'META-INF/*' -x 'webroot/*' -d "$MODPATH" >&2
|
||||
if [ -d "/data/adb/box" ]; then
|
||||
ui_print "— Backup existing box data"
|
||||
@@ -192,7 +192,7 @@ restore_ini() {
|
||||
target_ini="/data/adb/box/settings.ini"
|
||||
|
||||
# List of keys to restore (separate with spaces)
|
||||
keys="network_mode bin_name ipv6 xclash_option renew update_subscription subscription_url_clash subscription_url_singbox name_clash_config clash_config name_provide_clash_config clash_provide_path enable_network_service_control use_module_on_wifi_disconnect use_module_on_wifi use_ssid_matching use_wifi_list_mode wifi_ssids_list inotify_log_enabled stealth_mode stealth_hide_loopback stealth_block_external_api stealth_disable_api stealth_api_bind stealth_api_port stealth_block_quic stealth_forbid_tun sidecar_enable sidecar_protocol sidecar_listen_port sidecar_outbound_tag sidecar_set_final"
|
||||
keys="network_mode bin_name ipv6 xclash_option renew update_subscription subscription_url_clash subscription_url_singbox name_clash_config clash_config name_provide_clash_config clash_provide_path name_sing_config enable_network_service_control use_module_on_wifi_disconnect use_module_on_wifi use_ssid_matching use_wifi_list_mode wifi_ssids_list inotify_log_enabled stealth_mode stealth_hide_loopback stealth_block_external_api stealth_disable_api stealth_api_bind stealth_api_port stealth_block_quic stealth_forbid_tun sidecar_enable sidecar_protocol sidecar_listen_port sidecar_tt_port sidecar_olc_port sidecar_olc_tag sidecar_outbound_tag sidecar_set_final wgobfs_enable wgobfs_listen_port wgobfs_masking wgobfs_patch_config"
|
||||
|
||||
for key in $keys; do
|
||||
value=$(grep "^$key=" "$backup_ini")
|
||||
@@ -264,10 +264,18 @@ if [ "${backup_box}" = "true" ]; then
|
||||
fi
|
||||
}
|
||||
|
||||
for kernel in curl yq xray sing-box v2fly hysteria xclash/mihomo xclash/premium; do
|
||||
for kernel in curl yq xray sing-box v2fly hysteria xclash/mihomo xclash/premium trusttunnel_client olcrtc wg-obfuscator; do
|
||||
restore_kernel "$kernel"
|
||||
done
|
||||
|
||||
# Sidecar configs (TrustTunnel / olcrtc) — not shipped with secrets in ZIP
|
||||
if [ -d "${temp_dir}/sidecar" ]; then
|
||||
ui_print "— Restoring sidecar configs..."
|
||||
mkdir -p /data/adb/box/sidecar
|
||||
cp -rf "${temp_dir}/sidecar/"* "/data/adb/box/sidecar/" 2>/dev/null
|
||||
fi
|
||||
[ -f "${temp_dir}/stealth.list.cfg" ] && cp -f "${temp_dir}/stealth.list.cfg" "/data/adb/box/stealth.list.cfg"
|
||||
|
||||
ui_print "— Restoring..."
|
||||
ui_print " ↳ *.logs"
|
||||
ui_print " ↳ box.pid"
|
||||
@@ -302,14 +310,16 @@ fi
|
||||
# Update module description if no kernel binaries are found
|
||||
[ -z "$(find /data/adb/box/bin -type f)" ] && sed -Ei 's/^description=(\[.*][[:space:]]*)?/description=[ 😱 Module installed but manual Kernel download required ] /g' $MODPATH/module.prop
|
||||
|
||||
# Customize module name based on environment
|
||||
# Keep PronBox branding (do not rewrite to stock "Box for Magisk")
|
||||
if [ "$KSU" = "true" ]; then
|
||||
sed -i "s/name=.*/name=Box for KernelSU/g" $MODPATH/module.prop
|
||||
sed -i "s/^name=.*/name=PronBox (KernelSU)/g" $MODPATH/module.prop
|
||||
elif [ "$APATCH" = "true" ]; then
|
||||
sed -i "s/name=.*/name=Box for APatch/g" $MODPATH/module.prop
|
||||
sed -i "s/^name=.*/name=PronBox (APatch)/g" $MODPATH/module.prop
|
||||
else
|
||||
sed -i "s/name=.*/name=Box for Magisk/g" $MODPATH/module.prop
|
||||
sed -i "s/^name=.*/name=PronBox/g" $MODPATH/module.prop
|
||||
fi
|
||||
# Always pin author to НИИ ТехноПрон
|
||||
sed -i "s/^author=.*/author=команда НИИ «ТехноПрон»/g" $MODPATH/module.prop
|
||||
unzip -o "$ZIPFILE" 'webroot/*' -d "$MODPATH" >&2
|
||||
|
||||
# Clean up temporary files
|
||||
|
||||
10
module.prop
10
module.prop
@@ -1,6 +1,6 @@
|
||||
id=box_for_root
|
||||
name=BFR Stealth Mod
|
||||
version=v1.10.2-stealth.1
|
||||
versionCode=2026081201
|
||||
author=bfr_mod (fork of taamarin)
|
||||
description=Transparent proxy with stealth hardening (no LSPosed), olcrtc/TrustTunnel sidecar, sing-box tproxy. Fork of Box for Root.
|
||||
name=PronBox
|
||||
version=v1.12.0
|
||||
versionCode=2026081301
|
||||
author=команда НИИ «ТехноПрон»
|
||||
description=PronBox — прозрачный TPROXY-прокси из стен НИИ «ТехноПрон». Stealth без LSPosed, TrustTunnel/olcrtc/wg-obfuscator, sing-box. Magisk id: box_for_root.
|
||||
|
||||
11
sbfr
11
sbfr
@@ -15,11 +15,12 @@ fi
|
||||
|
||||
# Help function
|
||||
help() {
|
||||
echo -e "${CYAN}Usage: $0 {start|stop|s <args>|i <args>|u|x|r|t <args>}${RESET}\n"
|
||||
echo -e " ${YELLOW}start${RESET} : Start Box (service and iptables)"
|
||||
echo -e " ${YELLOW}stop${RESET} : Stop Box (iptables and service)"
|
||||
echo -e "${CYAN}Usage: $0 {start|stop|s <args>|i <args>|p <args>|u|x|r|t <args>}${RESET}\n"
|
||||
echo -e " ${YELLOW}start${RESET} : Start PronBox (service and iptables)"
|
||||
echo -e " ${YELLOW}stop${RESET} : Stop PronBox (iptables and service)"
|
||||
echo -e " ${YELLOW}s <args>${RESET} : Run command to box.service with extra arguments"
|
||||
echo -e " ${YELLOW}i <args>${RESET} : Run command to box.iptables with extra arguments"
|
||||
echo -e " ${YELLOW}p <args>${RESET} : Profile switch — list | status | use trusttunnel | use olcrtc"
|
||||
echo -e " ${YELLOW}t <args>${RESET} : Run tools from box.tool with extra arguments"
|
||||
echo -e " ${YELLOW}u${RESET} : API to upgrade core[clash] (POST to /upgrade)"
|
||||
echo -e " ${YELLOW}x${RESET} : API to upgrade Dashboard UI [clash/sing] (POST to /upgrade/ui)"
|
||||
@@ -65,6 +66,10 @@ case "$1" in
|
||||
t)
|
||||
su -c "/data/adb/box/scripts/box.tool $2"
|
||||
;;
|
||||
p|profile)
|
||||
shift
|
||||
su -c "/data/adb/box/scripts/box.profile $*"
|
||||
;;
|
||||
help|-h|--help)
|
||||
help
|
||||
;;
|
||||
|
||||
33
tools/build_olcrtc_arm64.ps1
Normal file
33
tools/build_olcrtc_arm64.ps1
Normal file
@@ -0,0 +1,33 @@
|
||||
# Build olcrtc linux/arm64 static binary for Android Magisk sidecar
|
||||
# Requires: Go 1.26+, git
|
||||
#
|
||||
# Local Android fixes live in tools/src/olcrtc (see tools/patches/olcrtc-android-ca.md):
|
||||
# - load Android CA store for TLS
|
||||
# - prefer IPv4 / no env proxy / no HTTP2 force
|
||||
param(
|
||||
[string]$OutDir = "E:\bfr_mod\tools\binaries",
|
||||
[string]$SrcDir = "E:\bfr_mod\tools\src\olcrtc"
|
||||
)
|
||||
$ErrorActionPreference = "Stop"
|
||||
$env:Path = "C:\Program Files\Go\bin;$env:USERPROFILE\go\bin;" + $env:Path
|
||||
|
||||
if (-not (Test-Path "$SrcDir\.git")) {
|
||||
New-Item -ItemType Directory -Force -Path (Split-Path $SrcDir) | Out-Null
|
||||
git clone --recurse-submodules --depth 1 https://github.com/openlibrecommunity/olcrtc.git $SrcDir
|
||||
Write-Host "NOTE: re-apply Android CA patch from tools/patches/olcrtc-android-ca.md to internal/protect/protect.go"
|
||||
}
|
||||
|
||||
Push-Location $SrcDir
|
||||
try {
|
||||
New-Item -ItemType Directory -Force -Path $OutDir, "build" | Out-Null
|
||||
$env:CGO_ENABLED = "0"
|
||||
$env:GOOS = "linux"
|
||||
$env:GOARCH = "arm64"
|
||||
$out = Join-Path $OutDir "olcrtc-linux-arm64"
|
||||
go build -trimpath -ldflags "-s -w -checklinkname=0" -o $out ./cmd/olcrtc
|
||||
Get-Item $out | Format-List FullName, Length, LastWriteTime
|
||||
Write-Host "Push: adb push $out /data/local/tmp/olcrtc"
|
||||
Write-Host "Install: su -c 'cp /data/local/tmp/olcrtc /data/adb/box/bin/olcrtc && chmod 755 /data/adb/box/bin/olcrtc'"
|
||||
} finally {
|
||||
Pop-Location
|
||||
}
|
||||
93
tools/build_zip.py
Normal file
93
tools/build_zip.py
Normal file
@@ -0,0 +1,93 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Build Magisk ZIP with LF scripts (Android unzip-safe)."""
|
||||
from __future__ import annotations
|
||||
|
||||
import zipfile
|
||||
from pathlib import Path
|
||||
|
||||
ROOT = Path(__file__).resolve().parents[1]
|
||||
EXCLUDE_DIRS = {
|
||||
".git",
|
||||
".github",
|
||||
"docs",
|
||||
"tools",
|
||||
"phone_configs",
|
||||
"__pycache__",
|
||||
}
|
||||
EXCLUDE_FILES = {
|
||||
"CHANGELOG.md",
|
||||
"update.json",
|
||||
"build.sh",
|
||||
".gitignore",
|
||||
"RELEASE.md",
|
||||
}
|
||||
EXCLUDE_GLOBS_SUFFIX = (".zip", ".pyc", ".lf", ".tar.gz", ".bak")
|
||||
|
||||
|
||||
def version() -> str:
|
||||
for line in (ROOT / "module.prop").read_text(encoding="utf-8").splitlines():
|
||||
if line.startswith("version="):
|
||||
return line.split("=", 1)[1].strip()
|
||||
raise SystemExit("version= missing in module.prop")
|
||||
|
||||
|
||||
def should_skip(rel: Path) -> bool:
|
||||
parts = rel.parts
|
||||
if any(p in EXCLUDE_DIRS for p in parts):
|
||||
return True
|
||||
if any(p.startswith("phone_") for p in parts):
|
||||
return True
|
||||
if rel.name in EXCLUDE_FILES:
|
||||
return True
|
||||
if rel.name.endswith(EXCLUDE_GLOBS_SUFFIX):
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
def normalize_bytes(path: Path, data: bytes) -> bytes:
|
||||
# Force LF for shell/scripts installed on Android
|
||||
text_ext = {".sh", ".ini", ".cfg", ".prop", ".md", ".json", ".yaml", ".yml", ".toml", ".example"}
|
||||
name = path.name
|
||||
if (
|
||||
path.suffix.lower() in text_ext
|
||||
or name in {"sbfr", "box.stealth", "box.sidecar", "box.service", "box.iptables", "box.tool", "box.profile", "customize.sh", "uninstall.sh", "box_service.sh", "service.sh", "post-fs-data.sh"}
|
||||
or name.startswith("box.")
|
||||
):
|
||||
try:
|
||||
text = data.decode("utf-8")
|
||||
except UnicodeDecodeError:
|
||||
return data
|
||||
return text.replace("\r\n", "\n").replace("\r", "\n").encode("utf-8")
|
||||
return data
|
||||
|
||||
|
||||
def main() -> None:
|
||||
ver = version()
|
||||
out = ROOT / f"pronbox-{ver}.zip"
|
||||
if out.exists():
|
||||
out.unlink()
|
||||
count = 0
|
||||
with zipfile.ZipFile(out, "w", compression=zipfile.ZIP_DEFLATED) as zf:
|
||||
for path in sorted(ROOT.rglob("*")):
|
||||
if not path.is_file():
|
||||
continue
|
||||
rel = path.relative_to(ROOT)
|
||||
if should_skip(rel):
|
||||
continue
|
||||
data = normalize_bytes(path, path.read_bytes())
|
||||
# Unix paths inside zip
|
||||
arc = rel.as_posix()
|
||||
info = zipfile.ZipInfo(arc)
|
||||
info.compress_type = zipfile.ZIP_DEFLATED
|
||||
info.external_attr = 0o755 << 16 if (
|
||||
path.parent.name == "scripts"
|
||||
or path.name in {"sbfr", "customize.sh", "uninstall.sh", "box_service.sh", "service.sh"}
|
||||
or path.suffix == ".sh"
|
||||
) else (0o644 << 16)
|
||||
zf.writestr(info, data)
|
||||
count += 1
|
||||
print(f"Wrote {out.name} ({count} files, {out.stat().st_size} bytes)")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
13
tools/check_olc_now.sh
Normal file
13
tools/check_olc_now.sh
Normal file
@@ -0,0 +1,13 @@
|
||||
#!/system/bin/sh
|
||||
export PATH="/data/adb/magisk:/data/adb/box/bin:/system/bin:$PATH"
|
||||
. /data/adb/box/settings.ini
|
||||
echo "protocol=$(grep '^sidecar_protocol=' /data/adb/box/settings.ini)"
|
||||
echo "final=$(/data/adb/box/bin/yq -r '.route.final' "$sing_config")"
|
||||
echo "tt=$(pidof trusttunnel_client) olc=$(pidof olcrtc) sb=$(pidof sing-box)"
|
||||
/data/adb/magisk/busybox nc -z 127.0.0.1 10801 && echo 10801_open || echo 10801_closed
|
||||
curl -m 20 -sS -o /dev/null -w "google %{http_code} %{time_total}\n" https://www.google.com/ || true
|
||||
curl -m 15 -sS https://1.1.1.1/cdn-cgi/trace 2>/dev/null | grep -E '^(ip|loc)=' || true
|
||||
echo "=== live olcrtc ==="
|
||||
grep -E 'SOCKS5 server listening|control alive|Shutdown|opened' /data/adb/box/run/sidecar.log 2>/dev/null | tail -8
|
||||
tail -8 /data/adb/box/run/olcrtc.log 2>/dev/null
|
||||
ps -A 2>/dev/null | grep -E 'olcrtc|trusttunnel' || /data/adb/magisk/busybox ps | grep -E 'olcrtc|trusttunnel'
|
||||
18
tools/check_route.sh
Normal file
18
tools/check_route.sh
Normal file
@@ -0,0 +1,18 @@
|
||||
#!/system/bin/sh
|
||||
export PATH="/data/adb/magisk:/data/adb/box/bin:/system/bin:$PATH"
|
||||
echo "=== yq ==="
|
||||
ls -la /data/adb/box/bin/yq
|
||||
/data/adb/box/bin/yq --version 2>&1 | head -2
|
||||
echo "=== OUTBOUNDS TAGS ==="
|
||||
/data/adb/box/bin/yq '.outbounds[].tag' /data/adb/box/sing-box/config.json 2>&1
|
||||
echo "=== ROUTE FINAL ==="
|
||||
/data/adb/box/bin/yq '.route.final' /data/adb/box/sing-box/config.json 2>&1
|
||||
echo "=== HAS SIDECAR ==="
|
||||
/data/adb/box/bin/yq '.outbounds[] | select(.tag == "sidecar-proxy")' /data/adb/box/sing-box/config.json 2>&1
|
||||
echo "=== WHICH CONFIG ==="
|
||||
# prepare may use directory
|
||||
ls /data/adb/box/sing-box/*.json
|
||||
echo "=== SYSTEM IP AGAIN ==="
|
||||
curl -m 10 -sS https://1.1.1.1/cdn-cgi/trace | head -5
|
||||
echo "=== SOCKS IP ==="
|
||||
curl -x socks5h://127.0.0.1:10800 -m 10 -sS https://1.1.1.1/cdn-cgi/trace | head -5
|
||||
7
tools/check_scripts.sh
Normal file
7
tools/check_scripts.sh
Normal file
@@ -0,0 +1,7 @@
|
||||
#!/system/bin/sh
|
||||
export PATH="/data/adb/magisk:/data/adb/ksu/bin:/system/bin:$PATH"
|
||||
echo "=== SCRIPTS DIR ==="
|
||||
ls -la /data/adb/box/scripts/ 2>&1 | head -30
|
||||
echo "=== MODULE ==="
|
||||
ls /data/adb/modules/box_for_root/ 2>&1 | head -20
|
||||
cat /data/adb/modules/box_for_root/module.prop 2>&1 | head -8
|
||||
10
tools/debug_exec.sh
Normal file
10
tools/debug_exec.sh
Normal file
@@ -0,0 +1,10 @@
|
||||
#!/system/bin/sh
|
||||
export PATH="/data/adb/magisk:/system/bin:$PATH"
|
||||
file /data/adb/box/scripts/box.service 2>/dev/null || true
|
||||
head -1 /data/adb/box/scripts/box.service | od -An -tx1 | head -2
|
||||
# try execute
|
||||
sh /data/adb/box/scripts/box.service status 2>&1 | head -20
|
||||
echo EXIT=$?
|
||||
# check mount options
|
||||
mount | grep ' /data '
|
||||
ls -la /system/bin/sh
|
||||
64
tools/deploy_olcrtc_both.sh
Normal file
64
tools/deploy_olcrtc_both.sh
Normal file
@@ -0,0 +1,64 @@
|
||||
#!/system/bin/sh
|
||||
set -e
|
||||
export PATH="/data/adb/magisk:/data/adb/box/bin:/system/bin:$PATH"
|
||||
|
||||
# Install updated sidecar script if staged
|
||||
if [ -f /data/local/tmp/box.sidecar ]; then
|
||||
cp /data/local/tmp/box.sidecar /data/adb/box/scripts/box.sidecar
|
||||
chmod 755 /data/adb/box/scripts/box.sidecar
|
||||
fi
|
||||
|
||||
# Ensure olcrtc binary
|
||||
chmod 755 /data/adb/box/bin/olcrtc 2>/dev/null || true
|
||||
mkdir -p /data/adb/box/run/olcrtc-data
|
||||
|
||||
# Enable dual sidecar on device settings (preserve other keys)
|
||||
INI=/data/adb/box/settings.ini
|
||||
grep -q 'sidecar_tt_port=' "$INI" || cat >> "$INI" <<'EOF'
|
||||
|
||||
# Dual sidecar ports (added by deploy)
|
||||
sidecar_tt_port="10800"
|
||||
sidecar_olc_port="10801"
|
||||
sidecar_olc_tag="olcrtc-proxy"
|
||||
EOF
|
||||
|
||||
# Flip protocol to both (sed-safe)
|
||||
sed -i 's/^sidecar_enable=.*/sidecar_enable="true"/' "$INI"
|
||||
sed -i 's/^sidecar_protocol=.*/sidecar_protocol="both"/' "$INI"
|
||||
sed -i 's/^sidecar_listen_port=.*/sidecar_listen_port="10800"/' "$INI"
|
||||
grep -q '^sidecar_set_final=' "$INI" || echo 'sidecar_set_final="true"' >> "$INI"
|
||||
|
||||
# Add RKNHardering to stealth observer list
|
||||
STEALTH=/data/adb/box/stealth.list.cfg
|
||||
touch "$STEALTH"
|
||||
pkg=$(pm list packages | sed -n 's/^package://p' | grep -iE 'rknharden|notcvnt|rkn' | head -1)
|
||||
echo "detected_rkn_pkg=${pkg}"
|
||||
if [ -n "$pkg" ] && ! grep -qxF "$pkg" "$STEALTH" 2>/dev/null; then
|
||||
echo "$pkg" >> "$STEALTH"
|
||||
echo "added to stealth.list.cfg"
|
||||
fi
|
||||
# known package id from project docs
|
||||
if ! grep -qxF 'com.notcvnt.rknhardering' "$STEALTH" 2>/dev/null; then
|
||||
echo 'com.notcvnt.rknhardering' >> "$STEALTH"
|
||||
fi
|
||||
|
||||
echo "=== settings sidecar ==="
|
||||
grep -E '^sidecar_' "$INI"
|
||||
echo "=== stealth list ==="
|
||||
cat "$STEALTH"
|
||||
echo "=== restart ==="
|
||||
sh /data/adb/box/scripts/box.service restart
|
||||
sleep 5
|
||||
echo "tt=$(pidof trusttunnel_client) olc=$(pidof olcrtc) sb=$(pidof sing-box)"
|
||||
sh /data/adb/box/scripts/box.sidecar status || true
|
||||
echo "=== ports ==="
|
||||
busybox nc -z 127.0.0.1 10800 && echo 10800_open || echo 10800_closed
|
||||
busybox nc -z 127.0.0.1 10801 && echo 10801_open || echo 10801_closed
|
||||
echo "=== olcrtc log tail ==="
|
||||
tail -30 /data/adb/box/run/sidecar.log
|
||||
echo "=== connectivity via TT final ==="
|
||||
curl -m 15 -sS -o /dev/null -w "google %{http_code}\n" https://www.google.com/ || true
|
||||
curl -m 12 -sS https://1.1.1.1/cdn-cgi/trace 2>/dev/null | grep -E '^(ip|loc)=' || true
|
||||
echo "=== socks test olcrtc :10801 ==="
|
||||
curl -x socks5://127.0.0.1:10801 -m 20 -sS -o /dev/null -w "olc_ipgoogle %{http_code} %{time_total}\n" https://1.1.1.1/cdn-cgi/trace || true
|
||||
curl -x socks5h://127.0.0.1:10801 -m 25 -sS -o /dev/null -w "olc_google %{http_code} %{time_total}\n" https://www.google.com/ || true
|
||||
28
tools/diag_routing.sh
Normal file
28
tools/diag_routing.sh
Normal file
@@ -0,0 +1,28 @@
|
||||
#!/system/bin/sh
|
||||
export PATH="/data/adb/magisk:/data/adb/box/bin:/system/bin:$PATH"
|
||||
YQ=/data/adb/box/bin/yq
|
||||
CFG=/data/adb/box/sing-box/config.json
|
||||
|
||||
echo "=== ROUTE FINAL ==="
|
||||
$YQ '.route.final' "$CFG"
|
||||
echo "=== ROUTE RULES ==="
|
||||
$YQ '.route.rules' "$CFG"
|
||||
echo "=== DNS ==="
|
||||
$YQ '.dns' "$CFG"
|
||||
echo "=== OUTBOUNDS ==="
|
||||
$YQ '.outbounds[] | {"tag":.tag,"type":.type}' "$CFG"
|
||||
echo "=== IP RULES ==="
|
||||
ip rule list 2>/dev/null | head -30
|
||||
echo "=== IPTABLES MANGLE BOX ==="
|
||||
iptables -t mangle -S 2>/dev/null | grep -iE 'BOX|TPROXY|9898|mark' | head -40
|
||||
echo "=== TEST RU ==="
|
||||
curl -m 10 -sS -o /dev/null -w "yandex:%{http_code} ip=" https://ya.ru/ 2>&1
|
||||
curl -m 10 -sS https://api.ipify.org?format=text 2>&1; echo
|
||||
echo "=== TEST FOREIGN ==="
|
||||
curl -m 12 -sS -o /dev/null -w "google:%{http_code}\n" https://www.google.com/ 2>&1
|
||||
curl -m 12 -sS -o /dev/null -w "cf:%{http_code}\n" https://1.1.1.1/cdn-cgi/trace 2>&1
|
||||
curl -m 12 -sS https://1.1.1.1/cdn-cgi/trace 2>&1 | head -5
|
||||
echo "=== SING-BOX RECENT ERRORS ==="
|
||||
grep -iE 'ERROR|FATAL|reject|closed' /data/adb/box/run/sing-box.log 2>/dev/null | tail -25
|
||||
echo "=== SIDECAR RECENT ==="
|
||||
grep -iE 'ERROR|DISCONNECTED|CONNECTED|Failed' /data/adb/box/run/sidecar.log 2>/dev/null | tail -15
|
||||
16
tools/diag_tt.sh
Normal file
16
tools/diag_tt.sh
Normal file
@@ -0,0 +1,16 @@
|
||||
#!/system/bin/sh
|
||||
export PATH="/data/adb/magisk:/data/adb/ksu/bin:/data/adb/ap/bin:/system/bin:$PATH"
|
||||
echo "=== PROCESS ==="
|
||||
pidof trusttunnel_client || echo "NOT_RUNNING"
|
||||
ps -A 2>/dev/null | grep -i trust || true
|
||||
echo "=== PORT 10800 ==="
|
||||
grep -E ':2A30 ' /proc/net/tcp /proc/net/tcp6 2>/dev/null || echo "NOT_LISTENING"
|
||||
echo "=== LAST LOG ==="
|
||||
tail -n 40 /data/adb/box/run/sidecar.log 2>/dev/null || echo "NO_LOG"
|
||||
echo "=== SOCKS TEST ==="
|
||||
curl -x socks5h://127.0.0.1:10800 -m 12 -sS https://1.1.1.1/cdn-cgi/trace 2>&1 | head -8
|
||||
echo "CURL_EXIT=$?"
|
||||
echo "=== DIRECT TEST ==="
|
||||
curl -m 8 -sS https://1.1.1.1/cdn-cgi/trace 2>&1 | head -5
|
||||
echo "=== BOX ==="
|
||||
pidof sing-box || echo "sing-box not running"
|
||||
12
tools/dns_deep.sh
Normal file
12
tools/dns_deep.sh
Normal file
@@ -0,0 +1,12 @@
|
||||
#!/system/bin/sh
|
||||
export PATH="/data/adb/magisk:/data/adb/box/bin:/system/bin:$PATH"
|
||||
echo "tt=$(pidof trusttunnel_client) sb=$(pidof sing-box)"
|
||||
echo "=== socks doh via curl ==="
|
||||
# resolve via DoH manually through socks
|
||||
curl -x socks5h://127.0.0.1:10800 -m 10 -sS 'https://1.1.1.1/dns-query?name=www.google.com&type=A' -H 'accept: application/dns-json' 2>&1 | head -c 400; echo
|
||||
echo "=== system google ==="
|
||||
curl -m 15 -v https://www.google.com/ -o /dev/null 2>&1 | tail -20
|
||||
echo "=== recent dns errors ==="
|
||||
grep -i 'dns: exchange failed' /data/adb/box/run/sing-box.log | tail -10
|
||||
echo "=== config dns ==="
|
||||
/data/adb/box/bin/yq '.dns' /data/adb/box/sing-box/config.json
|
||||
14
tools/dns_ipt.sh
Normal file
14
tools/dns_ipt.sh
Normal file
@@ -0,0 +1,14 @@
|
||||
#!/system/bin/sh
|
||||
export PATH="/data/adb/magisk:/data/adb/box/bin:/system/bin:$PATH"
|
||||
echo "=== mangle local/tproxy ==="
|
||||
iptables -t mangle -S 2>/dev/null | grep -E '127\.0\.0\.1|RETURN|MARK|TPROXY|10800|BOX' | head -50
|
||||
echo "=== filter related ==="
|
||||
iptables -t nat -S 2>/dev/null | grep -E '127\.0\.0\.1|10800|RED|BOX' | head -30
|
||||
echo "=== ip rule ==="
|
||||
ip rule | head -20
|
||||
echo "=== outbounds ==="
|
||||
yq -o=json '.outbounds[] | {"tag":.tag,"type":.type,"server":.server,"server_port":.server_port}' /data/adb/box/sing-box/config.json
|
||||
echo "=== route final ==="
|
||||
yq -o=json '.route | {"final":.final,"rules_count":(.rules|length)}' /data/adb/box/sing-box/config.json
|
||||
echo "=== last google dns log ==="
|
||||
grep -i 'www.google.com' /data/adb/box/run/sing-box.log | tail -15
|
||||
33
tools/dns_probe2.sh
Normal file
33
tools/dns_probe2.sh
Normal file
@@ -0,0 +1,33 @@
|
||||
#!/system/bin/sh
|
||||
export PATH="/data/adb/magisk:/data/adb/box/bin:/system/bin:$PATH"
|
||||
echo "=== raw udp53 from root (will be hijacked) ==="
|
||||
# use busybox nslookup if available
|
||||
busybox nslookup google.com 77.88.8.8 2>&1 | head -20 || true
|
||||
echo "=== udp53 via sing-box owner? test with nc ==="
|
||||
# Direct connect test: can we reach DNS/UDP and TT socks
|
||||
echo | busybox nc -w 2 -u 77.88.8.8 53; echo "nc_udp_exit=$?"
|
||||
echo "=== socks connect test ==="
|
||||
curl -x socks5h://127.0.0.1:10800 -m 8 -sS -o /dev/null -w "socks_google %{http_code} %{time_total}\n" https://www.google.com/ || true
|
||||
curl -x socks5://127.0.0.1:10800 -m 8 -sS -o /dev/null -w "socks_ipgoogle %{http_code} %{time_total}\n" https://142.251.150.119/ --resolve www.google.com:443:142.251.150.119 || true
|
||||
echo "=== tt log ==="
|
||||
tail -30 /data/adb/box/run/sidecar.log 2>/dev/null || tail -30 /data/adb/box/run/trusttunnel*.log 2>/dev/null || ls -la /data/adb/box/run/
|
||||
echo "=== try dns detour=direct DoH ==="
|
||||
CFG=/data/adb/box/sing-box/config.json
|
||||
yq -i -o=json '(.dns.servers[] | select(.tag=="dns-remote") | .detour) = "direct"' "$CFG"
|
||||
# also add pure tcp dns via sidecar as dns-tcp
|
||||
yq -i -o=json '
|
||||
.dns.servers += [{"type":"tcp","tag":"dns-tcp-socks","detour":"sidecar-proxy","server":"1.1.1.1"}] |
|
||||
.dns.final = "dns-tcp-socks" |
|
||||
.dns.strategy = "ipv4_only"
|
||||
' "$CFG"
|
||||
kill -HUP "$(pidof sing-box)" 2>/dev/null || true
|
||||
sleep 1
|
||||
# hard restart sing-box only (keep TT)
|
||||
sh /data/adb/box/scripts/box.service restart
|
||||
sleep 4
|
||||
echo "=== dns cfg ==="
|
||||
yq -o=json '.dns' "$CFG"
|
||||
echo "=== test ==="
|
||||
curl -m 15 -sS -o /dev/null -w "google %{http_code} %{time_total}\n" https://www.google.com/ || true
|
||||
curl -m 12 -sS -o /dev/null -w "ya %{http_code} %{time_total}\n" https://ya.ru/ || true
|
||||
grep 'dns: exchange failed' /data/adb/box/run/sing-box.log | tail -8
|
||||
22
tools/export_cfg_shape.sh
Normal file
22
tools/export_cfg_shape.sh
Normal file
@@ -0,0 +1,22 @@
|
||||
#!/system/bin/sh
|
||||
export PATH="/data/adb/magisk:/data/adb/box/bin:/system/bin:$PATH"
|
||||
. /data/adb/box/settings.ini
|
||||
CFG="$sing_config"
|
||||
echo "CFG=$CFG"
|
||||
echo "=== files ==="
|
||||
ls -la /data/adb/box/sing-box/
|
||||
echo "=== settings sidecar ==="
|
||||
grep -E 'name_sing|sidecar_|bin_name' /data/adb/box/settings.ini
|
||||
echo "=== dump redacted ==="
|
||||
# redact passwords/keys from json for template base
|
||||
yq -o=json '
|
||||
(.outbounds[] | select(has("password")) | .password) = "REDACTED" |
|
||||
(.outbounds[] | select(has("uuid")) | .uuid) = "REDACTED" |
|
||||
(.outbounds[] | select(.tls.server_name != null) | .tls.server_name) = .tls.server_name
|
||||
' "$CFG" 2>/dev/null | head -c 8000
|
||||
echo
|
||||
echo "=== route/dns/outbounds summary ==="
|
||||
yq -r '"final=" + .route.final' "$CFG"
|
||||
yq -r '.dns.servers[] | "dns:" + .tag + " type=" + .type + " detour=" + (.detour // "-")' "$CFG"
|
||||
yq -r '.outbounds[] | "out:" + .tag + " type=" + .type + " port=" + ((.server_port // 0)|tostring)' "$CFG"
|
||||
yq -r '.route.rules[] | "rule_out=" + (.outbound // .action // "?")' "$CFG" 2>/dev/null | head -20
|
||||
55
tools/fix_active_cfg.sh
Normal file
55
tools/fix_active_cfg.sh
Normal file
@@ -0,0 +1,55 @@
|
||||
#!/system/bin/sh
|
||||
set -e
|
||||
export PATH="/data/adb/magisk:/data/adb/box/bin:/system/bin:$PATH"
|
||||
. /data/adb/box/settings.ini
|
||||
CFG="${sing_config}"
|
||||
YQ=/data/adb/box/bin/yq
|
||||
echo "ACTIVE_CFG=$CFG"
|
||||
cp -f "$CFG" "${CFG}.bak-activedns-$(date +%Y%m%d_%H%M%S)"
|
||||
|
||||
"$YQ" -i -o=json '
|
||||
.dns.servers = [
|
||||
{"type":"https","tag":"dns-remote","detour":"sidecar-proxy","server":"1.1.1.1","path":"/dns-query"},
|
||||
{"type":"https","tag":"dns-hy2","detour":"proxy","server":"1.1.1.1","path":"/dns-query"},
|
||||
{"type":"udp","tag":"dns-direct","detour":"direct","server":"192.168.0.1"}
|
||||
] |
|
||||
.dns.rules = [] |
|
||||
.dns.final = "dns-remote" |
|
||||
.dns.strategy = "ipv4_only" |
|
||||
.dns.independent_cache = true
|
||||
' "$CFG"
|
||||
|
||||
if ! "$YQ" -e '.route.rules[] | select(.ip_cidr[] == "13.140.17.163/32")' "$CFG" >/dev/null 2>&1; then
|
||||
"$YQ" -i -o=json '.route.rules = [{"ip_cidr":["13.140.17.163/32"],"outbound":"direct"}] + .route.rules' "$CFG"
|
||||
fi
|
||||
"$YQ" -i -o=json 'del(.route.rules[] | select(.outbound == "wg-home"))' "$CFG" 2>/dev/null || true
|
||||
|
||||
echo "=== dns pre-start ==="
|
||||
"$YQ" -o=json '.dns' "$CFG"
|
||||
|
||||
# Install updated sidecar script if present
|
||||
if [ -f /data/local/tmp/box.sidecar ]; then
|
||||
cp /data/local/tmp/box.sidecar /data/adb/box/scripts/box.sidecar
|
||||
chmod 755 /data/adb/box/scripts/box.sidecar
|
||||
echo "updated box.sidecar"
|
||||
fi
|
||||
|
||||
sh /data/adb/box/scripts/box.service restart
|
||||
sleep 4
|
||||
|
||||
echo "=== dns post-start (should stay https) ==="
|
||||
"$YQ" -o=json '.dns.servers,.dns.final,.dns.strategy' "$CFG"
|
||||
echo "tt=$(pidof trusttunnel_client) sb=$(pidof sing-box)"
|
||||
echo "cmdline: $(tr '\0' ' ' < /proc/$(pidof sing-box)/cmdline)"
|
||||
|
||||
for h in www.google.com ya.ru github.com 2ip.ru; do
|
||||
echo "=== $h ==="
|
||||
curl -m 18 -sS -o /dev/null -w "%{http_code} %{time_total}\n" "https://$h/" || true
|
||||
sleep 1
|
||||
done
|
||||
echo "=== ip ==="
|
||||
curl -m 12 -sS https://1.1.1.1/cdn-cgi/trace 2>/dev/null | grep -E '^(ip|loc)=' || true
|
||||
echo "=== fails ==="
|
||||
grep 'dns: exchange failed' /data/adb/box/run/sing-box.log | tail -8 || echo none
|
||||
echo "=== doh dials ==="
|
||||
grep -i '1.1.1.1' /data/adb/box/run/sing-box.log | tail -15
|
||||
40
tools/fix_active_cfg2.sh
Normal file
40
tools/fix_active_cfg2.sh
Normal file
@@ -0,0 +1,40 @@
|
||||
#!/system/bin/sh
|
||||
set -e
|
||||
export PATH="/data/adb/magisk:/data/adb/box/bin:/system/bin:$PATH"
|
||||
. /data/adb/box/settings.ini
|
||||
CFG="${sing_config}"
|
||||
YQ=/data/adb/box/bin/yq
|
||||
echo "ACTIVE_CFG=$CFG"
|
||||
|
||||
"$YQ" -i -o=json '
|
||||
.dns.servers = [
|
||||
{"type":"https","tag":"dns-remote","detour":"sidecar-proxy","server":"1.1.1.1","path":"/dns-query"},
|
||||
{"type":"https","tag":"dns-hy2","detour":"proxy","server":"1.1.1.1","path":"/dns-query"}
|
||||
] |
|
||||
.dns.rules = [] |
|
||||
.dns.final = "dns-remote" |
|
||||
.dns.strategy = "ipv4_only" |
|
||||
.dns.independent_cache = true
|
||||
' "$CFG"
|
||||
|
||||
if ! "$YQ" -e '.route.rules[] | select(.ip_cidr[] == "13.140.17.163/32")' "$CFG" >/dev/null 2>&1; then
|
||||
"$YQ" -i -o=json '.route.rules = [{"ip_cidr":["13.140.17.163/32"],"outbound":"direct"}] + .route.rules' "$CFG"
|
||||
fi
|
||||
|
||||
echo "=== dns ==="
|
||||
"$YQ" -o=json '.dns' "$CFG"
|
||||
|
||||
sh /data/adb/box/scripts/box.service restart
|
||||
sleep 4
|
||||
echo "tt=$(pidof trusttunnel_client) sb=$(pidof sing-box)"
|
||||
"$YQ" -o=json '.dns.servers,.dns.final' "$CFG"
|
||||
|
||||
for h in www.google.com ya.ru github.com 2ip.ru; do
|
||||
echo "=== $h ==="
|
||||
curl -m 18 -sS -o /dev/null -w "%{http_code} %{time_total}\n" "https://$h/" || true
|
||||
sleep 1
|
||||
done
|
||||
echo "=== ip ==="
|
||||
curl -m 12 -sS https://1.1.1.1/cdn-cgi/trace 2>/dev/null | grep -E '^(ip|loc)=' || true
|
||||
grep 'dns: exchange failed' /data/adb/box/run/sing-box.log | tail -6 || echo none
|
||||
grep '1.1.1.1' /data/adb/box/run/sing-box.log | tail -12
|
||||
51
tools/fix_active_cfg3.sh
Normal file
51
tools/fix_active_cfg3.sh
Normal file
@@ -0,0 +1,51 @@
|
||||
#!/system/bin/sh
|
||||
set -e
|
||||
export PATH="/data/adb/magisk:/data/adb/box/bin:/system/bin:$PATH"
|
||||
. /data/adb/box/settings.ini
|
||||
CFG="${sing_config}"
|
||||
YQ=/data/adb/box/bin/yq
|
||||
echo "ACTIVE_CFG=$CFG"
|
||||
|
||||
echo "=== refs to dns-direct ==="
|
||||
grep -n 'dns-direct\|domain_resolver' "$CFG" || true
|
||||
"$YQ" -o=json '.. | select(has("domain_resolver"))' "$CFG" 2>/dev/null || true
|
||||
"$YQ" -o=json '.outbounds' "$CFG" | head -c 2000; echo
|
||||
|
||||
# dns-direct as local (no empty direct detour); remote DoH via TT
|
||||
"$YQ" -i -o=json '
|
||||
.dns.servers = [
|
||||
{"type":"local","tag":"dns-direct"},
|
||||
{"type":"https","tag":"dns-remote","detour":"sidecar-proxy","server":"1.1.1.1","path":"/dns-query"},
|
||||
{"type":"https","tag":"dns-hy2","detour":"proxy","server":"1.1.1.1","path":"/dns-query"}
|
||||
] |
|
||||
.dns.rules = [] |
|
||||
.dns.final = "dns-remote" |
|
||||
.dns.strategy = "ipv4_only" |
|
||||
.dns.independent_cache = true
|
||||
' "$CFG"
|
||||
|
||||
if ! "$YQ" -e '.route.rules[] | select(.ip_cidr[] == "13.140.17.163/32")' "$CFG" >/dev/null 2>&1; then
|
||||
"$YQ" -i -o=json '.route.rules = [{"ip_cidr":["13.140.17.163/32"],"outbound":"direct"}] + .route.rules' "$CFG"
|
||||
fi
|
||||
|
||||
echo "=== dns ==="
|
||||
"$YQ" -o=json '.dns' "$CFG"
|
||||
|
||||
sh /data/adb/box/scripts/box.service restart
|
||||
sleep 4
|
||||
echo "tt=$(pidof trusttunnel_client) sb=$(pidof sing-box)"
|
||||
if [ -z "$(pidof sing-box)" ]; then
|
||||
echo "START FAILED"
|
||||
tail -30 /data/adb/box/run/sing-box.log
|
||||
exit 1
|
||||
fi
|
||||
|
||||
for h in www.google.com ya.ru github.com 2ip.ru; do
|
||||
echo "=== $h ==="
|
||||
curl -m 18 -sS -o /dev/null -w "%{http_code} %{time_total}\n" "https://$h/" || true
|
||||
sleep 1
|
||||
done
|
||||
echo "=== ip ==="
|
||||
curl -m 12 -sS https://1.1.1.1/cdn-cgi/trace 2>/dev/null | grep -E '^(ip|loc)=' || true
|
||||
grep 'dns: exchange failed' /data/adb/box/run/sing-box.log | tail -6 || echo none
|
||||
grep 'outbound/socks.*1.1.1.1\|dns-remote\|exchange' /data/adb/box/run/sing-box.log | tail -20
|
||||
43
tools/fix_dns_tcp.sh
Normal file
43
tools/fix_dns_tcp.sh
Normal file
@@ -0,0 +1,43 @@
|
||||
#!/system/bin/sh
|
||||
# Stabilize DNS: all resolution via TCP→SOCKS→1.1.1.1 (UDP53/direct often blocked; HTTPS-DoH via socks flaky)
|
||||
set -e
|
||||
export PATH="/data/adb/magisk:/data/adb/box/bin:/system/bin:$PATH"
|
||||
CFG=/data/adb/box/sing-box/config.json
|
||||
YQ=/data/adb/box/bin/yq
|
||||
TS=$(date +%Y%m%d_%H%M%S)
|
||||
cp -f "$CFG" "/data/adb/box/sing-box/config.json.bak-dnsok-$TS"
|
||||
|
||||
"$YQ" -i -o=json '
|
||||
.dns.servers = [
|
||||
{"type":"tcp","tag":"dns-remote","detour":"sidecar-proxy","server":"1.1.1.1"},
|
||||
{"type":"udp","tag":"dns-direct","detour":"direct","server":"192.168.0.1"},
|
||||
{"type":"https","tag":"dns-doh-yandex","detour":"direct","server":"77.88.8.8","path":"/dns-query"}
|
||||
] |
|
||||
.dns.rules = [] |
|
||||
.dns.final = "dns-remote" |
|
||||
.dns.strategy = "ipv4_only" |
|
||||
.dns.independent_cache = true
|
||||
' "$CFG"
|
||||
|
||||
# Keep TT endpoint direct
|
||||
if ! "$YQ" -e '.route.rules[] | select(.ip_cidr[] == "13.140.17.163/32")' "$CFG" >/dev/null 2>&1; then
|
||||
"$YQ" -i -o=json '.route.rules = [{"ip_cidr":["13.140.17.163/32"],"outbound":"direct"}] + .route.rules' "$CFG"
|
||||
fi
|
||||
"$YQ" -i -o=json 'del(.route.rules[] | select(.outbound == "wg-home"))' "$CFG" 2>/dev/null || true
|
||||
|
||||
echo "=== dns ==="
|
||||
"$YQ" -o=json '.dns' "$CFG"
|
||||
|
||||
# Restart sing-box; sidecar inject will keep dns-remote detour on sidecar
|
||||
sh /data/adb/box/scripts/box.service restart
|
||||
sleep 4
|
||||
|
||||
echo "tt=$(pidof trusttunnel_client) sb=$(pidof sing-box)"
|
||||
for h in www.google.com ya.ru github.com 2ip.ru; do
|
||||
echo "=== $h ==="
|
||||
curl -m 15 -sS -o /dev/null -w "%{http_code} %{time_total}\n" "https://$h/" || true
|
||||
done
|
||||
echo "=== ip ==="
|
||||
curl -m 12 -sS https://1.1.1.1/cdn-cgi/trace 2>/dev/null | grep -E '^(ip|loc)=' || true
|
||||
echo "=== dns fail tail ==="
|
||||
grep 'dns: exchange failed' /data/adb/box/run/sing-box.log | tail -5 || echo none
|
||||
59
tools/fix_dns_tt.sh
Normal file
59
tools/fix_dns_tt.sh
Normal file
@@ -0,0 +1,59 @@
|
||||
#!/system/bin/sh
|
||||
export PATH="/data/adb/magisk:/data/adb/box/bin:/system/bin:$PATH"
|
||||
YQ=/data/adb/box/bin/yq
|
||||
CFG=/data/adb/box/sing-box/config.json
|
||||
|
||||
# backup
|
||||
cp "$CFG" "/data/adb/box/sing-box/config.json.bak.$(date +%H%M%S)"
|
||||
|
||||
# 1) DNS remote must use sidecar-proxy, not old hysteria "proxy"
|
||||
$YQ '(.dns.servers[] | select(.tag == "dns-remote") | .detour) = "sidecar-proxy"' -i --output-format=json "$CFG"
|
||||
|
||||
# 2) ensure dns-direct has no broken detour (use direct)
|
||||
$YQ '(.dns.servers[] | select(.tag == "dns-direct") | .detour) = "direct"' -i --output-format=json "$CFG"
|
||||
$YQ '(.dns.servers[] | select(.tag == "dns-backup-direct") | .detour) = "direct"' -i --output-format=json "$CFG"
|
||||
|
||||
# 3) TT endpoint must bypass proxy (anti-loop)
|
||||
# add 13.140.17.163/32 to first ip_cidr direct rule if missing
|
||||
if ! $YQ '.route.rules[] | select(.outbound == "direct") | .ip_cidr // [] | .[]' "$CFG" | grep -q '13.140.17.163'; then
|
||||
$YQ '(.route.rules[] | select(.outbound == "direct" and (.ip_cidr | type) == "!!seq") | .ip_cidr) += ["13.140.17.163/32"]' -i --output-format=json "$CFG" 2>/dev/null || \
|
||||
$YQ '.route.rules = [{"ip_cidr":["13.140.17.163/32"],"outbound":"direct"}] + .route.rules' -i --output-format=json "$CFG"
|
||||
fi
|
||||
|
||||
# 4) remove broken wg-home rule (outbound missing)
|
||||
$YQ 'del(.route.rules[] | select(.outbound == "wg-home"))' -i --output-format=json "$CFG"
|
||||
|
||||
# 5) final must stay sidecar
|
||||
$YQ '.route.final = "sidecar-proxy"' -i --output-format=json "$CFG"
|
||||
|
||||
# ensure sidecar outbound exists
|
||||
if ! $YQ '.outbounds[] | select(.tag == "sidecar-proxy")' "$CFG" | grep -q .; then
|
||||
$YQ '.outbounds += [{"type":"socks","tag":"sidecar-proxy","server":"127.0.0.1","server_port":10800,"version":"5"}]' -i --output-format=json "$CFG"
|
||||
fi
|
||||
|
||||
echo "=== DNS servers ==="
|
||||
$YQ '.dns.servers' "$CFG"
|
||||
echo "=== route.final ==="
|
||||
$YQ '.route.final' "$CFG"
|
||||
echo "=== direct ip rules (first) ==="
|
||||
$YQ '[.route.rules[] | select(.outbound == "direct" and .ip_cidr)]' "$CFG" | head -40
|
||||
|
||||
# restart stack
|
||||
sh /data/adb/box/scripts/box.iptables disable 2>/dev/null || true
|
||||
sh /data/adb/box/scripts/box.service stop 2>/dev/null || true
|
||||
kill -9 $(pidof trusttunnel_client) 2>/dev/null || true
|
||||
kill -9 $(pidof sing-box) 2>/dev/null || true
|
||||
sleep 2
|
||||
sh /data/adb/box/scripts/box.service start
|
||||
sleep 3
|
||||
sh /data/adb/box/scripts/box.iptables enable
|
||||
sleep 2
|
||||
|
||||
echo "=== PIDS tt=$(pidof trusttunnel_client) sb=$(pidof sing-box) ==="
|
||||
echo "=== DNS TEST google ==="
|
||||
curl -m 15 -sS -o /dev/null -w "google:%{http_code} time:%{time_total}\n" https://www.google.com/ 2>&1
|
||||
echo "=== DNS TEST yandex ==="
|
||||
curl -m 12 -sS -o /dev/null -w "yandex:%{http_code} time:%{time_total}\n" https://ya.ru/ 2>&1
|
||||
echo "=== IP ==="
|
||||
curl -m 12 -sS https://1.1.1.1/cdn-cgi/trace 2>&1 | head -5
|
||||
curl -m 12 -sS https://ifconfig.me/ip 2>&1; echo
|
||||
64
tools/fix_dns_v2.sh
Normal file
64
tools/fix_dns_v2.sh
Normal file
@@ -0,0 +1,64 @@
|
||||
#!/system/bin/sh
|
||||
# Fix DNS for BFR+TrustTunnel: ipv4_only, RU via direct, remote DoH via sidecar
|
||||
set -e
|
||||
export PATH="/data/adb/magisk:/data/adb/box/bin:/system/bin:$PATH"
|
||||
CFG=/data/adb/box/sing-box/config.json
|
||||
YQ=/data/adb/box/bin/yq
|
||||
TS=$(date +%Y%m%d_%H%M%S)
|
||||
cp -f "$CFG" "/data/adb/box/sing-box/config.json.bak-dnsfix-$TS"
|
||||
|
||||
# Rebuild dns block: direct UDP for RU-ish, DoH via sidecar for rest
|
||||
"$YQ" -i -o=json '
|
||||
.dns.servers = [
|
||||
{"type":"udp","tag":"dns-direct","detour":"direct","server":"77.88.8.8"},
|
||||
{"type":"udp","tag":"dns-backup-direct","detour":"direct","server":"8.8.8.8"},
|
||||
{"type":"https","tag":"dns-remote","detour":"sidecar-proxy","server":"1.1.1.1","path":"/dns-query"}
|
||||
] |
|
||||
.dns.rules = [
|
||||
{"rule_set":"geosite-category-ru","server":"dns-direct"},
|
||||
{"domain_suffix":[".ru",".su",".xn--p1ai"],"server":"dns-direct"},
|
||||
{"rule_set":"geoip-ru","server":"dns-direct"}
|
||||
] |
|
||||
.dns.final = "dns-remote" |
|
||||
.dns.strategy = "ipv4_only" |
|
||||
.dns.independent_cache = true
|
||||
' "$CFG"
|
||||
|
||||
# Ensure TT server IP stays direct (anti-loop / keep tunnel up)
|
||||
"$YQ" -i -o=json '
|
||||
(.route.rules[] | select(.ip_cidr == ["13.140.17.163/32"]) | .outbound) = "direct"
|
||||
' "$CFG" 2>/dev/null || true
|
||||
|
||||
# If rule missing, prepend it
|
||||
if ! "$YQ" -e '.route.rules[] | select(.ip_cidr[] == "13.140.17.163/32")' "$CFG" >/dev/null 2>&1; then
|
||||
"$YQ" -i -o=json '
|
||||
.route.rules = [{"ip_cidr":["13.140.17.163/32"],"outbound":"direct"}] + .route.rules
|
||||
' "$CFG"
|
||||
fi
|
||||
|
||||
# Drop dead wg-home rule if present
|
||||
"$YQ" -i -o=json 'del(.route.rules[] | select(.outbound == "wg-home"))' "$CFG" 2>/dev/null || true
|
||||
|
||||
echo "=== dns after ==="
|
||||
"$YQ" -o=json '.dns' "$CFG"
|
||||
|
||||
echo "=== restart stack ==="
|
||||
sh /data/adb/box/scripts/box.service stop || true
|
||||
killall trusttunnel_client 2>/dev/null || true
|
||||
sleep 1
|
||||
sh /data/adb/box/scripts/box.service start
|
||||
sleep 3
|
||||
sh /data/adb/box/scripts/box.iptables renew
|
||||
sleep 2
|
||||
|
||||
echo "tt=$(pidof trusttunnel_client) sb=$(pidof sing-box)"
|
||||
echo "=== google ==="
|
||||
curl -m 20 -sS -o /dev/null -w "%{http_code} %{time_total}\n" https://www.google.com/ || true
|
||||
echo "=== yandex ==="
|
||||
curl -m 15 -sS -o /dev/null -w "%{http_code} %{time_total}\n" https://ya.ru/ || true
|
||||
echo "=== github ==="
|
||||
curl -m 20 -sS -o /dev/null -w "%{http_code} %{time_total}\n" https://github.com/ || true
|
||||
echo "=== ip ==="
|
||||
curl -m 15 -sS https://1.1.1.1/cdn-cgi/trace 2>/dev/null | grep -E '^(ip|loc|colo)=' || true
|
||||
echo "=== dns errs (last) ==="
|
||||
grep -i 'dns: exchange failed' /data/adb/box/run/sing-box.log | tail -5 || true
|
||||
40
tools/fix_doh_debug.sh
Normal file
40
tools/fix_doh_debug.sh
Normal file
@@ -0,0 +1,40 @@
|
||||
#!/system/bin/sh
|
||||
export PATH="/data/adb/magisk:/data/adb/box/bin:/system/bin:$PATH"
|
||||
CFG=/data/adb/box/sing-box/config.json
|
||||
YQ=/data/adb/box/bin/yq
|
||||
|
||||
# Use HTTPS DoH via sidecar (port 443 — TT allows this; TCP/53 often blocked by SOCKS policy)
|
||||
# Also try DoH via legacy hysteria outbound as fallback dns-hy2
|
||||
"$YQ" -i -o=json '
|
||||
.dns.servers = [
|
||||
{"type":"https","tag":"dns-remote","detour":"sidecar-proxy","server":"1.1.1.1","path":"/dns-query"},
|
||||
{"type":"https","tag":"dns-hy2","detour":"proxy","server":"1.1.1.1","path":"/dns-query"},
|
||||
{"type":"udp","tag":"dns-direct","detour":"direct","server":"192.168.0.1"}
|
||||
] |
|
||||
.dns.rules = [] |
|
||||
.dns.final = "dns-remote" |
|
||||
.dns.strategy = "ipv4_only" |
|
||||
.dns.independent_cache = true |
|
||||
.log.level = "debug"
|
||||
' "$CFG"
|
||||
|
||||
# Restart quietly
|
||||
sh /data/adb/box/scripts/box.service restart
|
||||
sleep 5
|
||||
echo "tt=$(pidof trusttunnel_client) sb=$(pidof sing-box)"
|
||||
echo "=== dns cfg ==="
|
||||
"$YQ" -o=json '.dns.servers,.dns.final,.dns.strategy' "$CFG"
|
||||
|
||||
# One hostname at a time with pauses
|
||||
sleep 2
|
||||
echo "=== google ==="
|
||||
curl -m 20 -sS -o /dev/null -w "%{http_code} %{time_total}\n" https://www.google.com/ 2>&1 || true
|
||||
sleep 2
|
||||
echo "=== ya ==="
|
||||
curl -m 15 -sS -o /dev/null -w "%{http_code} %{time_total}\n" https://ya.ru/ 2>&1 || true
|
||||
sleep 2
|
||||
echo "=== github ==="
|
||||
curl -m 15 -sS -o /dev/null -w "%{http_code} %{time_total}\n" https://github.com/ 2>&1 || true
|
||||
|
||||
echo "=== dial/dns debug lines ==="
|
||||
grep -iE 'dns-remote|dns:|sidecar|1\.1\.1\.1|exchange' /data/adb/box/run/sing-box.log | tail -40
|
||||
80
tools/fix_olc_room.sh
Normal file
80
tools/fix_olc_room.sh
Normal file
@@ -0,0 +1,80 @@
|
||||
#!/system/bin/sh
|
||||
set -e
|
||||
export PATH="/data/adb/magisk:/data/adb/box/bin:/system/bin:$PATH"
|
||||
CFG=/data/adb/box/sidecar/olcrtc.yaml
|
||||
cp -f "$CFG" "${CFG}.bak-$(date +%H%M%S)"
|
||||
|
||||
# Normalize telemost room.id: full URL -> trailing numeric id
|
||||
python3 - <<'PY' 2>/dev/null || true
|
||||
import re, pathlib
|
||||
p = pathlib.Path("/data/adb/box/sidecar/olcrtc.yaml")
|
||||
t = p.read_text(encoding="utf-8")
|
||||
m = re.search(r'(room:\s*\n\s*id:\s*")([^"]+)(")', t)
|
||||
if m:
|
||||
rid = m.group(2)
|
||||
num = re.search(r'(\d{8,})', rid)
|
||||
if num and rid != num.group(1):
|
||||
t2 = t[:m.start(2)] + num.group(1) + t[m.end(2):]
|
||||
p.write_text(t2, encoding="utf-8")
|
||||
print("normalized_room_id_len", len(num.group(1)))
|
||||
else:
|
||||
print("room_id_unchanged_len", len(rid))
|
||||
else:
|
||||
print("room_id_not_found")
|
||||
PY
|
||||
|
||||
# Fallback without python: busybox sed extract
|
||||
if ! grep -q 'normalized_room' /proc/self/fd/0 2>/dev/null; then
|
||||
rid=$(sed -n 's/.*id: *"\([^"]*\)".*/\1/p' "$CFG" | head -1)
|
||||
case "$rid" in
|
||||
http*|https*)
|
||||
num=$(echo "$rid" | grep -oE '[0-9]{8,}' | tail -1)
|
||||
if [ -n "$num" ]; then
|
||||
# replace id line
|
||||
sed -i "s|id: \".*\"|id: \"$num\"|" "$CFG"
|
||||
echo "sed_normalized_to_len=${#num}"
|
||||
fi
|
||||
;;
|
||||
*)
|
||||
echo "room_already_plain_len=${#rid}"
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
|
||||
# Prefer RU DNS for telemost bootstrap (8.8.8.8 often blocked)
|
||||
sed -i 's|dns: "8.8.8.8:53"|dns: "77.88.8.8:53"|' "$CFG"
|
||||
|
||||
echo "=== cfg shape ==="
|
||||
grep -E 'provider:|transport:|port:|dns:|id:' "$CFG" | sed -E 's/(id: ").+/\1***"/'
|
||||
|
||||
echo "=== yandex reachability ==="
|
||||
curl -m 12 -sS -o /dev/null -w "cloud-api %{http_code} %{time_total}\n" https://cloud-api.yandex.ru/ || true
|
||||
|
||||
echo "=== restart olcrtc ==="
|
||||
killall olcrtc 2>/dev/null || true
|
||||
mkdir -p /data/adb/box/run/olcrtc-data
|
||||
: > /data/adb/box/run/olcrtc.log
|
||||
nohup busybox setuidgid root:net_admin /data/adb/box/bin/olcrtc "$CFG" >> /data/adb/box/run/olcrtc.log 2>&1 &
|
||||
echo $! > /data/adb/box/run/sidecar-olcrtc.pid
|
||||
echo "pid=$!"
|
||||
i=0
|
||||
while [ $i -lt 90 ]; do
|
||||
if busybox nc -z 127.0.0.1 10801 2>/dev/null; then
|
||||
echo "10801_open after ${i}s"
|
||||
break
|
||||
fi
|
||||
# bail early if process died
|
||||
if ! kill -0 "$(cat /data/adb/box/run/sidecar-olcrtc.pid)" 2>/dev/null; then
|
||||
echo "olcrtc_exited early at ${i}s"
|
||||
break
|
||||
fi
|
||||
sleep 1
|
||||
i=$((i+1))
|
||||
done
|
||||
busybox nc -z 127.0.0.1 10801 && echo OPEN || echo CLOSED
|
||||
echo "=== log ==="
|
||||
tail -50 /data/adb/box/run/olcrtc.log
|
||||
if busybox nc -z 127.0.0.1 10801 2>/dev/null; then
|
||||
echo "=== socks test ==="
|
||||
curl -x socks5://127.0.0.1:10801 -m 30 -sS https://1.1.1.1/cdn-cgi/trace | grep -E '^(ip|loc)=' || true
|
||||
fi
|
||||
58
tools/fix_olc_yq.sh
Normal file
58
tools/fix_olc_yq.sh
Normal file
@@ -0,0 +1,58 @@
|
||||
#!/system/bin/sh
|
||||
export PATH="/data/adb/magisk:/data/adb/box/bin:/system/bin:$PATH"
|
||||
echo "=== raw id line ==="
|
||||
grep -n 'id:' /data/adb/box/sidecar/olcrtc.yaml | head -5
|
||||
echo "=== hexdump id vicinity ==="
|
||||
grep -n 'id:' /data/adb/box/sidecar/olcrtc.yaml | head -1
|
||||
# show exact bytes of id value
|
||||
sed -n '/room:/,/crypto:/p' /data/adb/box/sidecar/olcrtc.yaml | od -c | head -20
|
||||
|
||||
echo "=== force numeric id with yq/python ==="
|
||||
YQ=/data/adb/box/bin/yq
|
||||
if [ -x "$YQ" ]; then
|
||||
old=$("$YQ" -r '.room.id' /data/adb/box/sidecar/olcrtc.yaml)
|
||||
echo "old=$old"
|
||||
num=$(echo "$old" | grep -oE '[0-9]{8,}' | tail -1)
|
||||
echo "num=$num"
|
||||
"$YQ" -i ".room.id = \"$num\"" /data/adb/box/sidecar/olcrtc.yaml
|
||||
"$YQ" -i '.net.dns = "77.88.8.8:53"' /data/adb/box/sidecar/olcrtc.yaml
|
||||
echo "new=$("$YQ" -r '.room.id' /data/adb/box/sidecar/olcrtc.yaml)"
|
||||
fi
|
||||
|
||||
# Clear olcrtc runtime cache
|
||||
rm -rf /data/adb/box/run/olcrtc-data
|
||||
mkdir -p /data/adb/box/run/olcrtc-data
|
||||
|
||||
# Add direct routes for telemost bootstrap if missing
|
||||
CFG=/data/adb/box/sing-box/config-hy2-wg.json
|
||||
"$YQ" -i -o=json '
|
||||
.route.rules = (
|
||||
[{"domain_suffix":["yandex.ru","yandex.net","yandex.com","ya.ru"],"outbound":"direct"}]
|
||||
+ [.route.rules[] | select(.domain_suffix != ["yandex.ru","yandex.net","yandex.com","ya.ru"])]
|
||||
)
|
||||
' "$CFG" 2>/dev/null || true
|
||||
|
||||
# Restart sing-box briefly to apply route, keep TT
|
||||
kill -HUP "$(pidof sing-box)" 2>/dev/null || true
|
||||
sleep 1
|
||||
# soft reload may not reload route; restart service is safer but heavy — kill/start sing-box only
|
||||
# Use full renew
|
||||
sh /data/adb/box/scripts/box.service restart
|
||||
sleep 6
|
||||
|
||||
echo "=== start olcrtc after stack ==="
|
||||
killall olcrtc 2>/dev/null || true
|
||||
: > /data/adb/box/run/olcrtc.log
|
||||
nohup busybox setuidgid root:net_admin /data/adb/box/bin/olcrtc /data/adb/box/sidecar/olcrtc.yaml >> /data/adb/box/run/olcrtc.log 2>&1 &
|
||||
echo $! > /data/adb/box/run/sidecar-olcrtc.pid
|
||||
echo pid=$!
|
||||
i=0
|
||||
while [ $i -lt 75 ]; do
|
||||
if busybox nc -z 127.0.0.1 10801 2>/dev/null; then echo open_at_$i; break; fi
|
||||
if ! kill -0 "$(cat /data/adb/box/run/sidecar-olcrtc.pid)" 2>/dev/null; then echo dead_at_$i; break; fi
|
||||
sleep 1; i=$((i+1))
|
||||
done
|
||||
busybox nc -z 127.0.0.1 10801 && echo OPEN || echo CLOSED
|
||||
tail -30 /data/adb/box/run/olcrtc.log
|
||||
# Show what URL it tried
|
||||
grep -o 'conferences/[^/]*' /data/adb/box/run/olcrtc.log | tail -3
|
||||
33
tools/fix_ru_dns.sh
Normal file
33
tools/fix_ru_dns.sh
Normal file
@@ -0,0 +1,33 @@
|
||||
#!/system/bin/sh
|
||||
export PATH="/data/adb/magisk:/data/adb/box/bin:/system/bin:$PATH"
|
||||
YQ=/data/adb/box/bin/yq
|
||||
CFG=/data/adb/box/sing-box/config.json
|
||||
|
||||
# RU DNS also via sidecar DoH — route rules still send .ru traffic direct after resolve
|
||||
# (old dns-direct to 77.88.8.8 was timing out under tproxy)
|
||||
$YQ '(.dns.rules[] | .server) = "dns-remote"' -i --output-format=json "$CFG"
|
||||
$YQ '.dns.final = "dns-remote"' -i --output-format=json "$CFG"
|
||||
|
||||
echo "DNS rules now:"
|
||||
$YQ '.dns.rules' "$CFG"
|
||||
$YQ '.dns.final' "$CFG"
|
||||
|
||||
# reload sing-box without killing TT if possible
|
||||
kill -15 $(pidof sing-box) 2>/dev/null
|
||||
sleep 1
|
||||
kill -9 $(pidof sing-box) 2>/dev/null
|
||||
sleep 1
|
||||
# start only core
|
||||
sh /data/adb/box/scripts/box.service start
|
||||
sleep 2
|
||||
sh /data/adb/box/scripts/box.iptables renew >/dev/null 2>&1
|
||||
|
||||
echo "tt=$(pidof trusttunnel_client) sb=$(pidof sing-box)"
|
||||
echo "=== google ==="
|
||||
curl -m 12 -sS -o /dev/null -w "%{http_code} %{time_total}\n" https://www.google.com/
|
||||
echo "=== yandex ==="
|
||||
curl -m 12 -sS -o /dev/null -w "%{http_code} %{time_total}\n" https://ya.ru/
|
||||
echo "=== 2ip ==="
|
||||
curl -m 12 -sS -o /dev/null -w "%{http_code} %{time_total}\n" https://2ip.ru/
|
||||
echo "=== ip ==="
|
||||
curl -m 10 -sS https://1.1.1.1/cdn-cgi/trace | head -4
|
||||
53
tools/fix_sidecar_route.sh
Normal file
53
tools/fix_sidecar_route.sh
Normal file
@@ -0,0 +1,53 @@
|
||||
#!/system/bin/sh
|
||||
export PATH="/data/adb/magisk:/data/adb/box/bin:/system/bin:$PATH"
|
||||
YQ=/data/adb/box/bin/yq
|
||||
CFG=/data/adb/box/sing-box/config.json
|
||||
|
||||
echo "Before:"
|
||||
$YQ '.outbounds[].tag' "$CFG"
|
||||
$YQ '.route.final' "$CFG"
|
||||
|
||||
# inject if missing
|
||||
if ! $YQ '.outbounds[] | select(.tag == "sidecar-proxy")' "$CFG" | grep -q .; then
|
||||
$YQ '.outbounds += [{"type":"socks","tag":"sidecar-proxy","server":"127.0.0.1","server_port":10800,"version":"5"}]' -i --output-format=json "$CFG"
|
||||
echo INJECTED
|
||||
else
|
||||
echo ALREADY
|
||||
fi
|
||||
$YQ '.route.final = "sidecar-proxy"' -i --output-format=json "$CFG"
|
||||
|
||||
echo "After:"
|
||||
$YQ '.outbounds[].tag' "$CFG"
|
||||
$YQ '.route.final' "$CFG"
|
||||
$YQ '.outbounds[] | select(.tag == "sidecar-proxy")' "$CFG"
|
||||
|
||||
# restart sing-box only (keep TT)
|
||||
kill -15 $(pidof sing-box) 2>/dev/null
|
||||
sleep 1
|
||||
kill -9 $(pidof sing-box) 2>/dev/null
|
||||
sleep 1
|
||||
|
||||
# ensure TT still up
|
||||
if ! pidof trusttunnel_client >/dev/null; then
|
||||
echo "TT dead, restarting"
|
||||
/data/adb/box/bin/trusttunnel_client -s -c /data/adb/box/sidecar/trusttunnel.toml >> /data/adb/box/run/sidecar.log 2>&1 &
|
||||
sleep 3
|
||||
fi
|
||||
|
||||
# start sing-box with same prepare path
|
||||
sh /data/adb/box/scripts/box.service start
|
||||
sleep 2
|
||||
sh /data/adb/box/scripts/box.iptables renew
|
||||
|
||||
echo "=== PIDS ==="
|
||||
echo "tt=$(pidof trusttunnel_client)"
|
||||
echo "sb=$(pidof sing-box)"
|
||||
|
||||
echo "=== FINAL CHECK IN CONFIG ==="
|
||||
$YQ '.route.final' /data/adb/box/sing-box/config.json
|
||||
$YQ '.outbounds[] | select(.tag == "sidecar-proxy") | .server_port' /data/adb/box/sing-box/config.json
|
||||
|
||||
echo "=== SYSTEM IP (should be TT exit) ==="
|
||||
curl -m 15 -sS https://1.1.1.1/cdn-cgi/trace | head -6
|
||||
echo "=== SOCKS IP ==="
|
||||
curl -x socks5h://127.0.0.1:10800 -m 12 -sS https://1.1.1.1/cdn-cgi/trace | head -6
|
||||
119
tools/gen_bfr_manager_profiles.py
Normal file
119
tools/gen_bfr_manager_profiles.py
Normal file
@@ -0,0 +1,119 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Build BFR Manager–visible profiles (hyphen names) from live config."""
|
||||
from __future__ import annotations
|
||||
|
||||
import copy
|
||||
import json
|
||||
from pathlib import Path
|
||||
|
||||
ROOT = Path(__file__).resolve().parents[1]
|
||||
LIVE = ROOT / "phone_configs" / "live" / "config-hy2-wg.json"
|
||||
OUT_LIVE = ROOT / "phone_configs" / "live"
|
||||
OUT_REPO = ROOT / "box" / "sing-box"
|
||||
|
||||
|
||||
def scrub_for_repo(cfg: dict) -> dict:
|
||||
c = copy.deepcopy(cfg)
|
||||
c.pop("endpoints", None)
|
||||
for o in c.get("outbounds", []):
|
||||
if "password" in o:
|
||||
o["password"] = "YOUR_HYSTERIA2_PASSWORD"
|
||||
if "uuid" in o:
|
||||
o["uuid"] = "YOUR_UUID"
|
||||
return c
|
||||
|
||||
|
||||
def build(live: dict, final: str, *, scrub: bool) -> dict:
|
||||
c = scrub_for_repo(live) if scrub else copy.deepcopy(live)
|
||||
tags = {o.get("tag") for o in c.get("outbounds", [])}
|
||||
extras = [
|
||||
{
|
||||
"type": "socks",
|
||||
"tag": "sidecar-proxy",
|
||||
"server": "127.0.0.1",
|
||||
"server_port": 10800,
|
||||
"version": "5",
|
||||
},
|
||||
{
|
||||
"type": "socks",
|
||||
"tag": "olcrtc-proxy",
|
||||
"server": "127.0.0.1",
|
||||
"server_port": 10801,
|
||||
"version": "5",
|
||||
},
|
||||
]
|
||||
for e in extras:
|
||||
if e["tag"] not in tags:
|
||||
c.setdefault("outbounds", []).append(e)
|
||||
|
||||
rules = []
|
||||
for r in c.get("route", {}).get("rules", []):
|
||||
if r.get("outbound") == "wg-home":
|
||||
continue
|
||||
rules.append(r)
|
||||
if not any("yandex.ru" in (r.get("domain_suffix") or []) for r in rules):
|
||||
rules.insert(
|
||||
0,
|
||||
{
|
||||
"domain_suffix": ["yandex.ru", "yandex.net", "yandex.com", "ya.ru"],
|
||||
"outbound": "direct",
|
||||
},
|
||||
)
|
||||
if not any(
|
||||
(isinstance(r.get("ip_cidr"), list) and "13.140.17.163/32" in r["ip_cidr"])
|
||||
or r.get("ip_cidr") == "13.140.17.163/32"
|
||||
for r in rules
|
||||
):
|
||||
rules.insert(0, {"ip_cidr": ["13.140.17.163/32"], "outbound": "direct"})
|
||||
c.setdefault("route", {})["rules"] = rules
|
||||
c["route"]["final"] = final
|
||||
c["route"]["default_domain_resolver"] = "dns-direct"
|
||||
c["route"]["auto_detect_interface"] = False
|
||||
c["dns"] = {
|
||||
"servers": [
|
||||
{"type": "local", "tag": "dns-direct"},
|
||||
{
|
||||
"type": "https",
|
||||
"tag": "dns-remote",
|
||||
"detour": final,
|
||||
"server": "1.1.1.1",
|
||||
"path": "/dns-query",
|
||||
},
|
||||
],
|
||||
"final": "dns-remote",
|
||||
"strategy": "ipv4_only",
|
||||
"independent_cache": True,
|
||||
}
|
||||
c.setdefault("log", {})["level"] = "info"
|
||||
c["log"]["timestamp"] = True
|
||||
return c
|
||||
|
||||
|
||||
def write(path: Path, cfg: dict) -> None:
|
||||
path.write_text(json.dumps(cfg, indent=2, ensure_ascii=False) + "\n", encoding="utf-8")
|
||||
print(path, path.stat().st_size)
|
||||
|
||||
|
||||
def main() -> None:
|
||||
live = json.loads(LIVE.read_text(encoding="utf-8"))
|
||||
OUT_LIVE.mkdir(parents=True, exist_ok=True)
|
||||
OUT_REPO.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
pairs = [
|
||||
("config-trusttunnel.json", "sidecar-proxy"),
|
||||
("config-olcrtc.json", "olcrtc-proxy"),
|
||||
]
|
||||
for name, final in pairs:
|
||||
write(OUT_LIVE / name, build(live, final, scrub=False))
|
||||
write(OUT_REPO / name, build(live, final, scrub=True))
|
||||
|
||||
# remove old dotted names from module templates if present
|
||||
for old in ("config.trusttunnel.json", "config.olcrtc.json"):
|
||||
p = OUT_REPO / old
|
||||
if p.exists():
|
||||
p.unlink()
|
||||
print("removed", p)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
105
tools/gen_profiles.py
Normal file
105
tools/gen_profiles.py
Normal file
@@ -0,0 +1,105 @@
|
||||
import json
|
||||
import copy
|
||||
from pathlib import Path
|
||||
|
||||
live = json.loads(Path(r"E:\bfr_mod\phone_configs\live\config-hy2-wg.json").read_text(encoding="utf-8"))
|
||||
|
||||
|
||||
def scrub(cfg):
|
||||
c = copy.deepcopy(cfg)
|
||||
# Do not ship WireGuard private keys in the module repo
|
||||
c.pop("endpoints", None)
|
||||
for o in c.get("outbounds", []):
|
||||
if "password" in o:
|
||||
o["password"] = "YOUR_HYSTERIA2_PASSWORD"
|
||||
if "uuid" in o:
|
||||
o["uuid"] = "YOUR_UUID"
|
||||
rules = []
|
||||
seen = set()
|
||||
for r in c.get("route", {}).get("rules", []):
|
||||
key = json.dumps(r, sort_keys=True)
|
||||
if key in seen:
|
||||
continue
|
||||
seen.add(key)
|
||||
if r.get("outbound") == "wg-home":
|
||||
continue
|
||||
rules.append(r)
|
||||
c.setdefault("route", {})["rules"] = rules
|
||||
tags = {o.get("tag") for o in c.get("outbounds", [])}
|
||||
if "sidecar-proxy" not in tags:
|
||||
c["outbounds"].append(
|
||||
{
|
||||
"type": "socks",
|
||||
"tag": "sidecar-proxy",
|
||||
"server": "127.0.0.1",
|
||||
"server_port": 10800,
|
||||
"version": "5",
|
||||
}
|
||||
)
|
||||
if "olcrtc-proxy" not in tags:
|
||||
c["outbounds"].append(
|
||||
{
|
||||
"type": "socks",
|
||||
"tag": "olcrtc-proxy",
|
||||
"server": "127.0.0.1",
|
||||
"server_port": 10801,
|
||||
"version": "5",
|
||||
}
|
||||
)
|
||||
c["dns"] = {
|
||||
"servers": [
|
||||
{"type": "local", "tag": "dns-direct"},
|
||||
{
|
||||
"type": "https",
|
||||
"tag": "dns-remote",
|
||||
"detour": "PLACEHOLDER",
|
||||
"server": "1.1.1.1",
|
||||
"path": "/dns-query",
|
||||
},
|
||||
],
|
||||
"final": "dns-remote",
|
||||
"strategy": "ipv4_only",
|
||||
"independent_cache": True,
|
||||
}
|
||||
c["route"]["default_domain_resolver"] = "dns-direct"
|
||||
c["route"]["auto_detect_interface"] = False
|
||||
return c
|
||||
|
||||
|
||||
def apply_profile(cfg, final_tag):
|
||||
c = scrub(cfg)
|
||||
c["route"]["final"] = final_tag
|
||||
for s in c["dns"]["servers"]:
|
||||
if s.get("tag") == "dns-remote":
|
||||
s["detour"] = final_tag
|
||||
rules = c["route"]["rules"]
|
||||
has_tt = any(
|
||||
r.get("ip_cidr") in ("13.140.17.163/32", ["13.140.17.163/32"]) for r in rules
|
||||
)
|
||||
if not has_tt:
|
||||
rules.insert(0, {"ip_cidr": ["13.140.17.163/32"], "outbound": "direct"})
|
||||
has_ya = any("yandex.ru" in (r.get("domain_suffix") or []) for r in rules)
|
||||
if not has_ya:
|
||||
rules.insert(
|
||||
0,
|
||||
{
|
||||
"domain_suffix": ["yandex.ru", "yandex.net", "yandex.com", "ya.ru"],
|
||||
"outbound": "direct",
|
||||
},
|
||||
)
|
||||
c.setdefault("log", {})["level"] = "info"
|
||||
c["log"]["timestamp"] = True
|
||||
return c
|
||||
|
||||
|
||||
out = Path(r"E:\bfr_mod\box\sing-box")
|
||||
tt = apply_profile(live, "sidecar-proxy")
|
||||
olc = apply_profile(live, "olcrtc-proxy")
|
||||
(out / "config.trusttunnel.json").write_text(
|
||||
json.dumps(tt, indent=2, ensure_ascii=False) + "\n", encoding="utf-8"
|
||||
)
|
||||
(out / "config.olcrtc.json").write_text(
|
||||
json.dumps(olc, indent=2, ensure_ascii=False) + "\n", encoding="utf-8"
|
||||
)
|
||||
print("tt final", tt["route"]["final"])
|
||||
print("olc final", olc["route"]["final"])
|
||||
72
tools/gen_wgobfs_profile.py
Normal file
72
tools/gen_wgobfs_profile.py
Normal file
@@ -0,0 +1,72 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Build config-wg-obfs.json for BFR Manager from live hy2-wg (local secrets stay on device/live dir)."""
|
||||
from __future__ import annotations
|
||||
|
||||
import copy
|
||||
import json
|
||||
from pathlib import Path
|
||||
|
||||
LIVE = Path(r"E:\bfr_mod\phone_configs\live\config-hy2-wg.json")
|
||||
OUT_LIVE = Path(r"E:\bfr_mod\phone_configs\live\config-wg-obfs.json")
|
||||
OUT_REPO = Path(r"E:\bfr_mod\box\sing-box\config-wg-obfs.json")
|
||||
LISTEN = 41320
|
||||
|
||||
|
||||
def scrub(cfg: dict) -> dict:
|
||||
c = copy.deepcopy(cfg)
|
||||
for ep in c.get("endpoints", []) or []:
|
||||
if "private_key" in ep:
|
||||
ep["private_key"] = "YOUR_WIREGUARD_PRIVATE_KEY"
|
||||
for p in ep.get("peers", []) or []:
|
||||
if "public_key" in p:
|
||||
p["public_key"] = "YOUR_PEER_PUBLIC_KEY"
|
||||
# keep structure but scrub host in repo template
|
||||
if p.get("address") and p["address"] != "127.0.0.1":
|
||||
p["_example_real_address"] = p["address"]
|
||||
p["address"] = "127.0.0.1"
|
||||
p["port"] = LISTEN
|
||||
for o in c.get("outbounds", []):
|
||||
if "password" in o:
|
||||
o["password"] = "YOUR_HYSTERIA2_PASSWORD"
|
||||
return c
|
||||
|
||||
|
||||
def make_live(cfg: dict) -> dict:
|
||||
c = copy.deepcopy(cfg)
|
||||
for ep in c.get("endpoints", []) or []:
|
||||
if ep.get("type") != "wireguard":
|
||||
continue
|
||||
for p in ep.get("peers", []) or []:
|
||||
real_addr = p.get("address")
|
||||
real_port = p.get("port")
|
||||
if real_addr and real_addr != "127.0.0.1":
|
||||
p["_veilbox_real_address"] = real_addr
|
||||
p["_veilbox_real_port"] = real_port
|
||||
p["address"] = "127.0.0.1"
|
||||
p["port"] = LISTEN
|
||||
# direct for real server
|
||||
rules = c.setdefault("route", {}).setdefault("rules", [])
|
||||
for ep in c.get("endpoints", []) or []:
|
||||
for p in ep.get("peers", []) or []:
|
||||
rip = p.get("_veilbox_real_address")
|
||||
if rip and rip != "127.0.0.1":
|
||||
cidr = f"{rip}/32"
|
||||
if not any(cidr in (r.get("ip_cidr") or []) for r in rules):
|
||||
rules.insert(0, {"ip_cidr": [cidr], "outbound": "direct"})
|
||||
return c
|
||||
|
||||
|
||||
def main() -> None:
|
||||
if not LIVE.exists():
|
||||
raise SystemExit(f"missing {LIVE}")
|
||||
live = json.loads(LIVE.read_text(encoding="utf-8"))
|
||||
OUT_LIVE.parent.mkdir(parents=True, exist_ok=True)
|
||||
OUT_REPO.parent.mkdir(parents=True, exist_ok=True)
|
||||
OUT_LIVE.write_text(json.dumps(make_live(live), indent=2, ensure_ascii=False) + "\n", encoding="utf-8")
|
||||
OUT_REPO.write_text(json.dumps(scrub(live), indent=2, ensure_ascii=False) + "\n", encoding="utf-8")
|
||||
print("wrote", OUT_LIVE)
|
||||
print("wrote", OUT_REPO)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
41
tools/install_manager_profiles.sh
Normal file
41
tools/install_manager_profiles.sh
Normal file
@@ -0,0 +1,41 @@
|
||||
#!/system/bin/sh
|
||||
# Install BFR Manager profiles + enable both sidecars for UI switching
|
||||
set -e
|
||||
export PATH="/data/adb/magisk:/data/adb/box/bin:/system/bin:$PATH"
|
||||
INI=/data/adb/box/settings.ini
|
||||
SB=/data/adb/box/sing-box
|
||||
SCR=/data/adb/box/scripts
|
||||
|
||||
cp -f /sdcard/Download/config-trusttunnel.json "$SB/config-trusttunnel.json"
|
||||
cp -f /sdcard/Download/config-olcrtc.json "$SB/config-olcrtc.json"
|
||||
cp -f /sdcard/Download/box.sidecar "$SCR/box.sidecar"
|
||||
cp -f /sdcard/Download/box.profile "$SCR/box.profile"
|
||||
sed -i 's/\r$//' "$SCR/box.sidecar" "$SCR/box.profile"
|
||||
chmod 700 "$SCR/box.sidecar" "$SCR/box.profile"
|
||||
|
||||
# BFR Manager flip: both SOCKS up, do not overwrite profile finals
|
||||
sed -i 's/^sidecar_enable=.*/sidecar_enable="true"/' "$INI"
|
||||
sed -i 's/^sidecar_protocol=.*/sidecar_protocol="both"/' "$INI"
|
||||
sed -i 's/^sidecar_set_final=.*/sidecar_set_final="false"/' "$INI"
|
||||
grep -q '^sidecar_tt_port=' "$INI" || echo 'sidecar_tt_port="10800"' >> "$INI"
|
||||
grep -q '^sidecar_olc_port=' "$INI" || echo 'sidecar_olc_port="10801"' >> "$INI"
|
||||
grep -q '^sidecar_olc_tag=' "$INI" || echo 'sidecar_olc_tag="olcrtc-proxy"' >> "$INI"
|
||||
|
||||
# Keep current active if already hy2-wg; user picks TT/olcrtc in app
|
||||
# Optional: leave name_sing_config as-is
|
||||
|
||||
chown root:net_admin "$SB/config-trusttunnel.json" "$SB/config-olcrtc.json" 2>/dev/null || true
|
||||
chmod 644 "$SB/config-trusttunnel.json" "$SB/config-olcrtc.json"
|
||||
|
||||
echo "=== sing-box profiles ==="
|
||||
ls -la "$SB"/config*.json
|
||||
echo "=== sidecar settings ==="
|
||||
grep -E '^name_sing|^sidecar_' "$INI"
|
||||
echo "=== restart ==="
|
||||
/data/adb/box/scripts/box.service restart
|
||||
sleep 3
|
||||
/data/adb/box/scripts/box.iptables renew >/dev/null 2>&1 || true
|
||||
echo "tt=$(pidof trusttunnel_client) olc=$(pidof olcrtc) sb=$(pidof sing-box)"
|
||||
echo "final=$(/data/adb/box/bin/yq -r '.route.final' "$SB/$(grep '^name_sing_config=' "$INI" | cut -d\" -f2)")"
|
||||
busybox nc -z 127.0.0.1 10800 && echo 10800_open || echo 10800_closed
|
||||
busybox nc -z 127.0.0.1 10801 && echo 10801_open || echo 10801_closed
|
||||
67
tools/install_on_device.sh
Normal file
67
tools/install_on_device.sh
Normal file
@@ -0,0 +1,67 @@
|
||||
#!/system/bin/sh
|
||||
set -e
|
||||
ZIP=/sdcard/Download/box_for_root-v1.10.2-stealth.1.zip
|
||||
TMP=/data/local/tmp/bfr_stealth_install
|
||||
rm -rf "$TMP"
|
||||
mkdir -p "$TMP"
|
||||
cd "$TMP"
|
||||
unzip -o "$ZIP" >/dev/null
|
||||
|
||||
MOD=/data/adb/modules/box_for_root
|
||||
mkdir -p "$MOD" "$MOD/system/bin" "$MOD/webroot"
|
||||
cp -f module.prop customize.sh uninstall.sh action.sh "$MOD/"
|
||||
cp -f sbfr "$MOD/system/bin/sbfr"
|
||||
cp -rf webroot/. "$MOD/webroot/" 2>/dev/null || true
|
||||
|
||||
mkdir -p /data/adb/service.d
|
||||
cp -f box_service.sh /data/adb/service.d/box_service.sh
|
||||
chmod 755 /data/adb/service.d/box_service.sh "$MOD/uninstall.sh" "$MOD/system/bin/sbfr"
|
||||
|
||||
mkdir -p /data/adb/box/scripts /data/adb/box/sidecar /data/adb/box/run /data/adb/box/sing-box
|
||||
cp -f box/scripts/* /data/adb/box/scripts/
|
||||
chmod 700 /data/adb/box/scripts/*
|
||||
cp -f box/sidecar/* /data/adb/box/sidecar/ 2>/dev/null || true
|
||||
cp -f box/sing-box/config.stealth.example.json /data/adb/box/sing-box/ 2>/dev/null || true
|
||||
|
||||
if ! grep -q '^stealth_mode=' /data/adb/box/settings.ini; then
|
||||
echo "Appending stealth+sidecar settings"
|
||||
cat >> /data/adb/box/settings.ini <<'EOF'
|
||||
|
||||
# -----------------------------------------------------------------
|
||||
# BFR Stealth — anti-detection without LSPosed (iptables port-hide)
|
||||
# -----------------------------------------------------------------
|
||||
stealth_mode="true"
|
||||
stealth_hide_loopback="true"
|
||||
stealth_block_external_api="true"
|
||||
stealth_disable_api="true"
|
||||
stealth_api_bind="127.0.0.1"
|
||||
stealth_api_port="19090"
|
||||
stealth_block_quic="false"
|
||||
stealth_forbid_tun="true"
|
||||
stealth_extra_ports=("7890" "7891" "1080" "10808" "2080")
|
||||
stealth_config=$(dirname "$settings")/stealth.list.cfg
|
||||
[ -d "${stealth_config}" ] && rm -rf "${stealth_config}"
|
||||
[ ! -f "${stealth_config}" ] && cat > "${stealth_config}"<<'stealth_init'
|
||||
# Apps that scan for localhost proxy / VPN (one package per line)
|
||||
stealth_init
|
||||
stealth_packages_list=($(sed -n '/^[^#]/s/^\([^ ]*\.[^ ]*\).*/\1/p' ${stealth_config}))
|
||||
sidecar_enable="false"
|
||||
sidecar_protocol=""
|
||||
sidecar_listen_port="10800"
|
||||
sidecar_outbound_tag="sidecar-proxy"
|
||||
sidecar_set_final="true"
|
||||
sidecar_dir="${box_dir}/sidecar"
|
||||
EOF
|
||||
fi
|
||||
|
||||
chown -R root:net_admin /data/adb/box
|
||||
chmod 755 /data/adb/box/scripts/*
|
||||
rm -f "$MOD/disable"
|
||||
|
||||
echo INSTALL_OK
|
||||
cat "$MOD/module.prop"
|
||||
ls /data/adb/box/scripts/box.stealth /data/adb/box/scripts/box.sidecar
|
||||
test -f /data/adb/box/sing-box/config.json && echo CONFIG_PRESERVED
|
||||
test -x /data/adb/box/bin/sing-box && echo BIN_PRESERVED || ls /data/adb/box/bin/
|
||||
grep -q '^stealth_mode=' /data/adb/box/settings.ini && echo STEALTH_KEYS_OK
|
||||
rm -rf "$TMP"
|
||||
57
tools/install_wgobfs.sh
Normal file
57
tools/install_wgobfs.sh
Normal file
@@ -0,0 +1,57 @@
|
||||
#!/system/bin/sh
|
||||
set -e
|
||||
export PATH="/data/adb/magisk:/data/adb/box/bin:/system/bin:$PATH"
|
||||
BIN=/data/adb/box/bin
|
||||
SC=/data/adb/box/sidecar
|
||||
SB=/data/adb/box/sing-box
|
||||
SCR=/data/adb/box/scripts
|
||||
|
||||
cp -f /data/local/tmp/wg-obfuscator "$BIN/wg-obfuscator"
|
||||
chmod 755 "$BIN/wg-obfuscator"
|
||||
"$BIN/wg-obfuscator" -V 2>&1 | head -2 || true
|
||||
|
||||
cp -f /data/local/tmp/box.wgobfs "$SCR/box.wgobfs"
|
||||
cp -f /data/local/tmp/box.service "$SCR/box.service"
|
||||
cp -f /data/local/tmp/box.profile "$SCR/box.profile"
|
||||
cp -f /data/local/tmp/box.tool "$SCR/box.tool"
|
||||
sed -i 's/\r$//' "$SCR/box.wgobfs" "$SCR/box.service" "$SCR/box.profile" "$SCR/box.tool"
|
||||
chmod 700 "$SCR/box.wgobfs" "$SCR/box.service" "$SCR/box.profile" "$SCR/box.tool"
|
||||
|
||||
cp -f /data/local/tmp/wg-obfuscator.example.conf "$SC/wg-obfuscator.example.conf"
|
||||
cp -f /data/local/tmp/wg-obfuscator.server.example.conf "$SC/wg-obfuscator.server.example.conf"
|
||||
cp -f /data/local/tmp/config-wg-obfs.json "$SB/config-wg-obfs.json"
|
||||
chown root:net_admin "$SB/config-wg-obfs.json" 2>/dev/null || true
|
||||
chmod 644 "$SB/config-wg-obfs.json"
|
||||
|
||||
# Seed client conf once (do not overwrite existing key)
|
||||
if [ ! -f "$SC/wg-obfuscator.conf" ]; then
|
||||
cat > "$SC/wg-obfuscator.conf" <<'EOF'
|
||||
[client]
|
||||
source-if = 127.0.0.1
|
||||
source-lport = 41320
|
||||
target = 188.120.251.220:13232
|
||||
key = CHANGE_ME_WG_OBFS_KEY
|
||||
masking = STUN
|
||||
verbose = INFO
|
||||
EOF
|
||||
echo "CREATED $SC/wg-obfuscator.conf — set key= to match VPS"
|
||||
else
|
||||
echo "keep existing $SC/wg-obfuscator.conf"
|
||||
fi
|
||||
|
||||
# Ensure settings keys exist (disabled until VPS ready)
|
||||
INI=/data/adb/box/settings.ini
|
||||
grep -q '^wgobfs_enable=' "$INI" || echo 'wgobfs_enable="false"' >> "$INI"
|
||||
grep -q '^wgobfs_listen_port=' "$INI" || echo 'wgobfs_listen_port="41320"' >> "$INI"
|
||||
grep -q '^wgobfs_patch_config=' "$INI" || echo 'wgobfs_patch_config="true"' >> "$INI"
|
||||
grep -q '^wgobfs_config=' "$INI" || echo 'wgobfs_config="${box_dir}/sidecar/wg-obfuscator.conf"' >> "$INI"
|
||||
grep -q '^wgobfs_bin=' "$INI" || echo 'wgobfs_bin="${box_dir}/bin/wg-obfuscator"' >> "$INI"
|
||||
|
||||
echo "=== installed ==="
|
||||
ls -la "$BIN/wg-obfuscator" "$SB/config-wg-obfs.json" "$SC/wg-obfuscator.conf" "$SCR/box.wgobfs"
|
||||
echo
|
||||
echo "NEXT:"
|
||||
echo "1) On VPS: install wg-obfuscator, wrap WG port, SAME key"
|
||||
echo "2) Edit $SC/wg-obfuscator.conf key=..."
|
||||
echo "3) BFR Manager → Manage Profiles → config-wg-obfs.json"
|
||||
echo " (auto-starts wgobfs) OR: sed -i 's/wgobfs_enable=.*/wgobfs_enable=\"true\"/' $INI && box.service restart"
|
||||
20
tools/olc_diag2.sh
Normal file
20
tools/olc_diag2.sh
Normal file
@@ -0,0 +1,20 @@
|
||||
#!/system/bin/sh
|
||||
export PATH="/data/adb/magisk:/data/adb/box/bin:/system/bin:$PATH"
|
||||
URL='https://cloud-api.yandex.ru/telemost_front/v2/telemost/conferences/https%3A%2F%2Ftelemost.yandex.ru%2Fj%2F41001894292350/connection?display_name=test&next_gen_media_platform_allowed=true&waiting_room_supported=true'
|
||||
echo "=== curl as root:net_admin ==="
|
||||
busybox setuidgid root:net_admin curl -m 20 -sS -o /tmp/tm.json -w "%{http_code} %{time_total}\n" \
|
||||
-H 'User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:149.0) Gecko/20100101 Firefox/149.0' \
|
||||
-H 'Accept: */*' \
|
||||
-H 'Origin: https://telemost.yandex.ru' \
|
||||
-H 'Referer: https://telemost.yandex.ru/' \
|
||||
-H 'X-Telemost-Client-Version: 187.1.0' \
|
||||
"$URL" || true
|
||||
head -c 200 /tmp/tm.json; echo
|
||||
|
||||
echo "=== openssl/s_client quick ==="
|
||||
echo | busybox timeout 8 openssl s_client -connect 213.180.204.127:443 -servername cloud-api.yandex.ru 2>&1 | head -20
|
||||
|
||||
echo "=== verify binary has our patch strings ==="
|
||||
strings /data/adb/box/bin/olcrtc | grep -E 'ForceAttempt|Magisk/su|Prefer IPv4' | head
|
||||
# show build id / size
|
||||
ls -la /data/adb/box/bin/olcrtc
|
||||
19
tools/olc_http1.sh
Normal file
19
tools/olc_http1.sh
Normal file
@@ -0,0 +1,19 @@
|
||||
#!/system/bin/sh
|
||||
export PATH="/data/adb/magisk:/data/adb/box/bin:/system/bin:$PATH"
|
||||
CFG=/data/adb/box/sidecar/olcrtc.yaml
|
||||
killall olcrtc 2>/dev/null || true
|
||||
: > /data/adb/box/run/olcrtc.log
|
||||
nohup env \
|
||||
GODEBUG=http2client=0 \
|
||||
-u all_proxy -u ALL_PROXY -u http_proxy -u https_proxy -u HTTP_PROXY -u HTTPS_PROXY \
|
||||
busybox setuidgid root:net_admin /data/adb/box/bin/olcrtc "$CFG" >> /data/adb/box/run/olcrtc.log 2>&1 &
|
||||
echo $! > /data/adb/box/run/sidecar-olcrtc.pid
|
||||
echo pid=$!
|
||||
i=0
|
||||
while [ $i -lt 45 ]; do
|
||||
if busybox nc -z 127.0.0.1 10801 2>/dev/null; then echo OPEN_at_$i; break; fi
|
||||
if ! kill -0 "$(cat /data/adb/box/run/sidecar-olcrtc.pid)" 2>/dev/null; then echo DEAD_at_$i; break; fi
|
||||
sleep 1; i=$((i+1))
|
||||
done
|
||||
busybox nc -z 127.0.0.1 10801 && echo OPEN || echo CLOSED
|
||||
tail -40 /data/adb/box/run/olcrtc.log
|
||||
27
tools/olc_notproxy.sh
Normal file
27
tools/olc_notproxy.sh
Normal file
@@ -0,0 +1,27 @@
|
||||
#!/system/bin/sh
|
||||
export PATH="/data/adb/magisk:/data/adb/box/bin:/system/bin:$PATH"
|
||||
CFG=/data/adb/box/sidecar/olcrtc.yaml
|
||||
killall olcrtc 2>/dev/null || true
|
||||
|
||||
echo "=== disable tproxy temporarily ==="
|
||||
sh /data/adb/box/scripts/box.iptables disable
|
||||
sleep 1
|
||||
|
||||
: > /data/adb/box/run/olcrtc.log
|
||||
nohup env -u all_proxy -u ALL_PROXY -u http_proxy -u https_proxy -u HTTP_PROXY -u HTTPS_PROXY \
|
||||
busybox setuidgid root:net_admin /data/adb/box/bin/olcrtc "$CFG" >> /data/adb/box/run/olcrtc.log 2>&1 &
|
||||
echo $! > /data/adb/box/run/sidecar-olcrtc.pid
|
||||
echo pid=$!
|
||||
i=0
|
||||
while [ $i -lt 45 ]; do
|
||||
if busybox nc -z 127.0.0.1 10801 2>/dev/null; then echo OPEN_at_$i; break; fi
|
||||
if ! kill -0 "$(cat /data/adb/box/run/sidecar-olcrtc.pid)" 2>/dev/null; then echo DEAD_at_$i; break; fi
|
||||
sleep 1; i=$((i+1))
|
||||
done
|
||||
busybox nc -z 127.0.0.1 10801 && echo OPEN || echo CLOSED
|
||||
tail -40 /data/adb/box/run/olcrtc.log
|
||||
|
||||
echo "=== re-enable tproxy ==="
|
||||
sh /data/adb/box/scripts/box.iptables enable
|
||||
sleep 2
|
||||
curl -m 12 -sS -o /dev/null -w "google_after %{http_code}\n" https://www.google.com/ || true
|
||||
14
tools/patches/olcrtc-android-ca.md
Normal file
14
tools/patches/olcrtc-android-ca.md
Normal file
@@ -0,0 +1,14 @@
|
||||
# Local patch applied when building olcrtc for Magisk/Android sidecar
|
||||
#
|
||||
# File: internal/protect/protect.go
|
||||
#
|
||||
# 1) Load Android system CA store into tls.Config.RootCAs
|
||||
# (/system/etc/security/cacerts, /apex/com.android.conscrypt/cacerts)
|
||||
# Static linux/arm64 Go binaries have an empty SystemCertPool on Android.
|
||||
#
|
||||
# 2) Prefer IPv4 dials; disable env HTTP(S)_PROXY / ALL_PROXY; ForceAttemptHTTP2=false
|
||||
#
|
||||
# 3) On device, prefer net.dns = LAN resolver (e.g. 192.168.0.1:53).
|
||||
# PreferGo UDP to 8.8.8.8 / 77.88.8.8 as root:net_admin can hang on some phones.
|
||||
#
|
||||
# Rebuild: powershell -File tools/build_olcrtc_arm64.ps1
|
||||
11
tools/phone_state.sh
Normal file
11
tools/phone_state.sh
Normal file
@@ -0,0 +1,11 @@
|
||||
#!/system/bin/sh
|
||||
uname -m
|
||||
getprop ro.product.cpu.abi
|
||||
echo "=== bin ==="
|
||||
ls -la /data/adb/box/bin/ | head -40
|
||||
echo "=== sidecar ==="
|
||||
ls -la /data/adb/box/sidecar/
|
||||
echo "=== settings sidecar ==="
|
||||
grep -E 'sidecar_|olcrtc|trusttunnel' /data/adb/box/settings.ini
|
||||
echo "=== packages rkn ==="
|
||||
pm list packages 2>/dev/null | grep -iE 'rkn|harden|detect|vpn' || true
|
||||
18
tools/probe_tt3.sh
Normal file
18
tools/probe_tt3.sh
Normal file
@@ -0,0 +1,18 @@
|
||||
#!/system/bin/sh
|
||||
export PATH="/data/adb/magisk:/data/adb/ksu/bin:/data/adb/ap/bin:$PATH"
|
||||
echo "alive=$(pidof trusttunnel_client)"
|
||||
# check listening: port 10800 = 0x2A30 -> little endian in /proc = 302A0000?
|
||||
# actually format is hex IP:PORT where PORT is big-endian hex
|
||||
# 10800 = 0x2A30
|
||||
grep -E ':2A30 ' /proc/net/tcp /proc/net/tcp6 2>/dev/null && echo PORT_10800_LISTEN
|
||||
# try magisk busybox wget/curl
|
||||
which curl; which busybox
|
||||
if command -v curl >/dev/null; then
|
||||
curl -x socks5h://127.0.0.1:10800 -m 20 -sS https://1.1.1.1/cdn-cgi/trace | head -5
|
||||
elif [ -x /data/adb/box/bin/curl ]; then
|
||||
/data/adb/box/bin/curl -x socks5h://127.0.0.1:10800 -m 20 -sS https://1.1.1.1/cdn-cgi/trace | head -5
|
||||
else
|
||||
# minimal SOCKS5 handshake via toybox/dd? skip
|
||||
echo "NO_CURL — checking CONNECTED in log"
|
||||
grep 'Successfully connected' /data/adb/box/run/sidecar.log | tail -3
|
||||
fi
|
||||
12
tools/probe_tt_socks.sh
Normal file
12
tools/probe_tt_socks.sh
Normal file
@@ -0,0 +1,12 @@
|
||||
#!/system/bin/sh
|
||||
echo "alive=$(pidof trusttunnel_client)"
|
||||
# test SOCKS with curl if present
|
||||
CURL=/data/adb/box/bin/curl
|
||||
if [ -x "$CURL" ]; then
|
||||
"$CURL" -x socks5h://127.0.0.1:10800 -m 15 -sS https://ifconfig.me/ip && echo
|
||||
echo CURL_EXIT=$?
|
||||
else
|
||||
echo no_curl
|
||||
fi
|
||||
# show recent connected status
|
||||
grep -E 'Successfully connected|VPN_SS_CONNECTED|Listening on 127.0.0.1:10800|ERROR' /data/adb/box/run/sidecar.log | tail -15
|
||||
139
tools/push_profiles_to_phone.py
Normal file
139
tools/push_profiles_to_phone.py
Normal file
@@ -0,0 +1,139 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Build real (secret-bearing) profiles from phone live config and optional adb push."""
|
||||
from __future__ import annotations
|
||||
|
||||
import argparse
|
||||
import copy
|
||||
import json
|
||||
import subprocess
|
||||
from pathlib import Path
|
||||
|
||||
ROOT = Path(__file__).resolve().parents[1]
|
||||
LIVE = ROOT / "phone_configs" / "live" / "config-hy2-wg.json"
|
||||
OUT = ROOT / "phone_configs" / "live"
|
||||
ADB = Path(r"C:\Program Files\SuperDisplay\adb\adb.exe")
|
||||
|
||||
|
||||
def build(final: str) -> dict:
|
||||
cfg = json.loads(LIVE.read_text(encoding="utf-8"))
|
||||
c = copy.deepcopy(cfg)
|
||||
tags = {o.get("tag") for o in c.get("outbounds", [])}
|
||||
if "sidecar-proxy" not in tags:
|
||||
c["outbounds"].append(
|
||||
{
|
||||
"type": "socks",
|
||||
"tag": "sidecar-proxy",
|
||||
"server": "127.0.0.1",
|
||||
"server_port": 10800,
|
||||
"version": "5",
|
||||
}
|
||||
)
|
||||
if "olcrtc-proxy" not in tags:
|
||||
c["outbounds"].append(
|
||||
{
|
||||
"type": "socks",
|
||||
"tag": "olcrtc-proxy",
|
||||
"server": "127.0.0.1",
|
||||
"server_port": 10801,
|
||||
"version": "5",
|
||||
}
|
||||
)
|
||||
# drop dead wg-home rules
|
||||
rules = []
|
||||
for r in c.get("route", {}).get("rules", []):
|
||||
if r.get("outbound") == "wg-home":
|
||||
continue
|
||||
rules.append(r)
|
||||
# ensure yandex + TT IP direct
|
||||
if not any("yandex.ru" in (r.get("domain_suffix") or []) for r in rules):
|
||||
rules.insert(
|
||||
0,
|
||||
{
|
||||
"domain_suffix": ["yandex.ru", "yandex.net", "yandex.com", "ya.ru"],
|
||||
"outbound": "direct",
|
||||
},
|
||||
)
|
||||
if not any(
|
||||
(isinstance(r.get("ip_cidr"), list) and "13.140.17.163/32" in r["ip_cidr"])
|
||||
or r.get("ip_cidr") == "13.140.17.163/32"
|
||||
for r in rules
|
||||
):
|
||||
rules.insert(0, {"ip_cidr": ["13.140.17.163/32"], "outbound": "direct"})
|
||||
c.setdefault("route", {})["rules"] = rules
|
||||
c["route"]["final"] = final
|
||||
c["route"]["default_domain_resolver"] = "dns-direct"
|
||||
c["route"]["auto_detect_interface"] = False
|
||||
c["dns"] = {
|
||||
"servers": [
|
||||
{"type": "local", "tag": "dns-direct"},
|
||||
{
|
||||
"type": "https",
|
||||
"tag": "dns-remote",
|
||||
"detour": final,
|
||||
"server": "1.1.1.1",
|
||||
"path": "/dns-query",
|
||||
},
|
||||
],
|
||||
"final": "dns-remote",
|
||||
"strategy": "ipv4_only",
|
||||
"independent_cache": True,
|
||||
}
|
||||
c.setdefault("log", {})["level"] = "info"
|
||||
c["log"]["timestamp"] = True
|
||||
return c
|
||||
|
||||
|
||||
def adb(*args: str) -> None:
|
||||
cmd = [str(ADB), *args]
|
||||
print("+", " ".join(cmd))
|
||||
subprocess.check_call(cmd)
|
||||
|
||||
|
||||
def main() -> None:
|
||||
ap = argparse.ArgumentParser()
|
||||
ap.add_argument("--push", action="store_true", help="adb push to /data/adb/box/sing-box/")
|
||||
ap.add_argument("--use", choices=["trusttunnel", "olcrtc"], help="switch profile on device")
|
||||
args = ap.parse_args()
|
||||
if not LIVE.exists():
|
||||
raise SystemExit(f"missing {LIVE}")
|
||||
|
||||
tt = build("sidecar-proxy")
|
||||
ol = build("olcrtc-proxy")
|
||||
OUT.mkdir(parents=True, exist_ok=True)
|
||||
tt_path = OUT / "config.trusttunnel.json"
|
||||
ol_path = OUT / "config.olcrtc.json"
|
||||
tt_path.write_text(json.dumps(tt, indent=2, ensure_ascii=False) + "\n", encoding="utf-8")
|
||||
ol_path.write_text(json.dumps(ol, indent=2, ensure_ascii=False) + "\n", encoding="utf-8")
|
||||
print("wrote", tt_path)
|
||||
print("wrote", ol_path)
|
||||
|
||||
if args.push or args.use:
|
||||
for p in (tt_path, ol_path):
|
||||
adb("push", str(p), "/sdcard/Download/" + p.name)
|
||||
adb(
|
||||
"shell",
|
||||
"su",
|
||||
"-c",
|
||||
"cp -f /sdcard/Download/config.trusttunnel.json /data/adb/box/sing-box/ && "
|
||||
"cp -f /sdcard/Download/config.olcrtc.json /data/adb/box/sing-box/ && "
|
||||
"cp -f /data/local/tmp/box.profile /data/adb/box/scripts/box.profile 2>/dev/null; "
|
||||
"chmod 700 /data/adb/box/scripts/box.profile 2>/dev/null; "
|
||||
"ls -l /data/adb/box/sing-box/config.trusttunnel.json /data/adb/box/sing-box/config.olcrtc.json",
|
||||
)
|
||||
if args.use:
|
||||
# also push profile script
|
||||
profile = ROOT / "box" / "scripts" / "box.profile"
|
||||
adb("push", str(profile), "/sdcard/Download/box.profile")
|
||||
adb(
|
||||
"shell",
|
||||
"su",
|
||||
"-c",
|
||||
"cp -f /sdcard/Download/box.profile /data/adb/box/scripts/box.profile && "
|
||||
"chmod 700 /data/adb/box/scripts/box.profile && "
|
||||
"sed -i 's/\\r$//' /data/adb/box/scripts/box.profile && "
|
||||
f"/data/adb/box/scripts/box.profile use {args.use}",
|
||||
)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
42
tools/restart_full_stack.sh
Normal file
42
tools/restart_full_stack.sh
Normal file
@@ -0,0 +1,42 @@
|
||||
#!/system/bin/sh
|
||||
export PATH="/data/adb/magisk:/data/adb/ksu/bin:/data/adb/ap/bin:/system/bin:$PATH"
|
||||
set -x
|
||||
|
||||
# clean restart
|
||||
/data/adb/box/scripts/box.iptables disable 2>/dev/null || true
|
||||
/data/adb/box/scripts/box.service stop 2>/dev/null || true
|
||||
pkill -9 trusttunnel_client 2>/dev/null || true
|
||||
pkill -9 sing-box 2>/dev/null || true
|
||||
sleep 1
|
||||
|
||||
# ensure sidecar settings
|
||||
sed -i 's/^sidecar_enable=.*/sidecar_enable="true"/' /data/adb/box/settings.ini
|
||||
sed -i 's/^sidecar_protocol=.*/sidecar_protocol="trusttunnel"/' /data/adb/box/settings.ini
|
||||
sed -i 's/^sidecar_listen_port=.*/sidecar_listen_port="10800"/' /data/adb/box/settings.ini
|
||||
sed -i 's/^sidecar_set_final=.*/sidecar_set_final="true"/' /data/adb/box/settings.ini
|
||||
sed -i 's/^bin_name=.*/bin_name="sing-box"/' /data/adb/box/settings.ini
|
||||
sed -i 's/^network_mode=.*/network_mode="tproxy"/' /data/adb/box/settings.ini
|
||||
|
||||
# start service (includes sidecar)
|
||||
/data/adb/box/scripts/box.service start
|
||||
echo "SERVICE_EXIT=$?"
|
||||
sleep 2
|
||||
/data/adb/box/scripts/box.iptables enable
|
||||
echo "IPTABLES_EXIT=$?"
|
||||
|
||||
echo "=== STATUS ==="
|
||||
pidof trusttunnel_client && echo TT_OK || echo TT_FAIL
|
||||
pidof sing-box && echo SB_OK || echo SB_FAIL
|
||||
grep -E ':2A30 ' /proc/net/tcp && echo SOCKS_OK || echo SOCKS_FAIL
|
||||
|
||||
echo "=== SIDECAR LOG TAIL ==="
|
||||
tail -n 25 /data/adb/box/run/sidecar.log 2>/dev/null
|
||||
echo "=== SING-BOX LOG TAIL ==="
|
||||
tail -n 25 /data/adb/box/run/sing-box.log 2>/dev/null
|
||||
echo "=== RUNS LOG TAIL ==="
|
||||
tail -n 30 /data/adb/box/run/runs.log 2>/dev/null
|
||||
|
||||
echo "=== PROXY IP TEST ==="
|
||||
curl -x socks5h://127.0.0.1:10800 -m 12 -sS https://1.1.1.1/cdn-cgi/trace 2>&1 | head -6
|
||||
echo "=== SYSTEM IP TEST (via tproxy if up) ==="
|
||||
curl -m 12 -sS https://1.1.1.1/cdn-cgi/trace 2>&1 | head -6
|
||||
37
tools/restart_full_stack2.sh
Normal file
37
tools/restart_full_stack2.sh
Normal file
@@ -0,0 +1,37 @@
|
||||
#!/system/bin/sh
|
||||
export PATH="/data/adb/magisk:/data/adb/ksu/bin:/system/bin:$PATH"
|
||||
|
||||
sh /data/adb/box/scripts/box.iptables disable 2>/dev/null || true
|
||||
sh /data/adb/box/scripts/box.service stop 2>/dev/null || true
|
||||
kill -9 $(pidof trusttunnel_client) 2>/dev/null || true
|
||||
kill -9 $(pidof sing-box) 2>/dev/null || true
|
||||
sleep 2
|
||||
|
||||
sed -i 's/^sidecar_enable=.*/sidecar_enable="true"/' /data/adb/box/settings.ini
|
||||
sed -i 's/^sidecar_protocol=.*/sidecar_protocol="trusttunnel"/' /data/adb/box/settings.ini
|
||||
sed -i 's/^sidecar_listen_port=.*/sidecar_listen_port="10800"/' /data/adb/box/settings.ini
|
||||
sed -i 's/^sidecar_set_final=.*/sidecar_set_final="true"/' /data/adb/box/settings.ini
|
||||
|
||||
echo "=== START SERVICE ==="
|
||||
sh /data/adb/box/scripts/box.service start
|
||||
echo "SERVICE_EXIT=$?"
|
||||
sleep 3
|
||||
echo "=== ENABLE IPTABLES ==="
|
||||
sh /data/adb/box/scripts/box.iptables enable
|
||||
echo "IPTABLES_EXIT=$?"
|
||||
sleep 2
|
||||
|
||||
echo "=== PIDS ==="
|
||||
echo "tt=$(pidof trusttunnel_client)"
|
||||
echo "sb=$(pidof sing-box)"
|
||||
grep -E ':2A30 ' /proc/net/tcp && echo SOCKS_LISTEN || echo SOCKS_MISSING
|
||||
|
||||
echo "=== SIDECAR TAIL ==="
|
||||
tail -n 20 /data/adb/box/run/sidecar.log
|
||||
echo "=== RUNS TAIL ==="
|
||||
tail -n 25 /data/adb/box/run/runs.log
|
||||
|
||||
echo "=== SOCKS IP ==="
|
||||
curl -x socks5h://127.0.0.1:10800 -m 12 -sS https://1.1.1.1/cdn-cgi/trace 2>&1 | head -6
|
||||
echo "=== SYSTEM IP ==="
|
||||
curl -m 12 -sS https://1.1.1.1/cdn-cgi/trace 2>&1 | head -6
|
||||
11
tools/retest_tt.sh
Normal file
11
tools/retest_tt.sh
Normal file
@@ -0,0 +1,11 @@
|
||||
#!/system/bin/sh
|
||||
cp /sdcard/Download/trusttunnel.toml /data/adb/box/sidecar/trusttunnel.toml
|
||||
chmod 600 /data/adb/box/sidecar/trusttunnel.toml
|
||||
pkill -9 trusttunnel_client 2>/dev/null
|
||||
: > /data/adb/box/run/sidecar.log
|
||||
/data/adb/box/bin/trusttunnel_client -c /data/adb/box/sidecar/trusttunnel.toml >> /data/adb/box/run/sidecar.log 2>&1 &
|
||||
echo "PID=$!"
|
||||
sleep 4
|
||||
echo "pidof=$(busybox pidof trusttunnel_client)"
|
||||
busybox netstat -lntp 2>/dev/null | grep 10800 || true
|
||||
grep -E 'ERROR|Listening|CONNECTED|DISCONNECTED|Using endpoint|Successfully' /data/adb/box/run/sidecar.log | tail -30
|
||||
22
tools/retest_tt2.sh
Normal file
22
tools/retest_tt2.sh
Normal file
@@ -0,0 +1,22 @@
|
||||
#!/system/bin/sh
|
||||
grep skip_verification /data/adb/box/sidecar/trusttunnel.toml
|
||||
pkill -9 trusttunnel_client 2>/dev/null
|
||||
sleep 1
|
||||
: > /data/adb/box/run/sidecar.log
|
||||
# use -s to skip cert verify
|
||||
/data/adb/box/bin/trusttunnel_client -s -c /data/adb/box/sidecar/trusttunnel.toml >> /data/adb/box/run/sidecar.log 2>&1 &
|
||||
echo "PID=$!"
|
||||
sleep 5
|
||||
PIDOF=$(pidof trusttunnel_client)
|
||||
echo "pidof=$PIDOF"
|
||||
cat /proc/net/tcp | head -1
|
||||
# 10800 = 0x2A30 little endian in /proc/net/tcp = 302A
|
||||
grep -i '302A' /proc/net/tcp /proc/net/tcp6 2>/dev/null || true
|
||||
grep -E 'ERROR|Listening on 127.0.0.1:10800|CONNECTED|Successfully|DISCONNECTED' /data/adb/box/run/sidecar.log | tail -20
|
||||
# quick socks probe via toybox/busybox if available
|
||||
if [ -n "$PIDOF" ]; then
|
||||
echo STILL_ALIVE
|
||||
else
|
||||
echo DEAD
|
||||
tail -n 15 /data/adb/box/run/sidecar.log
|
||||
fi
|
||||
46
tools/retry_olc_fullurl.sh
Normal file
46
tools/retry_olc_fullurl.sh
Normal file
@@ -0,0 +1,46 @@
|
||||
#!/system/bin/sh
|
||||
export PATH="/data/adb/magisk:/data/adb/box/bin:/system/bin:$PATH"
|
||||
CFG=/data/adb/box/sidecar/olcrtc.yaml
|
||||
|
||||
# Restore full telemost room URL (API expects encoded full URL; numeric alone = 404)
|
||||
YQ=/data/adb/box/bin/yq
|
||||
num=$("$YQ" -r '.room.id' "$CFG")
|
||||
num=$(echo "$num" | grep -oE '[0-9]{8,}' | tail -1)
|
||||
"$YQ" -i ".room.id = \"https://telemost.yandex.ru/j/${num}\"" "$CFG"
|
||||
"$YQ" -i '.net.dns = "77.88.8.8:53"' "$CFG"
|
||||
"$YQ" -i '.debug = true' "$CFG" 2>/dev/null || true
|
||||
# Convert CRLF->LF
|
||||
busybox sed -i 's/\r$//' "$CFG"
|
||||
echo "room=$("$YQ" -r '.room.id' "$CFG")"
|
||||
|
||||
# Clear proxy env that can break protect.NewHTTPClient (ProxyFromEnvironment)
|
||||
unset all_proxy ALL_PROXY http_proxy https_proxy HTTP_PROXY HTTPS_PROXY no_proxy NO_PROXY
|
||||
|
||||
rm -rf /data/adb/box/run/olcrtc-data
|
||||
mkdir -p /data/adb/box/run/olcrtc-data
|
||||
killall olcrtc 2>/dev/null || true
|
||||
: > /data/adb/box/run/olcrtc.log
|
||||
|
||||
# Run in foreground briefly with timeout to capture more logs, then background
|
||||
# Prefer GODEBUG
|
||||
export GODEBUG=netdns=go+2
|
||||
nohup env -u all_proxy -u ALL_PROXY -u http_proxy -u https_proxy -u HTTP_PROXY -u HTTPS_PROXY \
|
||||
busybox setuidgid root:net_admin /data/adb/box/bin/olcrtc "$CFG" >> /data/adb/box/run/olcrtc.log 2>&1 &
|
||||
echo $! > /data/adb/box/run/sidecar-olcrtc.pid
|
||||
echo pid=$!
|
||||
|
||||
# Parallel: verify API still ok from same uid context
|
||||
curl -m 15 -sS -o /dev/null -w "curl_api %{http_code} %{time_total}\n" \
|
||||
-H 'User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:149.0) Gecko/20100101 Firefox/149.0' \
|
||||
-H 'Origin: https://telemost.yandex.ru' \
|
||||
-H 'Referer: https://telemost.yandex.ru/' \
|
||||
"https://cloud-api.yandex.ru/telemost_front/v2/telemost/conferences/https%3A%2F%2Ftelemost.yandex.ru%2Fj%2F${num}/connection?display_name=test&next_gen_media_platform_allowed=true&waiting_room_supported=true" || true
|
||||
|
||||
i=0
|
||||
while [ $i -lt 60 ]; do
|
||||
if busybox nc -z 127.0.0.1 10801 2>/dev/null; then echo OPEN_at_$i; break; fi
|
||||
if ! kill -0 "$(cat /data/adb/box/run/sidecar-olcrtc.pid)" 2>/dev/null; then echo DEAD_at_$i; break; fi
|
||||
sleep 1; i=$((i+1))
|
||||
done
|
||||
busybox nc -z 127.0.0.1 10801 && echo OPEN || echo CLOSED
|
||||
tail -60 /data/adb/box/run/olcrtc.log
|
||||
36
tools/retry_olcrtc.sh
Normal file
36
tools/retry_olcrtc.sh
Normal file
@@ -0,0 +1,36 @@
|
||||
#!/system/bin/sh
|
||||
export PATH="/data/adb/magisk:/data/adb/box/bin:/system/bin:$PATH"
|
||||
echo "=== room id shape (redacted) ==="
|
||||
# show only length / whether full URL vs numeric
|
||||
awk '/^room:/{p=1} p&&/id:/{
|
||||
gsub(/[" ]/,"",$2);
|
||||
id=$2;
|
||||
printf "len=%d starts_https=%s looks_numeric=%s\n", length(id), (id ~ /^https/?"yes":"no"), (id ~ /^[0-9]+$/"yes":"no")
|
||||
exit
|
||||
}' /data/adb/box/sidecar/olcrtc.yaml
|
||||
|
||||
echo "=== direct yandex api ==="
|
||||
curl -m 15 -sS -o /dev/null -w "cloud-api %{http_code} %{time_total}\n" https://cloud-api.yandex.ru/ || true
|
||||
curl -m 15 -sS -o /dev/null -w "telemost %{http_code} %{time_total}\n" https://telemost.yandex.ru/ || true
|
||||
|
||||
echo "=== start olcrtc alone (stack already up) ==="
|
||||
killall olcrtc 2>/dev/null || true
|
||||
mkdir -p /data/adb/box/run/olcrtc-data
|
||||
: > /data/adb/box/run/olcrtc.log
|
||||
nohup busybox setuidgid root:net_admin /data/adb/box/bin/olcrtc /data/adb/box/sidecar/olcrtc.yaml >> /data/adb/box/run/olcrtc.log 2>&1 &
|
||||
echo $! > /data/adb/box/run/sidecar-olcrtc.pid
|
||||
echo "pid=$!"
|
||||
i=0
|
||||
while [ $i -lt 60 ]; do
|
||||
if busybox nc -z 127.0.0.1 10801 2>/dev/null; then
|
||||
echo "10801_open after ${i}s"
|
||||
break
|
||||
fi
|
||||
sleep 1
|
||||
i=$((i+1))
|
||||
done
|
||||
busybox nc -z 127.0.0.1 10801 2>/dev/null || echo "10801_still_closed"
|
||||
echo "=== olcrtc.log ==="
|
||||
tail -40 /data/adb/box/run/olcrtc.log
|
||||
echo "=== socks via olcrtc ==="
|
||||
curl -x socks5://127.0.0.1:10801 -m 25 -sS https://1.1.1.1/cdn-cgi/trace 2>&1 | grep -E '^(ip|loc=|curl:)' || true
|
||||
31
tools/setup_sidecar_on_device.sh
Normal file
31
tools/setup_sidecar_on_device.sh
Normal file
@@ -0,0 +1,31 @@
|
||||
#!/system/bin/sh
|
||||
set -e
|
||||
cp /sdcard/Download/trusttunnel_client /data/adb/box/bin/trusttunnel_client
|
||||
chmod 755 /data/adb/box/bin/trusttunnel_client
|
||||
cp /sdcard/Download/trusttunnel.toml /data/adb/box/sidecar/trusttunnel.toml
|
||||
cp /sdcard/Download/olcrtc.yaml /data/adb/box/sidecar/olcrtc.yaml
|
||||
chmod 600 /data/adb/box/sidecar/trusttunnel.toml /data/adb/box/sidecar/olcrtc.yaml
|
||||
|
||||
# enable trusttunnel sidecar
|
||||
sed -i 's/^sidecar_enable=.*/sidecar_enable="true"/' /data/adb/box/settings.ini
|
||||
sed -i 's/^sidecar_protocol=.*/sidecar_protocol="trusttunnel"/' /data/adb/box/settings.ini
|
||||
sed -i 's/^sidecar_listen_port=.*/sidecar_listen_port="10800"/' /data/adb/box/settings.ini
|
||||
|
||||
grep -E '^sidecar_' /data/adb/box/settings.ini || true
|
||||
echo '--- binary test ---'
|
||||
file /data/adb/box/bin/trusttunnel_client 2>/dev/null || true
|
||||
/data/adb/box/bin/trusttunnel_client --help 2>&1 | head -25 || true
|
||||
echo "help_exit=$?"
|
||||
# try short run
|
||||
/data/adb/box/bin/trusttunnel_client -c /data/adb/box/sidecar/trusttunnel.toml >/data/adb/box/run/sidecar.log 2>&1 &
|
||||
SPID=$!
|
||||
echo "started_pid=$SPID"
|
||||
sleep 3
|
||||
if kill -0 "$SPID" 2>/dev/null; then
|
||||
echo SIDECAR_RUNNING
|
||||
busybox netstat -lntp 2>/dev/null | grep 10800 || ss -lntp 2>/dev/null | grep 10800 || true
|
||||
kill -15 "$SPID" 2>/dev/null || true
|
||||
else
|
||||
echo SIDECAR_FAILED
|
||||
tail -n 40 /data/adb/box/run/sidecar.log 2>/dev/null || true
|
||||
fi
|
||||
6
tools/show_final.sh
Normal file
6
tools/show_final.sh
Normal file
@@ -0,0 +1,6 @@
|
||||
#!/system/bin/sh
|
||||
export PATH="/data/adb/magisk:/data/adb/box/bin:/system/bin:$PATH"
|
||||
. /data/adb/box/settings.ini
|
||||
echo "route.final=$(yq -r '.route.final' "$sing_config")"
|
||||
echo "dns-remote.detour=$(yq -r '.dns.servers[] | select(.tag=="dns-remote") | .detour' "$sing_config")"
|
||||
yq -r '.outbounds[] | select(.tag=="sidecar-proxy" or .tag=="olcrtc-proxy") | .tag + " -> " + .server + ":" + (.server_port|tostring)' "$sing_config"
|
||||
7
tools/show_olc_cfg.sh
Normal file
7
tools/show_olc_cfg.sh
Normal file
@@ -0,0 +1,7 @@
|
||||
#!/system/bin/sh
|
||||
# Show olcrtc config shape without secrets
|
||||
export PATH="/data/adb/magisk:/data/adb/box/bin:/system/bin:$PATH"
|
||||
echo "=== olcrtc.yaml redacted ==="
|
||||
sed -E 's/(key:|password:|token:|secret:).*/\1 ***REDACTED***/I; s/(id: ").*(")/\1***\2/' /data/adb/box/sidecar/olcrtc.yaml
|
||||
echo "=== ports in yaml ==="
|
||||
grep -E 'port:|host:|mode:|transport:|provider:' /data/adb/box/sidecar/olcrtc.yaml
|
||||
4
tools/show_settings.sh
Normal file
4
tools/show_settings.sh
Normal file
@@ -0,0 +1,4 @@
|
||||
#!/system/bin/sh
|
||||
grep '^bin_name=' /data/adb/box/settings.ini
|
||||
grep '^network_mode=' /data/adb/box/settings.ini
|
||||
grep '^sidecar_' /data/adb/box/settings.ini
|
||||
29
tools/start_olc.sh
Normal file
29
tools/start_olc.sh
Normal file
@@ -0,0 +1,29 @@
|
||||
#!/system/bin/sh
|
||||
export PATH="/data/adb/magisk:/data/adb/box/bin:/system/bin:$PATH"
|
||||
BB=/data/adb/magisk/busybox
|
||||
cp /data/local/tmp/olcrtc /data/adb/box/bin/olcrtc
|
||||
chmod 755 /data/adb/box/bin/olcrtc
|
||||
killall olcrtc 2>/dev/null || true
|
||||
mkdir -p /data/adb/box/run/olcrtc-data
|
||||
: > /data/adb/box/run/olcrtc.log
|
||||
$BB setuidgid root:net_admin /data/adb/box/bin/olcrtc /data/adb/box/sidecar/olcrtc.yaml >> /data/adb/box/run/olcrtc.log 2>&1 &
|
||||
echo $! > /data/adb/box/run/sidecar-olcrtc.pid
|
||||
echo "pid=$(cat /data/adb/box/run/sidecar-olcrtc.pid)"
|
||||
i=0
|
||||
while [ $i -lt 90 ]; do
|
||||
if $BB nc -z 127.0.0.1 10801 2>/dev/null; then
|
||||
echo "OPEN_at_$i"
|
||||
break
|
||||
fi
|
||||
if ! kill -0 "$(cat /data/adb/box/run/sidecar-olcrtc.pid)" 2>/dev/null; then
|
||||
echo "DEAD_at_$i"
|
||||
break
|
||||
fi
|
||||
sleep 1
|
||||
i=$((i+1))
|
||||
done
|
||||
$BB nc -z 127.0.0.1 10801 && echo OPEN || echo CLOSED
|
||||
tail -40 /data/adb/box/run/olcrtc.log
|
||||
if $BB nc -z 127.0.0.1 10801 2>/dev/null; then
|
||||
curl -x socks5://127.0.0.1:10801 -m 25 -sS https://1.1.1.1/cdn-cgi/trace | grep -E '^(ip|loc)=' || true
|
||||
fi
|
||||
33
tools/start_olc_dnsfix.sh
Normal file
33
tools/start_olc_dnsfix.sh
Normal file
@@ -0,0 +1,33 @@
|
||||
#!/system/bin/sh
|
||||
export PATH="/data/adb/magisk:/data/adb/box/bin:/system/bin:$PATH"
|
||||
BB=/data/adb/magisk/busybox
|
||||
YQ=/data/adb/box/bin/yq
|
||||
CFG=/data/adb/box/sidecar/olcrtc.yaml
|
||||
|
||||
# PreferGo UDP to 77.88.8.8 hangs for root:net_admin on this device; router DNS works.
|
||||
$YQ -i '.net.dns = "192.168.0.1:53"' "$CFG"
|
||||
busybox sed -i 's/\r$//' "$CFG" 2>/dev/null || true
|
||||
echo "dns=$($YQ -r '.net.dns' "$CFG")"
|
||||
echo "room=$($YQ -r '.room.id' "$CFG" | sed 's/.*/***len='"$( $YQ -r '.room.id' "$CFG" | wc -c)"'***/')"
|
||||
|
||||
cp /data/local/tmp/olcrtc /data/adb/box/bin/olcrtc
|
||||
chmod 755 /data/adb/box/bin/olcrtc
|
||||
killall olcrtc 2>/dev/null || true
|
||||
mkdir -p /data/adb/box/run/olcrtc-data
|
||||
: > /data/adb/box/run/olcrtc.log
|
||||
$BB setuidgid root:net_admin /data/adb/box/bin/olcrtc "$CFG" >> /data/adb/box/run/olcrtc.log 2>&1 &
|
||||
echo $! > /data/adb/box/run/sidecar-olcrtc.pid
|
||||
echo "pid=$(cat /data/adb/box/run/sidecar-olcrtc.pid)"
|
||||
i=0
|
||||
while [ $i -lt 90 ]; do
|
||||
if $BB nc -z 127.0.0.1 10801 2>/dev/null; then echo "OPEN_at_$i"; break; fi
|
||||
if ! kill -0 "$(cat /data/adb/box/run/sidecar-olcrtc.pid)" 2>/dev/null; then echo "DEAD_at_$i"; break; fi
|
||||
sleep 1
|
||||
i=$((i+1))
|
||||
done
|
||||
$BB nc -z 127.0.0.1 10801 && echo OPEN || echo CLOSED
|
||||
tail -30 /data/adb/box/run/olcrtc.log
|
||||
if $BB nc -z 127.0.0.1 10801 2>/dev/null; then
|
||||
echo "=== socks via olcrtc ==="
|
||||
curl -x socks5://127.0.0.1:10801 -m 30 -sS https://1.1.1.1/cdn-cgi/trace | grep -E '^(ip|loc)=' || true
|
||||
fi
|
||||
49
tools/switch_to_olcrtc.sh
Normal file
49
tools/switch_to_olcrtc.sh
Normal file
@@ -0,0 +1,49 @@
|
||||
#!/system/bin/sh
|
||||
set -e
|
||||
export PATH="/data/adb/magisk:/data/adb/box/bin:/system/bin:$PATH"
|
||||
. /data/adb/box/settings.ini
|
||||
YQ=/data/adb/box/bin/yq
|
||||
INI=/data/adb/box/settings.ini
|
||||
CFG="$sing_config"
|
||||
BB=/data/adb/magisk/busybox
|
||||
|
||||
echo "ACTIVE_CFG=$CFG"
|
||||
|
||||
# Point primary sidecar at olcrtc for tests (keep yaml port 10801)
|
||||
sed -i 's/^sidecar_enable=.*/sidecar_enable="true"/' "$INI"
|
||||
sed -i 's/^sidecar_protocol=.*/sidecar_protocol="olcrtc"/' "$INI"
|
||||
sed -i 's/^sidecar_listen_port=.*/sidecar_listen_port="10801"/' "$INI"
|
||||
sed -i 's/^sidecar_outbound_tag=.*/sidecar_outbound_tag="olcrtc-proxy"/' "$INI"
|
||||
sed -i 's/^sidecar_set_final=.*/sidecar_set_final="true"/' "$INI"
|
||||
|
||||
# Ensure DNS in olcrtc yaml is LAN resolver (net_admin + 77.88 hangs)
|
||||
if [ -f /data/adb/box/sidecar/olcrtc.yaml ]; then
|
||||
"$YQ" -i '.net.dns = "192.168.0.1:53"' /data/adb/box/sidecar/olcrtc.yaml
|
||||
fi
|
||||
|
||||
# Pre-seed outbound so inject is happy
|
||||
if ! "$YQ" -e '.outbounds[] | select(.tag == "olcrtc-proxy")' "$CFG" >/dev/null 2>&1; then
|
||||
"$YQ" -i -o=json '.outbounds += [{"type":"socks","tag":"olcrtc-proxy","server":"127.0.0.1","server_port":10801,"version":"5"}]' "$CFG"
|
||||
fi
|
||||
|
||||
echo "=== settings ==="
|
||||
grep -E '^sidecar_' "$INI"
|
||||
|
||||
sh /data/adb/box/scripts/box.service restart
|
||||
sleep 5
|
||||
|
||||
echo "=== after restart ==="
|
||||
echo "tt=$(pidof trusttunnel_client) olc=$(pidof olcrtc) sb=$(pidof sing-box)"
|
||||
echo "final=$("$YQ" -r '.route.final' "$CFG")"
|
||||
echo "dns_detour=$("$YQ" -r '.dns.servers[] | select(.tag=="dns-remote") | .detour' "$CFG")"
|
||||
$BB nc -z 127.0.0.1 10801 && echo 10801_open || echo 10801_closed
|
||||
$BB nc -z 127.0.0.1 10800 && echo 10800_open || echo 10800_closed
|
||||
|
||||
echo "=== system IP (should be via olcrtc) ==="
|
||||
curl -m 25 -sS https://1.1.1.1/cdn-cgi/trace 2>/dev/null | grep -E '^(ip|loc|colo)=' || true
|
||||
echo "=== google ==="
|
||||
curl -m 25 -sS -o /dev/null -w "%{http_code} %{time_total}\n" https://www.google.com/ || true
|
||||
echo "=== ya.ru ==="
|
||||
curl -m 20 -sS -o /dev/null -w "%{http_code} %{time_total}\n" https://ya.ru/ || true
|
||||
echo "=== olcrtc log ==="
|
||||
tail -15 /data/adb/box/run/olcrtc.log 2>/dev/null || tail -15 /data/adb/box/run/sidecar.log
|
||||
12
tools/test_telemost_api.sh
Normal file
12
tools/test_telemost_api.sh
Normal file
@@ -0,0 +1,12 @@
|
||||
#!/system/bin/sh
|
||||
export PATH="/data/adb/magisk:/data/adb/box/bin:/system/bin:$PATH"
|
||||
URL='https://cloud-api.yandex.ru/telemost_front/v2/telemost/conferences/https%3A%2F%2Ftelemost.yandex.ru%2Fj%2F41001894292350/connection?display_name=test&next_gen_media_platform_allowed=true&waiting_room_supported=true'
|
||||
echo "=== exact telemost connection URL ==="
|
||||
curl -m 20 -sS -o /tmp/tm.json -w "%{http_code} %{time_total}\n" -H 'Accept: application/json' -H 'User-Agent: Mozilla/5.0' "$URL" || true
|
||||
head -c 400 /tmp/tm.json; echo
|
||||
echo "=== as numeric only path ==="
|
||||
URL2='https://cloud-api.yandex.ru/telemost_front/v2/telemost/conferences/41001894292350/connection?display_name=test&next_gen_media_platform_allowed=true&waiting_room_supported=true'
|
||||
curl -m 20 -sS -o /tmp/tm2.json -w "%{http_code} %{time_total}\n" -H 'Accept: application/json' -H 'User-Agent: Mozilla/5.0' "$URL2" || true
|
||||
head -c 400 /tmp/tm2.json; echo
|
||||
echo "=== resolve cloud-api ==="
|
||||
busybox nslookup cloud-api.yandex.ru 77.88.8.8 2>&1 | head -15
|
||||
17
tools/tt_check.sh
Normal file
17
tools/tt_check.sh
Normal file
@@ -0,0 +1,17 @@
|
||||
#!/system/bin/sh
|
||||
export PATH="/data/adb/magisk:/data/adb/box/bin:/system/bin:$PATH"
|
||||
echo "=== tt toml ==="
|
||||
cat /data/adb/box/sidecar/trusttunnel.toml
|
||||
echo
|
||||
echo "=== sidecar start cmd / settings ==="
|
||||
grep -E 'sidecar|trusttunnel|skip' /data/adb/box/settings.ini
|
||||
echo "=== process cmdline ==="
|
||||
tr '\0' ' ' < /proc/$(pidof trusttunnel_client)/cmdline; echo
|
||||
echo "=== socks5 IP DoH again ==="
|
||||
curl -x socks5://127.0.0.1:10800 -m 10 -sS 'https://1.1.1.1/dns-query?name=www.google.com&type=A' -H 'accept: application/dns-json' 2>&1 | head -c 300; echo
|
||||
echo "=== socks5h google ==="
|
||||
curl -x socks5h://127.0.0.1:10800 -m 10 -sS -o /dev/null -w "%{http_code}\n" https://www.google.com/ 2>&1 | tail -5
|
||||
echo "=== test results from prior ==="
|
||||
# read end was truncated in previous - quick retest with current final dns
|
||||
curl -m 12 -sS -o /dev/null -w "google %{http_code} %{time_total}\n" https://www.google.com/ || true
|
||||
curl -m 10 -sS -o /dev/null -w "ya %{http_code} %{time_total}\n" https://ya.ru/ || true
|
||||
123
tools/tt_deeplink_to_toml.py
Normal file
123
tools/tt_deeplink_to_toml.py
Normal file
@@ -0,0 +1,123 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Decode TrustTunnel tt:// deep link -> client TOML (SOCKS mode)."""
|
||||
import base64
|
||||
import sys
|
||||
|
||||
|
||||
def read_tls_varint(b, i):
|
||||
first = b[i]
|
||||
prefix = first >> 6
|
||||
length = 1 << prefix
|
||||
raw = int.from_bytes(b[i : i + length], "big")
|
||||
mask = (1 << (8 * length - 2)) - 1
|
||||
return raw & mask, i + length
|
||||
|
||||
|
||||
def decode_tt(uri: str) -> dict:
|
||||
payload = uri.split("?", 1)[1] if "?" in uri else uri[5:]
|
||||
pad = "=" * ((4 - len(payload) % 4) % 4)
|
||||
data = base64.urlsafe_b64decode(payload + pad)
|
||||
i = 0
|
||||
fields = {"addresses": []}
|
||||
tags = {
|
||||
0: "version",
|
||||
1: "hostname",
|
||||
2: "addresses",
|
||||
3: "custom_sni",
|
||||
4: "has_ipv6",
|
||||
5: "username",
|
||||
6: "password",
|
||||
7: "skip_verification",
|
||||
8: "certificate",
|
||||
9: "upstream_protocol",
|
||||
10: "anti_dpi",
|
||||
11: "client_random_prefix",
|
||||
12: "name",
|
||||
13: "dns_upstreams",
|
||||
}
|
||||
while i < len(data):
|
||||
tag, i = read_tls_varint(data, i)
|
||||
length, i = read_tls_varint(data, i)
|
||||
val = data[i : i + length]
|
||||
i += length
|
||||
name = tags.get(tag, f"tag_{tag}")
|
||||
if tag == 2:
|
||||
fields["addresses"].append(val.decode("utf-8"))
|
||||
elif tag in (4, 7, 10):
|
||||
fields[name] = bool(val[0])
|
||||
elif tag == 0:
|
||||
v, _ = read_tls_varint(val, 0)
|
||||
fields[name] = v
|
||||
elif tag == 9:
|
||||
v, _ = read_tls_varint(val, 0)
|
||||
fields[name] = {1: "http2", 2: "http3"}.get(v, str(v))
|
||||
elif tag == 8:
|
||||
fields[name] = val # raw DER
|
||||
elif tag == 13:
|
||||
# string[]
|
||||
j = 0
|
||||
ups = []
|
||||
while j < len(val):
|
||||
ln, j = read_tls_varint(val, j)
|
||||
ups.append(val[j : j + ln].decode("utf-8"))
|
||||
j += ln
|
||||
fields[name] = ups
|
||||
else:
|
||||
fields[name] = val.decode("utf-8")
|
||||
return fields
|
||||
|
||||
|
||||
def to_toml(fields: dict, socks_port: int = 10800) -> str:
|
||||
hostname = fields["hostname"]
|
||||
username = fields["username"]
|
||||
password = fields["password"]
|
||||
addresses = fields.get("addresses") or []
|
||||
addr_list = ", ".join(f'"{a}"' for a in addresses)
|
||||
has_ipv6 = str(fields.get("has_ipv6", True)).lower()
|
||||
skip = str(fields.get("skip_verification", False)).lower()
|
||||
proto = fields.get("upstream_protocol", "http2")
|
||||
anti = str(fields.get("anti_dpi", False)).lower()
|
||||
name = fields.get("name", "trusttunnel")
|
||||
return f'''# Generated from tt:// deep link — {name}
|
||||
loglevel = "info"
|
||||
vpn_mode = "general"
|
||||
killswitch_enabled = false
|
||||
post_quantum_group_enabled = true
|
||||
exclusions = []
|
||||
|
||||
[endpoint]
|
||||
hostname = "{hostname}"
|
||||
addresses = [{addr_list}]
|
||||
has_ipv6 = {has_ipv6}
|
||||
username = "{username}"
|
||||
password = "{password}"
|
||||
skip_verification = {skip}
|
||||
upstream_protocol = "{proto}"
|
||||
anti_dpi = {anti}
|
||||
dns_upstreams = ["tls://1.1.1.1"]
|
||||
|
||||
[listener.socks]
|
||||
address = "127.0.0.1:{socks_port}"
|
||||
'''
|
||||
|
||||
|
||||
def main():
|
||||
uri = sys.argv[1]
|
||||
out = sys.argv[2] if len(sys.argv) > 2 else "-"
|
||||
fields = decode_tt(uri)
|
||||
text = to_toml(fields)
|
||||
if out == "-":
|
||||
# redact password in stdout preview
|
||||
preview = text
|
||||
if "password =" in preview:
|
||||
import re
|
||||
preview = re.sub(r'password = ".*"', 'password = "***"', preview)
|
||||
print(preview)
|
||||
print("# fields:", {k: ("***" if k == "password" else v) for k, v in fields.items()}, file=sys.stderr)
|
||||
else:
|
||||
open(out, "w", encoding="utf-8").write(text)
|
||||
print(f"wrote {out}", file=sys.stderr)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
25
tools/tt_seq.sh
Normal file
25
tools/tt_seq.sh
Normal file
@@ -0,0 +1,25 @@
|
||||
#!/system/bin/sh
|
||||
export PATH="/data/adb/magisk:/data/adb/box/bin:/system/bin:$PATH"
|
||||
echo "=== tt toml ==="
|
||||
cat /data/adb/box/sidecar/trusttunnel.toml
|
||||
echo
|
||||
echo "=== cmdline ==="
|
||||
tr '\0' ' ' < /proc/$(pidof trusttunnel_client)/cmdline; echo
|
||||
echo "=== sequential socks DoH x5 ==="
|
||||
i=1
|
||||
while [ $i -le 5 ]; do
|
||||
code=$(curl -x socks5://127.0.0.1:10800 -m 8 -sS -o /tmp/doh.json -w "%{http_code}" 'https://1.1.1.1/dns-query?name=example.com&type=A' -H 'accept: application/dns-json' 2>/tmp/doh.err || echo err)
|
||||
echo "#$i http=$code $(head -c 80 /tmp/doh.json 2>/dev/null)"
|
||||
cat /tmp/doh.err 2>/dev/null | tail -1
|
||||
i=$((i+1))
|
||||
sleep 1
|
||||
done
|
||||
echo "=== system sequential ==="
|
||||
for h in www.google.com ya.ru github.com; do
|
||||
curl -m 12 -sS -o /dev/null -w "$h %{http_code} %{time_total}\n" "https://$h/" || echo "$h fail"
|
||||
sleep 1
|
||||
done
|
||||
echo "=== tt log tail ==="
|
||||
tail -20 /data/adb/box/run/sidecar.log
|
||||
echo "=== dns strategy now ==="
|
||||
yq -o=json '.dns.strategy,.dns.final,.dns.servers' /data/adb/box/sing-box/config.json
|
||||
14
tools/verify_dual.sh
Normal file
14
tools/verify_dual.sh
Normal file
@@ -0,0 +1,14 @@
|
||||
#!/system/bin/sh
|
||||
export PATH="/data/adb/magisk:/data/adb/box/bin:/system/bin:$PATH"
|
||||
BB=/data/adb/magisk/busybox
|
||||
echo "tt=$(pidof trusttunnel_client) olc=$(pidof olcrtc) sb=$(pidof sing-box)"
|
||||
$BB nc -z 127.0.0.1 10800 && echo 10800_ok || echo 10800_down
|
||||
$BB nc -z 127.0.0.1 10801 && echo 10801_ok || echo 10801_down
|
||||
echo "=== via olcrtc socks ==="
|
||||
curl -x socks5h://127.0.0.1:10801 -m 20 -sS -o /dev/null -w "google %{http_code} %{time_total}\n" https://www.google.com/ || true
|
||||
curl -x socks5://127.0.0.1:10801 -m 15 -sS https://1.1.1.1/cdn-cgi/trace 2>/dev/null | grep -E '^(ip|loc|colo)=' || true
|
||||
echo "=== system via TT final ==="
|
||||
curl -m 15 -sS -o /dev/null -w "google %{http_code}\n" https://www.google.com/ || true
|
||||
curl -m 12 -sS https://1.1.1.1/cdn-cgi/trace 2>/dev/null | grep -E '^(ip|loc)=' || true
|
||||
echo "=== rkn ==="
|
||||
pm path com.notcvnt.rknhardering
|
||||
10
tools/which_cfg.sh
Normal file
10
tools/which_cfg.sh
Normal file
@@ -0,0 +1,10 @@
|
||||
#!/system/bin/sh
|
||||
export PATH="/data/adb/magisk:/data/adb/box/bin:/system/bin:$PATH"
|
||||
echo "=== which config ==="
|
||||
grep -E 'config|bin_name|name_box' /data/adb/box/settings.ini | head -40
|
||||
ls -la /data/adb/box/sing-box/*.json
|
||||
echo "=== process cwd/open config? ==="
|
||||
# sing-box cmdline
|
||||
tr '\0' ' ' < /proc/$(pidof sing-box)/cmdline; echo
|
||||
echo "=== runs.log config lines ==="
|
||||
grep -i config /data/adb/box/run/runs.log | tail -20
|
||||
21
tools/which_path.sh
Normal file
21
tools/which_path.sh
Normal file
@@ -0,0 +1,21 @@
|
||||
#!/system/bin/sh
|
||||
export PATH="/data/adb/magisk:/data/adb/box/bin:/system/bin:$PATH"
|
||||
. /data/adb/box/settings.ini
|
||||
echo "=== settings ==="
|
||||
grep -E '^sidecar_' /data/adb/box/settings.ini
|
||||
echo "=== active sing config ==="
|
||||
echo "sing_config=$sing_config"
|
||||
yq -o=json '.route.final, (.outbounds[] | select(.tag=="sidecar-proxy" or .tag=="olcrtc-proxy") | {tag,type,server,server_port})' "$sing_config"
|
||||
echo "=== processes / ports ==="
|
||||
echo "tt=$(pidof trusttunnel_client) olc=$(pidof olcrtc) sb=$(pidof sing-box)"
|
||||
/data/adb/magisk/busybox nc -z 127.0.0.1 10800 && echo 10800_open || echo 10800_closed
|
||||
/data/adb/magisk/busybox nc -z 127.0.0.1 10801 && echo 10801_open || echo 10801_closed
|
||||
echo "=== IP via TT socks :10800 ==="
|
||||
curl -x socks5://127.0.0.1:10800 -m 15 -sS https://1.1.1.1/cdn-cgi/trace 2>/dev/null | grep -E '^(ip|loc|colo|http)=' || echo FAIL_TT
|
||||
echo "=== IP via olcrtc socks :10801 ==="
|
||||
curl -x socks5://127.0.0.1:10801 -m 20 -sS https://1.1.1.1/cdn-cgi/trace 2>/dev/null | grep -E '^(ip|loc|colo|http)=' || echo FAIL_OLC
|
||||
echo "=== IP via SYSTEM (follows route.final) ==="
|
||||
curl -m 15 -sS https://1.1.1.1/cdn-cgi/trace 2>/dev/null | grep -E '^(ip|loc|colo|http)=' || echo FAIL_SYS
|
||||
echo "=== olcrtc log (last session lines) ==="
|
||||
grep -E 'SOCKS5|telemost|session|opened|listening|peer latched' /data/adb/box/run/olcrtc.log 2>/dev/null | tail -15
|
||||
grep -E 'SOCKS5|telemost|session|opened|listening|peer latched' /data/adb/box/run/sidecar.log 2>/dev/null | tail -10
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"version": "v1.10.2-stealth.1",
|
||||
"versionCode": "2026081201",
|
||||
"zipUrl": "http://10.2.0.2/M1rs3m/BFR/releases/download/v1.10.2-stealth.1/box_for_root-v1.10.2-stealth.1.zip",
|
||||
"changelog": "http://10.2.0.2/M1rs3m/BFR/src/branch/main/README.md"
|
||||
"version": "v1.12.0",
|
||||
"versionCode": "2026081301",
|
||||
"zipUrl": "http://10.2.0.2/M1rs3m/BFR/releases/download/v1.12.0/pronbox-v1.12.0.zip",
|
||||
"changelog": "http://10.2.0.2/M1rs3m/BFR/src/branch/main/CHANGELOG_STEALTH.md"
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user