#!/bin/sh
set -e
CLIENT_NAME="{{CLIENT_NAME}}"
PROTOCOL="{{PROTOCOL}}"
PHOBOS_DIR=""
ROUTER_PLATFORM=""
SLOT=""
LPORT=""
. "$(dirname "$0")/lib-client.sh"
. "$(dirname "$0")/install-obfuscator.sh"
. "$(dirname "$0")/install-wireguard.sh"
PHASE_TOTAL=3
phase_start() {
msg ""
msg "[${1}/${PHASE_TOTAL}] ${2}..."
}
phase_ok() {
msg "[${1}/${PHASE_TOTAL}] ✓ ${2}"
}
phase_fail() {
msg "[${1}/${PHASE_TOTAL}] ✗ ${2}"
}
detect_3xui_mode() {
local platform="$1"
[ "$platform" = "linux" ] || { echo "false"; return; }
[ "$(detect_arch)" = "x86_64" ] || { echo "false"; return; }
if command -v systemctl >/dev/null 2>&1 && systemctl is-active --quiet x-ui 2>/dev/null; then
echo "true"; return
fi
for _db in /etc/x-ui/x-ui.db /usr/local/x-ui/x-ui.db /opt/x-ui/x-ui.db; do
[ -f "$_db" ] && { echo "true"; return; }
done
command -v x-ui >/dev/null 2>&1 && { echo "true"; return; }
echo "false"
}
check_dependencies() {
local platform="$1"
local deps
case "$platform" in
keenetic) deps="grep cut date tar curl jq" ;;
openwrt) deps="grep cut date tar uci" ;;
*) deps="grep cut date tar" ;;
esac
local missing=""
for cmd in $deps; do
command -v "$cmd" >/dev/null 2>&1 || missing="$missing $cmd"
done
[ -z "$missing" ] && return 0
if [ -z "$PKG_MGR" ]; then
msg "ОШИБКА: отсутствуют утилиты:${missing} — установите вручную"
return 1
fi
pkg_update >/dev/null 2>&1 || true
for cmd in $missing; do
pkg_install "$cmd" >/dev/null 2>&1 || true
done
return 0
}
setup_configs() {
mkdir -p "$PHOBOS_DIR"
cp wg-obfuscator.conf "$PHOBOS_DIR/${OBF_CONF_NAME}"
chmod 600 "$PHOBOS_DIR/${OBF_CONF_NAME}"
cp "${CLIENT_NAME}.conf" "$PHOBOS_DIR/${CLIENT_NAME}.conf"
chmod 600 "$PHOBOS_DIR/${CLIENT_NAME}.conf"
sed -i "s/^source-lport = .*/source-lport = ${LPORT}/" "$PHOBOS_DIR/${OBF_CONF_NAME}"
sed -i "s/^Endpoint = 127\.0\.0\.1:.*/Endpoint = 127.0.0.1:${LPORT}/" "$PHOBOS_DIR/${CLIENT_NAME}.conf"
}
setup_configs_socks5() {
mkdir -p "$PHOBOS_DIR"
cp wg-socks5-obfuscator.conf "$PHOBOS_DIR/${OBF_CONF_NAME}"
chmod 600 "$PHOBOS_DIR/${OBF_CONF_NAME}"
sed -i "s/^source-lport = .*/source-lport = ${LPORT}/" "$PHOBOS_DIR/${OBF_CONF_NAME}"
}
allocate_slot() {
local existing
existing=$(registry_line_for_client "$CLIENT_NAME")
if [ -n "$existing" ]; then
SLOT=$(registry_field "$existing" 2)
LPORT=$(registry_field "$existing" 3)
else
SLOT=$(registry_alloc_slot)
LPORT=$(registry_alloc_port 13255)
fi
compute_slot_names "$SLOT"
}
register_client() {
local target masking iface_ref
target=$(grep '^target' "$PHOBOS_DIR/${OBF_CONF_NAME}" 2>/dev/null | head -1 | cut -d'=' -f2 | tr -d ' ')
masking=$(grep '^masking' "$PHOBOS_DIR/${OBF_CONF_NAME}" 2>/dev/null | head -1 | cut -d'=' -f2 | tr -d ' ')
if [ "$ROUTER_PLATFORM" = "keenetic" ]; then
iface_ref="Phobos-${CLIENT_NAME}"
else
iface_ref="${OBF_WG_IFACE}"
fi
registry_remove_client "$CLIENT_NAME"
registry_add "${CLIENT_NAME}|${SLOT}|${LPORT}|${OBF_CONF_NAME}|${OBF_BINARY_NAME}|${OBF_INIT_NAME}|${OBF_SERVICE_NAME}|${iface_ref}|${target}|${masking}|$(date '+%Y-%m-%d %H:%M:%S')"
}
deploy_lib_client() {
[ -f "lib-client.sh" ] && cp "lib-client.sh" "$PHOBOS_DIR/lib-client.sh"
}
deploy_uninstall_script() {
if [ -f "phobos-uninstall.sh" ]; then
cp "phobos-uninstall.sh" "$PHOBOS_DIR/phobos-uninstall.sh"
chmod +x "$PHOBOS_DIR/phobos-uninstall.sh"
fi
}
verify_obfuscator_service() {
[ -f "/etc/systemd/system/${OBF_SERVICE_NAME}.service" ] || return 1
systemctl is-enabled --quiet "${OBF_SERVICE_NAME}" 2>/dev/null || return 1
systemctl is-active --quiet "${OBF_SERVICE_NAME}" 2>/dev/null || return 1
}
_json_str_array() {
local raw="$1" indent="$2"
local result="" item first=1 _ifs
_ifs="$IFS"
IFS=','
for item in $raw; do
IFS="$_ifs"
item=$(printf '%s' "$item" | tr -d ' \t')
if [ -n "$item" ]; then
if [ "$first" = "1" ]; then
result="${indent}\"${item}\""; first=0
else
result="${result},
${indent}\"${item}\""
fi
fi
IFS=','
done
IFS="$_ifs"
printf '%s' "$result"
}
print_xray_wireguard_json() {
local conf="${PHOBOS_DIR}/${CLIENT_NAME}.conf"
local secret_key mtu public_key preshared_key keepalive raw_addr raw_allowed
secret_key=$( grep '^PrivateKey' "$conf" | head -1 | cut -d'=' -f2- | tr -d ' \t\r\n')
mtu=$( grep '^MTU' "$conf" | head -1 | cut -d'=' -f2 | tr -d ' \t\r\n')
public_key=$( grep '^PublicKey' "$conf" | head -1 | cut -d'=' -f2- | tr -d ' \t\r\n')
preshared_key=$(grep -E '^PresharedKey|^PreSharedKey' "$conf" | head -1 | cut -d'=' -f2- | tr -d ' \t\r\n')
keepalive=$( grep '^PersistentKeepalive' "$conf" | head -1 | cut -d'=' -f2 | tr -d ' \t\r\n')
raw_addr=$( grep '^Address' "$conf" | head -1 | cut -d'=' -f2- | tr -d '\t\r\n')
raw_allowed=$( grep '^AllowedIPs' "$conf" | head -1 | cut -d'=' -f2- | tr -d '\t\r\n')
[ -z "$mtu" ] && mtu=1420
[ -z "$keepalive" ] && keepalive=0
local addr_arr allowed_arr
addr_arr=$( _json_str_array "$raw_addr" " ")
allowed_arr=$( _json_str_array "$raw_allowed" " ")
printf '{
"protocol": "wireguard",
"settings": {
"mtu": %s,
"secretKey": "%s",
"address": [
%s
],
"workers": 2,
"peers": [
{
"publicKey": "%s",
"preSharedKey": "%s",
"allowedIPs": [
%s
],
"endpoint": "127.0.0.1:%s",
"keepAlive": %s
}
],
"noKernelTun": false
},
"tag": "Phobos-%s"
}
' "$mtu" "$secret_key" "$addr_arr" \
"$public_key" "$preshared_key" "$allowed_arr" \
"$LPORT" "$keepalive" "$CLIENT_NAME"
}
print_xray_socks5_json() {
printf '{
"protocol": "socks",
"settings": {
"servers": [
{
"address": "127.0.0.1",
"port": %s,
"users": [
{
"user": "%s",
"pass": "%s"
}
]
}
]
},
"tag": "Phobos-%s"
}
' "$LPORT" "$SOCKS5_LOGIN" "$SOCKS5_PASSWORD" "$CLIENT_NAME"
}
extract_wireguard_params() {
local config_file="$PHOBOS_DIR/${CLIENT_NAME}.conf"
WG_PRIVATE_KEY=$(grep '^PrivateKey' "$config_file" | cut -d'=' -f2- | tr -d ' \t\n\r')
WG_ADDRESS=$(grep '^Address' "$config_file" | cut -d'=' -f2- | tr -d ' \t\n\r')
WG_SERVER_PUBKEY=$(grep '^PublicKey' "$config_file" | cut -d'=' -f2- | tr -d ' \t\n\r')
WG_PRESHARED_KEY=$(
grep -E '^PresharedKey|^PreSharedKey' "$config_file" |
head -1 |
cut -d'=' -f2- |
tr -d ' \t\n\r'
)
WG_ENDPOINT_PORT=$(grep '^Endpoint' "$config_file" | cut -d':' -f2 | tr -d ' \t\n\r')
CLIENT_IP=$(echo "$WG_ADDRESS" | cut -d',' -f1 | tr -d ' ')
CLIENT_IPV6=$(echo "$WG_ADDRESS" | cut -d',' -f2 | tr -d ' ')
if [ -z "$CLIENT_IPV6" ] || [ "$CLIENT_IPV6" = "$CLIENT_IP" ]; then
CLIENT_IPV6=$(grep -A 10 '\[Interface\]' "$config_file" | grep '^Address' | grep -o 'fd[0-9a-f:\/]*' | head -1)
fi
[ -z "$CLIENT_IPV6" ] && CLIENT_IPV6="none"
[ -z "$WG_ENDPOINT_PORT" ] && WG_ENDPOINT_PORT=13255
if [ -z "$WG_PRESHARED_KEY" ]; then
msg " PrivateKey: $(printf '%s' "$WG_PRIVATE_KEY" | cut -c1-20)..."
msg " Address: $WG_ADDRESS"
msg " PublicKey: $(printf '%s' "$WG_SERVER_PUBKEY" | cut -c1-20)..."
msg " EndpointPort: $WG_ENDPOINT_PORT"
msg "ОШИБКА: PresharedKey не найден в ${config_file}"
return 1
fi
}
install_wireguard_openwrt() {
command -v wg >/dev/null 2>&1 && return 0
pkg_update >/dev/null 2>&1 || true
pkg_install kmod-wireguard wireguard-tools luci-proto-wireguard >/dev/null 2>&1
}
install_redsocks_openwrt() {
if [ -x /usr/sbin/redsocks ] || command -v redsocks >/dev/null 2>&1; then
return 0
fi
pkg_update >/dev/null 2>&1 || true
pkg_install redsocks >/dev/null 2>&1 || true
[ -x /usr/sbin/redsocks ] || command -v redsocks >/dev/null 2>&1
}
configure_wireguard_rci() {
extract_wireguard_params || return 1
[ -f "./router-configure-wireguard.sh" ] || return 1
chmod +x ./router-configure-wireguard.sh
local _log="${PHOBOS_DIR}/.rci.log"
if ./router-configure-wireguard.sh \
--client-name "$CLIENT_NAME" \
--client-private-key "$WG_PRIVATE_KEY" \
--client-ip "$CLIENT_IP" \
--client-ipv6 "$CLIENT_IPV6" \
--server-public-key "$WG_SERVER_PUBKEY" \
--preshared-key "$WG_PRESHARED_KEY" \
--endpoint-port "$WG_ENDPOINT_PORT" \
--keepalive 25 \
--mtu 1420 \
--fallback-config "$PHOBOS_DIR/${CLIENT_NAME}.conf" >"$_log" 2>&1; then
rm -f "$_log"
return 0
fi
cat "$_log" 2>/dev/null || true
rm -f "$_log"
return 1
}
load_socks5_credentials() {
[ -f "socks5-credentials.env" ] || return 1
. ./socks5-credentials.env
[ -n "$SOCKS5_LOGIN" ] && [ -n "$SOCKS5_PASSWORD" ]
}
configure_socks5_rci() {
load_socks5_credentials || return 1
[ -f "./router-configure-socks5-keenetic.sh" ] || return 1
chmod +x ./router-configure-socks5-keenetic.sh
local _log="${PHOBOS_DIR}/.rci.log"
if ./router-configure-socks5-keenetic.sh \
--client-name "$CLIENT_NAME" \
--upstream-host "127.0.0.1" \
--upstream-port "$LPORT" \
--login "$SOCKS5_LOGIN" \
--password "$SOCKS5_PASSWORD" \
--fallback-config "$PHOBOS_DIR/${OBF_CONF_NAME}" >"$_log" 2>&1; then
rm -f "$_log"
return 0
fi
cat "$_log" 2>/dev/null || true
rm -f "$_log"
return 1
}
configure_socks5_openwrt() {
load_socks5_credentials || return 1
[ -f "./router-configure-socks5-openwrt.sh" ] || return 1
chmod +x ./router-configure-socks5-openwrt.sh
local target server_ip
target=$(grep '^target' "$PHOBOS_DIR/${OBF_CONF_NAME}" 2>/dev/null | head -1 | cut -d'=' -f2 | tr -d ' ')
server_ip="${target%:*}"
local _log="${PHOBOS_DIR}/.uci.log"
if ./router-configure-socks5-openwrt.sh \
--client-name "$CLIENT_NAME" \
--obf-port "$LPORT" \
--login "$SOCKS5_LOGIN" \
--password "$SOCKS5_PASSWORD" \
--server-ip "$server_ip" >"$_log" 2>&1; then
rm -f "$_log"
return 0
fi
cat "$_log" 2>/dev/null || true
rm -f "$_log"
return 1
}
configure_wireguard_openwrt() {
extract_wireguard_params || return 1
[ -f "./router-configure-wireguard-openwrt.sh" ] || return 1
chmod +x ./router-configure-wireguard-openwrt.sh
local _log="${PHOBOS_DIR}/.uci.log"
if ./router-configure-wireguard-openwrt.sh \
--client-name "$CLIENT_NAME" \
--interface "$OBF_WG_IFACE" \
--client-private-key "$WG_PRIVATE_KEY" \
--client-ip "$CLIENT_IP" \
--client-ipv6 "$CLIENT_IPV6" \
--server-public-key "$WG_SERVER_PUBKEY" \
--preshared-key "$WG_PRESHARED_KEY" \
--endpoint-port "$WG_ENDPOINT_PORT" \
--keepalive 25 \
--mtu 1420 \
--fallback-config "$PHOBOS_DIR/${CLIENT_NAME}.conf" >"$_log" 2>&1; then
rm -f "$_log"
return 0
fi
cat "$_log" 2>/dev/null || true
rm -f "$_log"
return 1
}
show_3xui_final_info() {
msg ""
msg "Файлы:"
msg "${PHOBOS_DIR}/"
msg "├─ ${CLIENT_NAME}.conf — конфигурация WireGuard клиента"
msg "├─ ${OBF_CONF_NAME} — конфигурация обфускатора (порт ${LPORT})"
msg "└─ phobos-uninstall.sh — скрипт удаления PhobosWG"
msg ""
msg "/usr/local/bin/${OBF_BINARY_NAME}"
msg "/etc/systemd/system/${OBF_SERVICE_NAME}.service"
msg ""
msg "Управление:"
msg " systemctl status ${OBF_SERVICE_NAME}"
msg " systemctl restart ${OBF_SERVICE_NAME}"
msg " ${PHOBOS_DIR}/phobos-uninstall.sh"
msg ""
msg "─────────────────────────────────────────────────"
msg "WireGuard outbound для 3x-ui (добавить вручную):"
msg "─────────────────────────────────────────────────"
print_xray_wireguard_json
msg "─────────────────────────────────────────────────"
}
show_3xui_socks5_final_info() {
msg ""
msg "Файлы:"
msg "${PHOBOS_DIR}/"
msg "├─ ${OBF_CONF_NAME} — конфигурация обфускатора SOCKS5 (порт ${LPORT})"
msg "└─ phobos-uninstall.sh — скрипт удаления PhobosWG"
msg ""
msg "/usr/local/bin/${OBF_BINARY_NAME}"
msg "/etc/systemd/system/${OBF_SERVICE_NAME}.service"
msg ""
msg "Управление:"
msg " systemctl status ${OBF_SERVICE_NAME}"
msg " systemctl restart ${OBF_SERVICE_NAME}"
msg " ${PHOBOS_DIR}/phobos-uninstall.sh"
msg ""
msg "Локальный SOCKS5-прокси: 127.0.0.1:${LPORT} (логин ${SOCKS5_LOGIN} / пароль ${SOCKS5_PASSWORD})"
msg ""
msg "─────────────────────────────────────────────────"
msg "SOCKS outbound для 3x-ui (добавить вручную):"
msg "─────────────────────────────────────────────────"
print_xray_socks5_json
msg "─────────────────────────────────────────────────"
}
show_keenetic_final_info() {
local rci_ok="$1"
msg ""
msg "Файлы:"
msg "${PHOBOS_DIR}/"
msg "├─ ${CLIENT_NAME}.conf — конфигурация WireGuard клиента"
msg "├─ ${OBF_CONF_NAME} — конфигурация обфускатора (порт ${LPORT})"
msg "└─ phobos-uninstall.sh — скрипт удаления PhobosWG"
msg ""
msg "/opt/bin/${OBF_BINARY_NAME}"
msg "/opt/etc/init.d/${OBF_INIT_NAME}"
msg ""
msg "Управление:"
msg " /opt/etc/init.d/${OBF_INIT_NAME} status"
msg " /opt/etc/init.d/${OBF_INIT_NAME} restart"
msg " ${PHOBOS_DIR}/phobos-uninstall.sh"
if [ "$rci_ok" != "1" ]; then
msg ""
msg "Ручная настройка WireGuard (Keenetic):"
msg " 1. Веб-панель → Интернет → Другие подключения"
msg " 2. WireGuard → Загрузить конфигурацию из файла"
msg " 3. Файл: ${PHOBOS_DIR}/${CLIENT_NAME}.conf"
msg " 4. Активируйте подключение"
fi
}
show_keenetic_socks5_final_info() {
local rci_ok="$1"
msg ""
msg "Файлы:"
msg "${PHOBOS_DIR}/"
msg "├─ ${OBF_CONF_NAME} — конфигурация обфускатора (порт ${LPORT})"
msg "└─ phobos-uninstall.sh — скрипт удаления PhobosWG"
msg ""
msg "/opt/bin/${OBF_BINARY_NAME}"
msg "/opt/etc/init.d/${OBF_INIT_NAME}"
msg ""
msg "Управление:"
msg " /opt/etc/init.d/${OBF_INIT_NAME} status"
msg " /opt/etc/init.d/${OBF_INIT_NAME} restart"
msg " ${PHOBOS_DIR}/phobos-uninstall.sh"
if [ "$rci_ok" != "1" ]; then
msg ""
msg "Ручная настройка SOCKS5 Proxy (Keenetic):"
msg " 1. Веб-панель → Интернет → Другие подключения → Добавить подключение"
msg " 2. Тип: Proxy, протокол SOCKS5"
msg " 3. Upstream: 127.0.0.1:${LPORT}"
msg " 4. Логин/пароль — см. страницу клиента в панели PhobosWG"
msg " 5. Активируйте подключение"
fi
}
show_openwrt_final_info() {
local uci_ok="$1"
local init_path="$2"
msg ""
msg "Файлы:"
msg "${PHOBOS_DIR}/"
msg "├─ ${CLIENT_NAME}.conf — конфигурация WireGuard клиента"
msg "├─ ${OBF_CONF_NAME} — конфигурация обфускатора (порт ${LPORT})"
msg "└─ phobos-uninstall.sh — скрипт удаления PhobosWG"
msg ""
msg "/usr/bin/${OBF_BINARY_NAME}"
msg "${init_path}"
msg ""
msg "Управление:"
msg " ${init_path} status"
msg " ${init_path} restart"
msg " ${PHOBOS_DIR}/phobos-uninstall.sh"
if [ "$uci_ok" != "1" ]; then
msg ""
msg "Ручная настройка WireGuard (OpenWRT):"
msg " 1. LuCI → Network → Interfaces → Add new"
msg " 2. Протокол: WireGuard VPN"
msg " 3. Параметры из файла: ${PHOBOS_DIR}/${CLIENT_NAME}.conf"
msg " 4. Настройте firewall zone"
fi
}
show_openwrt_socks5_final_info() {
local ok="$1"
local init_path="$2"
msg ""
msg "Файлы:"
msg "${PHOBOS_DIR}/"
msg "├─ ${OBF_CONF_NAME} — конфигурация обфускатора SOCKS5 (порт ${LPORT})"
msg "└─ phobos-uninstall.sh — скрипт удаления PhobosWG"
msg ""
msg "/usr/bin/${OBF_BINARY_NAME}"
msg "${init_path}"
msg "/etc/redsocks.conf — транспарентный SOCKS5-редирект"
msg "/etc/nftables.d/30-phobos-socks5.nft — правило редиректа (fw4)"
msg ""
msg "Управление:"
msg " ${init_path} status"
msg " /etc/init.d/redsocks status"
msg " ${PHOBOS_DIR}/phobos-uninstall.sh"
if [ "$ok" = "1" ]; then
msg ""
msg "TCP-трафик из LAN прозрачно идёт через SOCKS5 → сервер."
else
msg ""
msg "Ручная настройка SOCKS5 (OpenWRT):"
msg " 1. Установите redsocks (${PKG_MGR} install redsocks)"
msg " 2. /etc/redsocks.conf → upstream 127.0.0.1:${LPORT}, type socks5, login/пароль клиента"
msg " 3. nft redirect для LAN TCP → порт redsocks (см. router-configure-socks5-openwrt.sh)"
fi
}
show_linux_final_info() {
msg ""
msg "Файлы:"
msg "${PHOBOS_DIR}/"
msg "├─ ${CLIENT_NAME}.conf — конфигурация WireGuard клиента"
msg "├─ ${OBF_CONF_NAME} — конфигурация обфускатора (порт ${LPORT})"
msg "└─ phobos-uninstall.sh — скрипт удаления PhobosWG"
msg ""
msg "/usr/local/bin/${OBF_BINARY_NAME}"
msg "/etc/systemd/system/${OBF_SERVICE_NAME}.service"
msg "/etc/wireguard/${OBF_WG_IFACE}.conf"
msg ""
msg "Управление:"
msg " systemctl status ${OBF_SERVICE_NAME}"
msg " systemctl status wg-quick@${OBF_WG_IFACE}"
msg " ${PHOBOS_DIR}/phobos-uninstall.sh"
}
_run_3xui() {
PHASE_TOTAL=3
phase_start 1 "Установка службы обфускатора"
install_obfuscator "$ARCH"
setup_configs
if create_systemd_obfuscator_service; then
phase_ok 1 "wg-obfuscator → /usr/local/bin/${OBF_BINARY_NAME}"
else
phase_fail 1 "служба создана, но не запустилась (таймаут 10 сек)"
fi
phase_start 2 "Проверка ${OBF_SERVICE_NAME}"
if verify_obfuscator_service; then
phase_ok 2 "служба установлена, включена и запущена"
else
phase_fail 2 "служба не полностью активирована — systemctl status ${OBF_SERVICE_NAME}"
fi
phase_start 3 "Сохранение файлов"
register_client
deploy_lib_client
deploy_uninstall_script
phase_ok 3 "файлы сохранены в ${PHOBOS_DIR}"
show_3xui_final_info
}
_run_3xui_socks5() {
PHASE_TOTAL=3
load_socks5_credentials || true
phase_start 1 "Установка службы обфускатора SOCKS5"
install_obfuscator "$ARCH"
setup_configs_socks5
if create_systemd_obfuscator_service; then
phase_ok 1 "wg-obfuscator → /usr/local/bin/${OBF_BINARY_NAME}"
else
phase_fail 1 "служба создана, но не запустилась (таймаут 10 сек)"
fi
phase_start 2 "Проверка ${OBF_SERVICE_NAME}"
if verify_obfuscator_service; then
phase_ok 2 "служба установлена, включена и запущена"
else
phase_fail 2 "служба не полностью активирована — systemctl status ${OBF_SERVICE_NAME}"
fi
phase_start 3 "Сохранение файлов"
register_client
deploy_lib_client
deploy_uninstall_script
phase_ok 3 "файлы сохранены в ${PHOBOS_DIR}"
show_3xui_socks5_final_info
}
_run_keenetic() {
PHASE_TOTAL=3
local rci_ok=0
phase_start 1 "Установка обфускатора"
install_obfuscator "$ARCH"
setup_configs
create_init_script
if start_obfuscator; then
phase_ok 1 "wg-obfuscator запущен → /opt/bin/${OBF_BINARY_NAME}"
else
phase_fail 1 "wg-obfuscator не запущен — /opt/etc/init.d/${OBF_INIT_NAME} status"
fi
phase_start 2 "Настройка WireGuard (RCI API)"
if configure_wireguard_rci; then
rci_ok=1
phase_ok 2 "интерфейс Phobos-${CLIENT_NAME} создан"
else
phase_fail 2 "WireGuard не настроен — потребуется ручная конфигурация"
fi
phase_start 3 "Сохранение файлов"
register_client
deploy_lib_client
deploy_uninstall_script
phase_ok 3 "файлы сохранены в ${PHOBOS_DIR}"
show_keenetic_final_info "$rci_ok"
}
_run_keenetic_socks5() {
PHASE_TOTAL=3
local rci_ok=0
phase_start 1 "Установка обфускатора"
install_obfuscator "$ARCH"
setup_configs_socks5
create_init_script
if start_obfuscator; then
phase_ok 1 "wg-obfuscator запущен → /opt/bin/${OBF_BINARY_NAME}"
else
phase_fail 1 "wg-obfuscator не запущен — /opt/etc/init.d/${OBF_INIT_NAME} status"
fi
phase_start 2 "Настройка SOCKS5 Proxy (RCI API)"
if configure_socks5_rci; then
rci_ok=1
phase_ok 2 "интерфейс Phobos-${CLIENT_NAME} создан"
else
phase_fail 2 "SOCKS5 Proxy не настроен — потребуется ручная конфигурация"
fi
phase_start 3 "Сохранение файлов"
register_client
deploy_lib_client
deploy_uninstall_script
phase_ok 3 "файлы сохранены в ${PHOBOS_DIR}"
show_keenetic_socks5_final_info "$rci_ok"
}
_run_openwrt() {
PHASE_TOTAL=4
local uci_ok=0
local init_path=""
phase_start 1 "Установка пакетов WireGuard"
if install_wireguard_openwrt; then
phase_ok 1 "kmod-wireguard + wireguard-tools"
else
phase_fail 1 "не удалось установить пакеты WireGuard"
fi
phase_start 2 "Установка обфускатора"
install_obfuscator "$ARCH"
setup_configs
if [ -d "/opt/etc" ]; then
create_init_script
init_path="/opt/etc/init.d/${OBF_INIT_NAME}"
else
create_procd_init_script
init_path="/etc/init.d/${OBF_SERVICE_NAME}"
fi
if start_obfuscator; then
phase_ok 2 "wg-obfuscator запущен → /usr/bin/${OBF_BINARY_NAME}"
else
phase_fail 2 "wg-obfuscator не запущен — ${init_path} status"
fi
phase_start 3 "Настройка WireGuard (UCI)"
if configure_wireguard_openwrt; then
uci_ok=1
phase_ok 3 "интерфейс ${OBF_WG_IFACE} создан"
else
phase_fail 3 "WireGuard не настроен — потребуется ручная конфигурация"
fi
phase_start 4 "Сохранение файлов"
register_client
deploy_lib_client
deploy_uninstall_script
phase_ok 4 "файлы сохранены в ${PHOBOS_DIR}"
show_openwrt_final_info "$uci_ok" "$init_path"
}
_run_openwrt_socks5() {
PHASE_TOTAL=4
local proxy_ok=0
local init_path=""
phase_start 1 "Установка redsocks"
if install_redsocks_openwrt; then
phase_ok 1 "redsocks установлен"
else
phase_fail 1 "не удалось установить redsocks — потребуется ручная настройка"
fi
phase_start 2 "Установка обфускатора"
install_obfuscator "$ARCH"
setup_configs_socks5
if [ -d "/opt/etc" ]; then
create_init_script
init_path="/opt/etc/init.d/${OBF_INIT_NAME}"
else
create_procd_init_script
init_path="/etc/init.d/${OBF_SERVICE_NAME}"
fi
if start_obfuscator; then
phase_ok 2 "wg-obfuscator запущен → /usr/bin/${OBF_BINARY_NAME}"
else
phase_fail 2 "wg-obfuscator не запущен — ${init_path} status"
fi
phase_start 3 "Настройка SOCKS5 (redsocks + nft redirect)"
if configure_socks5_openwrt; then
proxy_ok=1
phase_ok 3 "транспарентный SOCKS5-редирект активен"
else
phase_fail 3 "SOCKS5 не настроен — потребуется ручная конфигурация"
fi
phase_start 4 "Сохранение файлов"
register_client
deploy_lib_client
deploy_uninstall_script
phase_ok 4 "файлы сохранены в ${PHOBOS_DIR}"
show_openwrt_socks5_final_info "$proxy_ok" "$init_path"
}
_run_linux() {
PHASE_TOTAL=4
phase_start 1 "Установка WireGuard"
if install_wireguard_linux; then
phase_ok 1 "WireGuard установлен"
else
msg "ОШИБКА: не удалось установить WireGuard"
exit 1
fi
phase_start 2 "Установка обфускатора"
install_obfuscator "$ARCH"
setup_configs
if create_systemd_obfuscator_service; then
phase_ok 2 "wg-obfuscator → /usr/local/bin/${OBF_BINARY_NAME}"
else
phase_fail 2 "служба создана, но не запустилась (таймаут 10 сек)"
fi
phase_start 3 "Настройка WireGuard"
if configure_wireguard_linux; then
configure_ufw_linux
phase_ok 3 "интерфейс ${OBF_WG_IFACE} настроен через systemd"
else
phase_fail 3 "WireGuard настроен с предупреждениями — systemctl status wg-quick@${OBF_WG_IFACE}"
fi
phase_start 4 "Сохранение файлов"
register_client
deploy_lib_client
deploy_uninstall_script
phase_ok 4 "файлы сохранены в ${PHOBOS_DIR}"
show_linux_final_info
}
main() {
ROUTER_PLATFORM=$(detect_router_platform)
PHOBOS_DIR=$(detect_phobos_dir "$ROUTER_PLATFORM")
IS_3XUI_MODE=$(detect_3xui_mode "$ROUTER_PLATFORM")
detect_pkg_manager
if [ "$ROUTER_PLATFORM" = "unknown" ]; then
msg "ОШИБКА: Неподдерживаемая платформа ($(uname -a))"
msg "Поддерживаются: Keenetic, OpenWRT, Linux (Ubuntu/Debian)"
exit 1
fi
if [ "$PROTOCOL" = "socks5" ] && [ "$ROUTER_PLATFORM" != "keenetic" ] && \
[ "$ROUTER_PLATFORM" != "openwrt" ] && [ "$IS_3XUI_MODE" != "true" ]; then
msg "Автоматическая установка SOCKS5 для платформы ${ROUTER_PLATFORM} пока не поддерживается."
msg "Используйте wg-socks5-obfuscator.conf и бинарник из bin/ вручную (см. README.txt)."
exit 0
fi
check_root
mkdir -p "$PHOBOS_DIR"
allocate_slot
ARCH=$(detect_arch)
if [ "$ARCH" = "unknown" ]; then
msg "ОШИБКА: Неподдерживаемая архитектура ($(uname -m))"
exit 1
fi
if [ "$IS_3XUI_MODE" = "true" ]; then
MODE_LABEL="3x-ui"
elif [ "$ROUTER_PLATFORM" = "keenetic" ]; then
MODE_LABEL="роутер"
elif [ "$ROUTER_PLATFORM" = "openwrt" ]; then
MODE_LABEL="OpenWRT"
else
MODE_LABEL="linux"
fi
msg "PhobosWG · клиент: ${CLIENT_NAME} · ${ROUTER_PLATFORM} (${ARCH}) · ${MODE_LABEL} · ${PHOBOS_DIR}"
if ! check_dependencies "$ROUTER_PLATFORM"; then
exit 1
fi
if [ "$ROUTER_PLATFORM" = "keenetic" ] && [ "$PROTOCOL" = "socks5" ]; then
_run_keenetic_socks5
elif [ "$ROUTER_PLATFORM" = "keenetic" ]; then
_run_keenetic
elif [ "$ROUTER_PLATFORM" = "openwrt" ] && [ "$PROTOCOL" = "socks5" ]; then
_run_openwrt_socks5
elif [ "$ROUTER_PLATFORM" = "openwrt" ]; then
_run_openwrt
elif [ "$IS_3XUI_MODE" = "true" ] && [ "$PROTOCOL" = "socks5" ]; then
_run_3xui_socks5
elif [ "$IS_3XUI_MODE" = "true" ]; then
_run_3xui
else
_run_linux
fi
}
main "$@"