add Proton additional out on 3080
This commit is contained in:
@@ -1,4 +1,4 @@
|
|||||||
# Sing-Box WARP Project
|
# Sing-Box WARP Project (Additional Proton out)
|
||||||
> Author remark:
|
> Author remark:
|
||||||
> вы спросите - нахуя такие сложности? А потому что нативный warp не поддерживает amneziaWG ключи для обфускации WireGuard. А ебаться в саму амнезию нет желания. К тому же sing-box сразу может поднять локальный сокс что упрощает просовывание этого варпа во всякого рода панели.
|
> вы спросите - нахуя такие сложности? А потому что нативный warp не поддерживает amneziaWG ключи для обфускации WireGuard. А ебаться в саму амнезию нет желания. К тому же sing-box сразу может поднять локальный сокс что упрощает просовывание этого варпа во всякого рода панели.
|
||||||
> UPD: Теперь в рф захотели блокировать github и появилась проблема установки панелей. Данное решение покрывает проблемы со скачиванием любых репозиториев или иного self-host софта с github и попутно покрывает ряд других блокнутых ресурсов при включении TUN во время установки.
|
> UPD: Теперь в рф захотели блокировать github и появилась проблема установки панелей. Данное решение покрывает проблемы со скачиванием любых репозиториев или иного self-host софта с github и попутно покрывает ряд других блокнутых ресурсов при включении TUN во время установки.
|
||||||
@@ -12,12 +12,25 @@
|
|||||||
- `quick-install.sh` — установка и настройка systemd-сервиса
|
- `quick-install.sh` — установка и настройка systemd-сервиса
|
||||||
- `generate-config.sh` — генератор `config.json` из WireGuard AWG3.0
|
- `generate-config.sh` — генератор `config.json` из WireGuard AWG3.0
|
||||||
- `warp.conf.example` — пример WARP-конфигурации
|
- `warp.conf.example` — пример WARP-конфигурации
|
||||||
|
- `proton.conf.example` — пример второй (Proton) WireGuard-конфигурации
|
||||||
|
|
||||||
## Как это работает
|
## Как это работает
|
||||||
|
|
||||||
1. При установке вводится WARP-конфиг (AWG 3.0) → сохраняется в `/etc/sing-box-warp/warp.conf`
|
1. При установке вводится WARP-конфиг (AWG 3.0) → сохраняется в `/etc/sing-box-warp/warp.conf`
|
||||||
2. `generate-config.sh` парсит конфиг и пишет `/opt/sing-box-warp/config.json`
|
2. Опционально вводится второй конфиг (Proton VPN, обычный WireGuard или `wg://`) → `/etc/sing-box-warp/proton.conf`
|
||||||
3. SOCKS5 доступен на порту `2080`; опционально TUN для сплит-маршрутизации
|
3. `generate-config.sh` парсит конфиги и пишет `/opt/sing-box-warp/config.json`
|
||||||
|
4. SOCKS5 WARP доступен на порту `2080`; при добавлении Proton — второй SOCKS5 на `3080`
|
||||||
|
5. Опционально TUN для сплит-маршрутизации
|
||||||
|
|
||||||
|
### Схема маршрутизации
|
||||||
|
|
||||||
|
Скрипт работает в двух режимах: **только WARP** или **WARP + Proton**.
|
||||||
|
|
||||||
|
- SOCKS-инпуты жёстко привязаны к своим выходам: `2080 → warp-out`, `3080 → proton-out`.
|
||||||
|
- Всё остальное (TUN-трафик, списки маршрутизации `.srs`, сайты проверки IP, proxy-DNS) идёт в
|
||||||
|
«дефолтный» выход. Дефолт выбирается при установке: **WARP** или **Proton** (вопрос задаётся
|
||||||
|
только если Proton добавлен).
|
||||||
|
- Если Proton не добавлен — второй SOCKS-инпут (`3080`) и `proton-out` не создаются, дефолт всегда WARP.
|
||||||
|
|
||||||
## Установка
|
## Установка
|
||||||
|
|
||||||
@@ -29,12 +42,30 @@ curl -fsSL https://gitea.digitalforest.my/hesoyam/sing-warp-socks5/raw/branch/ma
|
|||||||
|
|
||||||
Вставьте текстом всё содержимое сгенерированного AWG конфига в терминал. Enter затем ctrl+D
|
Вставьте текстом всё содержимое сгенерированного AWG конфига в терминал. Enter затем ctrl+D
|
||||||
|
|
||||||
Скрипт спросит включение TUN. Включите, если с сервера недоступны заблокированные ресурсы (GitHub и т.п.). Без TUN — только SOCKS5 на `2080`.
|
Затем скрипт спросит про Proton. Брать протон тут https://account.protonvpn.com/downloads (Нужен аккаунт)
|
||||||
|
Ответьте `n`, чтобы оставить только WARP, или `y` и вставьте
|
||||||
|
второй WireGuard-конфиг (формат `[Interface]`/`[Peer]` как у Proton VPN, либо `wg://`), завершив ввод Ctrl+D.
|
||||||
|
|
||||||
|
```
|
||||||
|
Add Proton configuration? (y/n)
|
||||||
|
```
|
||||||
|
|
||||||
|
Далее спрашивается включение TUN. Включите, если с сервера недоступны заблокированные ресурсы (GitHub и т.п.). Без TUN — только SOCKS5.
|
||||||
|
|
||||||
```
|
```
|
||||||
Enable TUN mode? (y/n)
|
Enable TUN mode? (y/n)
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Если Proton добавлен — скрипт спросит, куда направлять весь не-SOCKS трафик (дефолтный выход).
|
||||||
|
SOCKS-инпуты при этом всегда остаются: `2080 → WARP`, `3080 → Proton`.
|
||||||
|
|
||||||
|
```
|
||||||
|
=== Default route ===
|
||||||
|
1) WARP (warp-out)
|
||||||
|
2) Proton (proton-out)
|
||||||
|
Select default route [1/2]
|
||||||
|
```
|
||||||
|
|
||||||
Повторный запуск инсталлера останавливает старый сервис, переустанавливает файлы и запускает заново.
|
Повторный запуск инсталлера останавливает старый сервис, переустанавливает файлы и запускает заново.
|
||||||
|
|
||||||
## Формат warp.conf
|
## Формат warp.conf
|
||||||
@@ -63,15 +94,36 @@ Endpoint = engage.cloudflareclient.com:2408
|
|||||||
PersistentKeepalive = 25
|
PersistentKeepalive = 25
|
||||||
```
|
```
|
||||||
|
|
||||||
## Использование
|
## Формат proton.conf (опционально)
|
||||||
|
|
||||||
SOCKS5 без авторизации: `localhost:2080`
|
Обычный WireGuard-конфиг (например, экспорт из Proton VPN) или `wg://`-ссылка.
|
||||||
|
|
||||||
```bash
|
```ini
|
||||||
curl --proxy socks5://localhost:2080 ip-api.com
|
[Interface]
|
||||||
|
PrivateKey = {privkey}
|
||||||
|
Address = 10.2.0.2/32
|
||||||
|
DNS = 10.2.0.1
|
||||||
|
|
||||||
|
[Peer]
|
||||||
|
PublicKey = {pubkey}
|
||||||
|
AllowedIPs = 0.0.0.0/0, ::/0
|
||||||
|
Endpoint = 149.50.211.159:51820
|
||||||
|
PersistentKeepalive = 25
|
||||||
```
|
```
|
||||||
|
|
||||||
С TUN трафик по спискам `.srs` идёт через WARP; SOCKS5 при этом остаётся доступным.
|
## Использование
|
||||||
|
|
||||||
|
SOCKS5 без авторизации:
|
||||||
|
|
||||||
|
- WARP — `localhost:2080`
|
||||||
|
- Proton (если добавлен) — `0.0.0.0:3080`
|
||||||
|
|
||||||
|
```bash
|
||||||
|
curl --proxy socks5://localhost:2080 ip-api.com # через WARP
|
||||||
|
curl --proxy socks5://localhost:3080 ip-api.com # через Proton
|
||||||
|
```
|
||||||
|
|
||||||
|
С TUN трафик по спискам `.srs` идёт через дефолтный выход (WARP или Proton); SOCKS5 при этом остаётся доступным.
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
curl ip-api.com
|
curl ip-api.com
|
||||||
@@ -89,7 +141,14 @@ sudo systemctl restart sing-box-warp
|
|||||||
|
|
||||||
## Обновление конфигурации
|
## Обновление конфигурации
|
||||||
|
|
||||||
Отредактируйте `/etc/sing-box-warp/warp.conf` (и при необходимости `/etc/sing-box-warp/enable-tun`), затем:
|
Отредактируйте нужные файлы в `/etc/sing-box-warp/`:
|
||||||
|
|
||||||
|
- `warp.conf` — конфиг WARP
|
||||||
|
- `proton.conf` — конфиг Proton (удалите файл, чтобы отключить Proton)
|
||||||
|
- `enable-tun` — `1`/`0` для TUN
|
||||||
|
- `default-route` — `warp` или `proton` (куда идёт весь не-SOCKS трафик)
|
||||||
|
|
||||||
|
затем:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
sudo /opt/sing-box-warp/generate-config.sh
|
sudo /opt/sing-box-warp/generate-config.sh
|
||||||
|
|||||||
+225
-12
@@ -1,8 +1,10 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
|
|
||||||
WARP_CONF="${WARP_CONF:-/etc/sing-box-warp/warp.conf}"
|
WARP_CONF="${WARP_CONF:-/etc/sing-box-warp/warp.conf}"
|
||||||
|
PROTON_CONF="${PROTON_CONF:-/etc/sing-box-warp/proton.conf}"
|
||||||
OUTPUT_CONFIG="${OUTPUT_CONFIG:-/opt/sing-box-warp/config.json}"
|
OUTPUT_CONFIG="${OUTPUT_CONFIG:-/opt/sing-box-warp/config.json}"
|
||||||
ENABLE_TUN_FILE="${ENABLE_TUN_FILE:-/etc/sing-box-warp/enable-tun}"
|
ENABLE_TUN_FILE="${ENABLE_TUN_FILE:-/etc/sing-box-warp/enable-tun}"
|
||||||
|
DEFAULT_ROUTE_FILE="${DEFAULT_ROUTE_FILE:-/etc/sing-box-warp/default-route}"
|
||||||
|
|
||||||
load_enable_tun() {
|
load_enable_tun() {
|
||||||
local value
|
local value
|
||||||
@@ -18,6 +20,22 @@ load_enable_tun() {
|
|||||||
esac
|
esac
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Where all non-SOCKS traffic goes (TUN rules, routing lists, IP-leak sites).
|
||||||
|
# The SOCKS inbounds keep their own hard-coded outbound.
|
||||||
|
load_default_route() {
|
||||||
|
local value
|
||||||
|
|
||||||
|
value=$(trim "${DEFAULT_ROUTE:-}")
|
||||||
|
if [ -z "$value" ] && [ -f "$DEFAULT_ROUTE_FILE" ]; then
|
||||||
|
value=$(trim "$(cat "$DEFAULT_ROUTE_FILE")")
|
||||||
|
fi
|
||||||
|
|
||||||
|
case "$value" in
|
||||||
|
2|proton|PROTON|Proton) DEFAULT_ROUTE=proton ;;
|
||||||
|
*) DEFAULT_ROUTE=warp ;;
|
||||||
|
esac
|
||||||
|
}
|
||||||
|
|
||||||
urldecode() {
|
urldecode() {
|
||||||
echo "$1" | sed 's/%3[dD]/=/g; s/%2[bB]/+/g; s/%2[fF]/\//g; s/%2[cC]/,/g'
|
echo "$1" | sed 's/%3[dD]/=/g; s/%2[bB]/+/g; s/%2[fF]/\//g; s/%2[cC]/,/g'
|
||||||
}
|
}
|
||||||
@@ -80,6 +98,39 @@ normalize_cidr() {
|
|||||||
esac
|
esac
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Convert a comma-separated AllowedIPs list into a JSON array body:
|
||||||
|
# "0.0.0.0/0, ::/0" -> "0.0.0.0/0", "::/0"
|
||||||
|
build_allowed_ips_json() {
|
||||||
|
local input
|
||||||
|
local result=""
|
||||||
|
local item
|
||||||
|
local old_ifs
|
||||||
|
|
||||||
|
input="$1"
|
||||||
|
if [ -z "$input" ]; then
|
||||||
|
echo '"0.0.0.0/0", "::/0"'
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
|
||||||
|
old_ifs="$IFS"
|
||||||
|
IFS=','
|
||||||
|
for item in $input; do
|
||||||
|
item=$(trim "$item")
|
||||||
|
[ -z "$item" ] && continue
|
||||||
|
if [ -z "$result" ]; then
|
||||||
|
result="\"$item\""
|
||||||
|
else
|
||||||
|
result="$result, \"$item\""
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
IFS="$old_ifs"
|
||||||
|
|
||||||
|
if [ -z "$result" ]; then
|
||||||
|
result='"0.0.0.0/0", "::/0"'
|
||||||
|
fi
|
||||||
|
echo "$result"
|
||||||
|
}
|
||||||
|
|
||||||
# Extract parameter from URL
|
# Extract parameter from URL
|
||||||
get_param() {
|
get_param() {
|
||||||
local url="$1"
|
local url="$1"
|
||||||
@@ -134,7 +185,7 @@ parse_from_wg_url() {
|
|||||||
H4=${H4:-4}
|
H4=${H4:-4}
|
||||||
|
|
||||||
ALLOWED_IPS="0.0.0.0/0"
|
ALLOWED_IPS="0.0.0.0/0"
|
||||||
TAG="wireguard-out"
|
TAG="warp-out"
|
||||||
LOG_LEVEL="error"
|
LOG_LEVEL="error"
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -226,11 +277,112 @@ parse_from_ini() {
|
|||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
TAG="wireguard-out"
|
TAG="warp-out"
|
||||||
LOG_LEVEL="error"
|
LOG_LEVEL="error"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
parse_proton_from_ini() {
|
||||||
|
local section=""
|
||||||
|
local key=""
|
||||||
|
local value=""
|
||||||
|
local p_ipv4=""
|
||||||
|
local p_allowed=""
|
||||||
|
|
||||||
|
while IFS= read -r line || [ -n "$line" ]; do
|
||||||
|
line=$(trim "$line")
|
||||||
|
[ -z "$line" ] && continue
|
||||||
|
|
||||||
|
case "$line" in
|
||||||
|
\#*|\;*) continue ;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
case "$line" in
|
||||||
|
"[Interface]") section="Interface"; continue ;;
|
||||||
|
"[Peer]") section="Peer"; continue ;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
key=$(trim "$(echo "$line" | cut -d'=' -f1)")
|
||||||
|
value=$(trim "$(echo "$line" | cut -d'=' -f2-)")
|
||||||
|
[ -z "$key" ] && continue
|
||||||
|
|
||||||
|
if [ "$section" = "Interface" ]; then
|
||||||
|
case "$key" in
|
||||||
|
PrivateKey) PROTON_PRIVATE_KEY="$value" ;;
|
||||||
|
Address) p_ipv4=$(trim "$(echo "$value" | cut -d',' -f1)") ;;
|
||||||
|
MTU) PROTON_MTU="$value" ;;
|
||||||
|
esac
|
||||||
|
elif [ "$section" = "Peer" ]; then
|
||||||
|
case "$key" in
|
||||||
|
PublicKey) PROTON_PUBLIC_KEY="$value" ;;
|
||||||
|
AllowedIPs) p_allowed="$value" ;;
|
||||||
|
Endpoint)
|
||||||
|
PROTON_SERVER=$(echo "$value" | cut -d':' -f1)
|
||||||
|
PROTON_PORT=$(echo "$value" | cut -d':' -f2)
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
fi
|
||||||
|
done < "$PROTON_CONF"
|
||||||
|
|
||||||
|
PROTON_ADDRESS=$(normalize_cidr "$p_ipv4" 32)
|
||||||
|
PROTON_ALLOWED_IPS=$(build_allowed_ips_json "$p_allowed")
|
||||||
|
}
|
||||||
|
|
||||||
|
parse_proton_from_wg_url() {
|
||||||
|
local url
|
||||||
|
local local_addr
|
||||||
|
local p_ipv4
|
||||||
|
|
||||||
|
url=$(grep "^wg://" "$PROTON_CONF" | head -1)
|
||||||
|
|
||||||
|
PROTON_SERVER=$(echo "$url" | sed 's|wg://\([^:]*\):.*|\1|')
|
||||||
|
PROTON_PORT=$(echo "$url" | sed 's|wg://[^:]*:\([0-9]*\)?.*|\1|')
|
||||||
|
PROTON_PRIVATE_KEY=$(urldecode "$(get_param "$url" "private_key")")
|
||||||
|
PROTON_PUBLIC_KEY=$(urldecode "$(get_param "$url" "peer_public_key")")
|
||||||
|
PROTON_MTU=$(get_param "$url" "mtu")
|
||||||
|
|
||||||
|
local_addr=$(urldecode "$(get_param "$url" "local_address")")
|
||||||
|
p_ipv4=$(echo "$local_addr" | tr ',-' '\n' | sed -n '1p')
|
||||||
|
PROTON_ADDRESS=$(normalize_cidr "$p_ipv4" 32)
|
||||||
|
PROTON_ALLOWED_IPS='"0.0.0.0/0", "::/0"'
|
||||||
|
}
|
||||||
|
|
||||||
|
parse_proton_conf() {
|
||||||
|
local first_line
|
||||||
|
first_line=$(head -n 1 "$PROTON_CONF" | tr -d '\r')
|
||||||
|
first_line=$(trim "$first_line")
|
||||||
|
|
||||||
|
if echo "$first_line" | grep -q "^wg://"; then
|
||||||
|
parse_proton_from_wg_url
|
||||||
|
elif echo "$first_line" | grep -q "^\[Interface\]"; then
|
||||||
|
parse_proton_from_ini
|
||||||
|
else
|
||||||
|
echo "Error: Unsupported proton.conf format (expected wg:// or [Interface])"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
PROTON_MTU=${PROTON_MTU:-1280}
|
||||||
|
|
||||||
|
if [ -z "$PROTON_PRIVATE_KEY" ] || [ -z "$PROTON_PUBLIC_KEY" ] \
|
||||||
|
|| [ -z "$PROTON_SERVER" ] || [ -z "$PROTON_PORT" ] \
|
||||||
|
|| [ -z "$PROTON_ADDRESS" ]; then
|
||||||
|
echo "Error: proton.conf is missing required fields (PrivateKey/PublicKey/Endpoint/Address)"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
ENABLE_PROTON=1
|
||||||
|
}
|
||||||
|
|
||||||
write_config() {
|
write_config() {
|
||||||
|
# Default outbound for everything that is not a hard SOCKS rule
|
||||||
|
# (TUN rules, routing lists, IP-leak sites, proxy DNS).
|
||||||
|
# Proton can only be the default when it is actually enabled.
|
||||||
|
if [ "$DEFAULT_ROUTE" = "proton" ] && [ "$ENABLE_PROTON" = "1" ]; then
|
||||||
|
DEFAULT_OUTBOUND="proton-out"
|
||||||
|
else
|
||||||
|
DEFAULT_OUTBOUND="warp-out"
|
||||||
|
fi
|
||||||
|
echo "Default route outbound: $DEFAULT_OUTBOUND" >&2
|
||||||
|
|
||||||
if [ "$ENABLE_TUN" = "1" ]; then
|
if [ "$ENABLE_TUN" = "1" ]; then
|
||||||
EXCLUDE_IFACE=$(detect_default_interface) || {
|
EXCLUDE_IFACE=$(detect_default_interface) || {
|
||||||
echo "Warning: could not detect default network interface, using eth0" >&2
|
echo "Warning: could not detect default network interface, using eth0" >&2
|
||||||
@@ -275,7 +427,7 @@ TUNEOF
|
|||||||
}
|
}
|
||||||
RULEEOF
|
RULEEOF
|
||||||
)
|
)
|
||||||
RULE_SET_RULE_PART=$(cat <<'RULEEOF'
|
RULE_SET_RULE_PART=$(cat <<RULEEOF
|
||||||
,
|
,
|
||||||
{
|
{
|
||||||
"rule_set": [
|
"rule_set": [
|
||||||
@@ -289,7 +441,7 @@ RULEEOF
|
|||||||
"canonical_MetaCubeX",
|
"canonical_MetaCubeX",
|
||||||
"launchpad_KaringX"
|
"launchpad_KaringX"
|
||||||
],
|
],
|
||||||
"outbound": "wireguard-out"
|
"outbound": "$DEFAULT_OUTBOUND"
|
||||||
}
|
}
|
||||||
RULEEOF
|
RULEEOF
|
||||||
)
|
)
|
||||||
@@ -360,6 +512,58 @@ DEFSEOF
|
|||||||
ROUTE_RULE_SET_SECTION=""
|
ROUTE_RULE_SET_SECTION=""
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
if [ "$ENABLE_PROTON" = "1" ]; then
|
||||||
|
echo "Proton enabled, adding proton-out endpoint and proton-in inbound (:3080)" >&2
|
||||||
|
WARP_IN_TAG="warp-in"
|
||||||
|
PROTON_ENDPOINT_PART=$(cat <<PROTONEOF
|
||||||
|
,
|
||||||
|
{
|
||||||
|
"type": "wireguard",
|
||||||
|
"tag": "proton-out",
|
||||||
|
"mtu": $PROTON_MTU,
|
||||||
|
"address": [
|
||||||
|
"$PROTON_ADDRESS"
|
||||||
|
],
|
||||||
|
"private_key": "$PROTON_PRIVATE_KEY",
|
||||||
|
"listen_port": 10004,
|
||||||
|
"peers": [
|
||||||
|
{
|
||||||
|
"address": "$PROTON_SERVER",
|
||||||
|
"port": $PROTON_PORT,
|
||||||
|
"public_key": "$PROTON_PUBLIC_KEY",
|
||||||
|
"allowed_ips": [$PROTON_ALLOWED_IPS]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"udp_timeout": "5m0s"
|
||||||
|
}
|
||||||
|
PROTONEOF
|
||||||
|
)
|
||||||
|
PROTON_INBOUND_PART=$(cat <<'PROTONEOF'
|
||||||
|
,
|
||||||
|
{
|
||||||
|
"type": "mixed",
|
||||||
|
"tag": "proton-in",
|
||||||
|
"listen": "0.0.0.0",
|
||||||
|
"listen_port": 3080
|
||||||
|
}
|
||||||
|
PROTONEOF
|
||||||
|
)
|
||||||
|
PROTON_ROUTE_RULE_PART=$(cat <<'PROTONEOF'
|
||||||
|
|
||||||
|
{
|
||||||
|
"inbound": "proton-in",
|
||||||
|
"outbound": "proton-out"
|
||||||
|
},
|
||||||
|
PROTONEOF
|
||||||
|
)
|
||||||
|
else
|
||||||
|
echo "Proton disabled" >&2
|
||||||
|
WARP_IN_TAG="mixed-in"
|
||||||
|
PROTON_ENDPOINT_PART=""
|
||||||
|
PROTON_INBOUND_PART=""
|
||||||
|
PROTON_ROUTE_RULE_PART=""
|
||||||
|
fi
|
||||||
|
|
||||||
if [ -n "$I1" ] || [ -n "$I2" ]; then
|
if [ -n "$I1" ] || [ -n "$I2" ]; then
|
||||||
H4_COMMA=","
|
H4_COMMA=","
|
||||||
else
|
else
|
||||||
@@ -397,7 +601,7 @@ DEFSEOF
|
|||||||
"tag": "dns-proxy",
|
"tag": "dns-proxy",
|
||||||
"type": "tls",
|
"type": "tls",
|
||||||
"server": "8.8.8.8",
|
"server": "8.8.8.8",
|
||||||
"detour": "wireguard-out"
|
"detour": "$DEFAULT_OUTBOUND"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"tag": "local",
|
"tag": "local",
|
||||||
@@ -438,14 +642,14 @@ DEFSEOF
|
|||||||
$I1_LINE
|
$I1_LINE
|
||||||
$I2_LINE
|
$I2_LINE
|
||||||
}
|
}
|
||||||
}
|
}$PROTON_ENDPOINT_PART
|
||||||
],
|
],
|
||||||
"inbounds": [
|
"inbounds": [
|
||||||
{
|
{
|
||||||
"type": "mixed",
|
"type": "mixed",
|
||||||
"tag": "mixed-in",
|
"tag": "$WARP_IN_TAG",
|
||||||
"listen_port": 2080
|
"listen_port": 2080
|
||||||
}$TUN_INBOUND_PART
|
}$PROTON_INBOUND_PART$TUN_INBOUND_PART
|
||||||
],
|
],
|
||||||
"outbounds": [
|
"outbounds": [
|
||||||
{
|
{
|
||||||
@@ -463,9 +667,9 @@ $I2_LINE
|
|||||||
"outbound": "direct"
|
"outbound": "direct"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"inbound": "mixed-in",
|
"inbound": "$WARP_IN_TAG",
|
||||||
"outbound": "wireguard-out"
|
"outbound": "warp-out"
|
||||||
},
|
},$PROTON_ROUTE_RULE_PART
|
||||||
{
|
{
|
||||||
"protocol": "dns",
|
"protocol": "dns",
|
||||||
"action": "hijack-dns"
|
"action": "hijack-dns"
|
||||||
@@ -485,7 +689,7 @@ $I2_LINE
|
|||||||
"ipecho.net",
|
"ipecho.net",
|
||||||
"ip.sb"
|
"ip.sb"
|
||||||
],
|
],
|
||||||
"outbound": "wireguard-out"
|
"outbound": "$DEFAULT_OUTBOUND"
|
||||||
}$RULE_SET_RULE_PART
|
}$RULE_SET_RULE_PART
|
||||||
],
|
],
|
||||||
$ROUTE_RULE_SET_SECTION
|
$ROUTE_RULE_SET_SECTION
|
||||||
@@ -512,11 +716,20 @@ parse_warp_conf() {
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
load_enable_tun
|
load_enable_tun
|
||||||
|
|
||||||
|
if [ -f "$PROTON_CONF" ] && [ -s "$PROTON_CONF" ]; then
|
||||||
|
parse_proton_conf
|
||||||
|
fi
|
||||||
|
|
||||||
|
load_default_route
|
||||||
|
|
||||||
write_config
|
write_config
|
||||||
}
|
}
|
||||||
|
|
||||||
# Main
|
# Main
|
||||||
|
ENABLE_PROTON=0
|
||||||
load_enable_tun
|
load_enable_tun
|
||||||
|
load_default_route
|
||||||
|
|
||||||
if [ ! -f "$WARP_CONF" ]; then
|
if [ ! -f "$WARP_CONF" ]; then
|
||||||
echo "Error: $WARP_CONF not found!"
|
echo "Error: $WARP_CONF not found!"
|
||||||
|
|||||||
@@ -0,0 +1,15 @@
|
|||||||
|
[Interface]
|
||||||
|
# Bouncing = 1
|
||||||
|
# NAT-PMP (Port Forwarding) = off
|
||||||
|
# VPN Accelerator = on
|
||||||
|
PrivateKey = {privkey}
|
||||||
|
Address = 10.2.0.2/32
|
||||||
|
DNS = 10.2.0.1
|
||||||
|
|
||||||
|
[Peer]
|
||||||
|
# SG-FREE#4
|
||||||
|
PublicKey = {pubkey}
|
||||||
|
AllowedIPs = 0.0.0.0/0, ::/0
|
||||||
|
Endpoint = 123.123.123.123:51820
|
||||||
|
|
||||||
|
PersistentKeepalive = 25
|
||||||
@@ -58,6 +58,8 @@ clean_existing_files() {
|
|||||||
rm -rf "$INSTALL_DIR/rules"
|
rm -rf "$INSTALL_DIR/rules"
|
||||||
|
|
||||||
rm -f "$CONFIG_DIR/enable-tun" 2>/dev/null || true
|
rm -f "$CONFIG_DIR/enable-tun" 2>/dev/null || true
|
||||||
|
rm -f "$CONFIG_DIR/proton.conf" 2>/dev/null || true
|
||||||
|
rm -f "$CONFIG_DIR/default-route" 2>/dev/null || true
|
||||||
rm -rf "${CACHE_DIR:?}"/*
|
rm -rf "${CACHE_DIR:?}"/*
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -79,8 +81,10 @@ prepare_reinstall() {
|
|||||||
start_service() {
|
start_service() {
|
||||||
echo "Generating config..."
|
echo "Generating config..."
|
||||||
WARP_CONF="$CONFIG_DIR/warp.conf" \
|
WARP_CONF="$CONFIG_DIR/warp.conf" \
|
||||||
|
PROTON_CONF="$CONFIG_DIR/proton.conf" \
|
||||||
OUTPUT_CONFIG="$INSTALL_DIR/config.json" \
|
OUTPUT_CONFIG="$INSTALL_DIR/config.json" \
|
||||||
ENABLE_TUN_FILE="$CONFIG_DIR/enable-tun" \
|
ENABLE_TUN_FILE="$CONFIG_DIR/enable-tun" \
|
||||||
|
DEFAULT_ROUTE_FILE="$CONFIG_DIR/default-route" \
|
||||||
"$INSTALL_DIR/generate-config.sh"
|
"$INSTALL_DIR/generate-config.sh"
|
||||||
|
|
||||||
echo "Starting ${SERVICE_NAME}..."
|
echo "Starting ${SERVICE_NAME}..."
|
||||||
@@ -122,6 +126,28 @@ printf "%s\n" "$WARP_INPUT" > "$CONFIG_DIR/warp.conf"
|
|||||||
echo ""
|
echo ""
|
||||||
echo "Configuration saved to $CONFIG_DIR/warp.conf"
|
echo "Configuration saved to $CONFIG_DIR/warp.conf"
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "=== Proton Configuration (optional) ==="
|
||||||
|
echo "Adds a second WireGuard endpoint (e.g. Proton VPN) exposed as SOCKS5 on port 3080."
|
||||||
|
echo "The main WARP proxy stays on port 2080."
|
||||||
|
read -p "Add Proton configuration? (y/n) " -n 1 -r < /dev/tty
|
||||||
|
echo
|
||||||
|
if [[ $REPLY =~ ^[Yy]$ ]]; then
|
||||||
|
echo "Paste your Proton config ([Interface]/[Peer] INI or wg://)."
|
||||||
|
echo "Finish input with Ctrl-D."
|
||||||
|
PROTON_INPUT=$(cat < /dev/tty)
|
||||||
|
if [ -z "$PROTON_INPUT" ]; then
|
||||||
|
echo "Proton input is empty, skipping Proton configuration."
|
||||||
|
rm -f "$CONFIG_DIR/proton.conf"
|
||||||
|
else
|
||||||
|
printf "%s\n" "$PROTON_INPUT" > "$CONFIG_DIR/proton.conf"
|
||||||
|
echo "Proton configuration saved to $CONFIG_DIR/proton.conf"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
rm -f "$CONFIG_DIR/proton.conf"
|
||||||
|
echo "Skipping Proton configuration."
|
||||||
|
fi
|
||||||
|
|
||||||
echo ""
|
echo ""
|
||||||
echo "=== TUN mode ==="
|
echo "=== TUN mode ==="
|
||||||
echo "TUN routes system traffic through sing-box (needs CAP_NET_ADMIN)."
|
echo "TUN routes system traffic through sing-box (needs CAP_NET_ADMIN)."
|
||||||
@@ -138,6 +164,26 @@ else
|
|||||||
echo "TUN mode disabled (SOCKS5 only)."
|
echo "TUN mode disabled (SOCKS5 only)."
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
DEFAULT_ROUTE="warp"
|
||||||
|
if [ -f "$CONFIG_DIR/proton.conf" ]; then
|
||||||
|
echo ""
|
||||||
|
echo "=== Default route ==="
|
||||||
|
echo "Choose where all non-SOCKS traffic goes (TUN rules, routing lists, IP-leak sites)."
|
||||||
|
echo "SOCKS inbounds always keep their own outbound: 2080 -> WARP, 3080 -> Proton."
|
||||||
|
echo " 1) WARP (warp-out)"
|
||||||
|
echo " 2) Proton (proton-out)"
|
||||||
|
read -p "Select default route [1/2] " -n 1 -r < /dev/tty
|
||||||
|
echo
|
||||||
|
if [[ $REPLY == "2" ]]; then
|
||||||
|
DEFAULT_ROUTE="proton"
|
||||||
|
echo "Default route: Proton (proton-out)."
|
||||||
|
else
|
||||||
|
DEFAULT_ROUTE="warp"
|
||||||
|
echo "Default route: WARP (warp-out)."
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
echo "$DEFAULT_ROUTE" > "$CONFIG_DIR/default-route"
|
||||||
|
|
||||||
echo ""
|
echo ""
|
||||||
echo "Downloading sing-box..."
|
echo "Downloading sing-box..."
|
||||||
NEED_DOWNLOAD=1
|
NEED_DOWNLOAD=1
|
||||||
@@ -203,6 +249,8 @@ User=root
|
|||||||
WorkingDirectory=/opt/sing-box-warp
|
WorkingDirectory=/opt/sing-box-warp
|
||||||
Environment="HOME=/var/cache/sing-box-warp"
|
Environment="HOME=/var/cache/sing-box-warp"
|
||||||
Environment="WARP_CONF=/etc/sing-box-warp/warp.conf"
|
Environment="WARP_CONF=/etc/sing-box-warp/warp.conf"
|
||||||
|
Environment="PROTON_CONF=/etc/sing-box-warp/proton.conf"
|
||||||
|
Environment="DEFAULT_ROUTE_FILE=/etc/sing-box-warp/default-route"
|
||||||
Environment="OUTPUT_CONFIG=/opt/sing-box-warp/config.json"
|
Environment="OUTPUT_CONFIG=/opt/sing-box-warp/config.json"
|
||||||
ExecStartPre=/opt/sing-box-warp/generate-config.sh
|
ExecStartPre=/opt/sing-box-warp/generate-config.sh
|
||||||
ExecStart=/usr/local/bin/sing-box run -c /opt/sing-box-warp/config.json
|
ExecStart=/usr/local/bin/sing-box run -c /opt/sing-box-warp/config.json
|
||||||
|
|||||||
Reference in New Issue
Block a user