Files
PCA_Phobos/overlay/phobos-uninstall.sh
2026-06-12 12:21:26 +03:00

544 lines
18 KiB
Bash
Executable File
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/bin/sh
set -e
PHOBOS_DIR=""
ROUTER_PLATFORM=""
SELECTED_CONF=""
IS_FULL_REMOVAL="1"
OBFUSCATOR_CONFIGS=""
OBFUSCATOR_CONFIG_COUNT=0
. "$(dirname "$0")/lib-client.sh"
collect_obf_configs() {
OBFUSCATOR_CONFIGS=""
OBFUSCATOR_CONFIG_COUNT=0
[ -d "$PHOBOS_DIR" ] || return
for f in "$PHOBOS_DIR"/wg-obfuscator*.conf; do
[ -f "$f" ] || continue
OBFUSCATOR_CONFIGS="${OBFUSCATOR_CONFIGS}$(basename "$f" .conf) "
OBFUSCATOR_CONFIG_COUNT=$((OBFUSCATOR_CONFIG_COUNT + 1))
done
}
get_config_label() {
local obf_conf_base="$1"
local idx_suffix="${obf_conf_base#wg-obfuscator}"
local wg_iface="phobos${idx_suffix}"
local addr=""
if [ -f "/etc/wireguard/${wg_iface}.conf" ]; then
addr=$(grep '^Address' "/etc/wireguard/${wg_iface}.conf" 2>/dev/null | cut -d'=' -f2 | tr -d ' ' | cut -d'/' -f1 | cut -d',' -f1) || addr=""
fi
if [ -n "$addr" ]; then
printf "%s [интерфейс: %s, адрес: %s]" "$obf_conf_base" "$wg_iface" "$addr"
else
printf "%s" "$obf_conf_base"
fi
}
select_config_to_remove() {
collect_obf_configs
if [ "$OBFUSCATOR_CONFIG_COUNT" -eq 0 ]; then
IS_FULL_REMOVAL="1"
SELECTED_CONF="all"
return
fi
if [ "$OBFUSCATOR_CONFIG_COUNT" -eq 1 ]; then
SELECTED_CONF=$(echo "$OBFUSCATOR_CONFIGS" | tr -s ' ' '\n' | grep -v '^$' | head -1)
IS_FULL_REMOVAL="1"
log "Обнаружена конфигурация: ${SELECTED_CONF}"
return
fi
log ""
log "Обнаружено несколько конфигураций:"
log ""
local i=1
for conf_base in $OBFUSCATOR_CONFIGS; do
local label
label=$(get_config_label "$conf_base")
log " ${i}) ${label}"
i=$((i + 1))
done
local all_num=$i
log " ${all_num}) Удалить все"
log ""
printf "Введите номер конфигурации для удаления: "
read -r answer || answer=""
case "$answer" in
''|*[!0-9]*)
log "ОШИБКА: Неверный ввод"
exit 1
;;
esac
if [ "$answer" -eq "$all_num" ]; then
IS_FULL_REMOVAL="1"
SELECTED_CONF="all"
return
fi
if [ "$answer" -lt 1 ] || [ "$answer" -ge "$all_num" ]; then
log "ОШИБКА: Номер вне диапазона"
exit 1
fi
local selected_i=1
for conf_base in $OBFUSCATOR_CONFIGS; do
if [ "$selected_i" -eq "$answer" ]; then
SELECTED_CONF="$conf_base"
IS_FULL_REMOVAL="0"
return
fi
selected_i=$((selected_i + 1))
done
}
remove_single_obfuscator_instance() {
local obf_conf_base="$1"
local idx_suffix="${obf_conf_base#wg-obfuscator}"
local binary_name="wg-obfuscator${idx_suffix}"
local service_name="phobos-obfuscator${idx_suffix}"
local wg_iface="phobos${idx_suffix}"
log "Удаление конфигурации ${obf_conf_base}..."
local link_file="$PHOBOS_DIR/${obf_conf_base}.link"
local linked_client=""
if [ -f "$link_file" ]; then
linked_client=$(cat "$link_file" 2>/dev/null) || linked_client=""
fi
local privkey_fallback=""
if [ -z "$linked_client" ] && [ "$ROUTER_PLATFORM" = "linux" ] && [ -f "/etc/wireguard/${wg_iface}.conf" ]; then
privkey_fallback=$(grep '^PrivateKey' "/etc/wireguard/${wg_iface}.conf" 2>/dev/null | cut -d'=' -f2- | tr -d ' \t') || privkey_fallback=""
fi
for f in /opt/etc/init.d/S[0-9]*wg-obfuscator*; do
[ -f "$f" ] || continue
if grep -q "^PROCS=${binary_name}$" "$f" 2>/dev/null; then
"$f" stop >/dev/null 2>&1 || true
rm -f "$f"
log " ✓ Удален init-скрипт: $f"
break
fi
done
if [ -f "/etc/init.d/${service_name}" ]; then
/etc/init.d/${service_name} stop >/dev/null 2>&1 || true
/etc/init.d/${service_name} disable >/dev/null 2>&1 || true
rm -f "/etc/init.d/${service_name}"
log " ✓ Удален procd init-скрипт: /etc/init.d/${service_name}"
fi
if command -v systemctl >/dev/null 2>&1 && [ -f "/etc/systemd/system/${service_name}.service" ]; then
systemctl stop "${service_name}" >/dev/null 2>&1 || true
systemctl disable "${service_name}" >/dev/null 2>&1 || true
rm -f "/etc/systemd/system/${service_name}.service"
log " ✓ Удален systemd сервис: /etc/systemd/system/${service_name}.service"
fi
for dir in /opt/bin /usr/bin /usr/local/bin; do
if [ -f "${dir}/${binary_name}" ]; then
rm -f "${dir}/${binary_name}"
log " ✓ Удален бинарник: ${dir}/${binary_name}"
fi
done
if [ "$ROUTER_PLATFORM" = "linux" ] && command -v systemctl >/dev/null 2>&1; then
systemctl stop "wg-quick@${wg_iface}" >/dev/null 2>&1 || true
systemctl disable "wg-quick@${wg_iface}" >/dev/null 2>&1 || true
if [ -d "/etc/systemd/system/wg-quick@${wg_iface}.service.d" ]; then
rm -rf "/etc/systemd/system/wg-quick@${wg_iface}.service.d"
log " ✓ Удален systemd override: wg-quick@${wg_iface}"
fi
if [ -f "/etc/wireguard/${wg_iface}.conf" ]; then
rm -f "/etc/wireguard/${wg_iface}.conf"
log " ✓ Удален WireGuard конфиг: /etc/wireguard/${wg_iface}.conf"
fi
systemctl daemon-reload >/dev/null 2>&1 || true
elif [ "$ROUTER_PLATFORM" = "keenetic" ]; then
if command -v curl >/dev/null 2>&1 && command -v jq >/dev/null 2>&1 && [ -n "$linked_client" ]; then
local target_desc="Phobos-${linked_client}"
log " Удаление WireGuard интерфейса Keenetic: ${target_desc}..."
local iface_list=$(curl -s "http://127.0.0.1:79/rci/show/interface" 2>/dev/null || echo "")
if [ -n "$iface_list" ] && echo "$iface_list" | jq -e . >/dev/null 2>&1; then
local iface_id=$(echo "$iface_list" | jq -r --arg desc "$target_desc" 'to_entries[] | select((.value.description? // "") == $desc) | .key' 2>/dev/null)
if [ -n "$iface_id" ]; then
local del_json=$(cat <<EOF
{
"interface": {
"$iface_id": {
"no": true
}
}
}
EOF
)
local del_result=$(echo "$del_json" | curl -s -X POST \
-H "Content-Type: application/json" \
-d @- \
"http://127.0.0.1:79/rci/" 2>/dev/null)
if echo "$del_result" | jq -e '.status == "error"' >/dev/null 2>&1; then
local err_msg=$(echo "$del_result" | jq -r '.message // "Unknown error"' 2>/dev/null)
log " ОШИБКА при удалении ${iface_id}: $err_msg"
else
log " ✓ Интерфейс ${iface_id} (${target_desc}) удален"
curl -s -X POST \
-H "Content-Type: application/json" \
-d '{"system":{"configuration":{"save":{}}}}' \
"http://127.0.0.1:79/rci/" >/dev/null 2>&1
log " ✓ Конфигурация сохранена"
fi
else
log " Интерфейс с описанием '${target_desc}' не найден"
fi
else
log " RCI API недоступен, пропускаем удаление интерфейса Keenetic"
fi
else
log " curl/jq не доступны или имя клиента не определено, пропускаем удаление интерфейса Keenetic"
fi
elif [ "$ROUTER_PLATFORM" = "openwrt" ]; then
remove_wireguard_interfaces_openwrt
remove_firewall_zone_openwrt
fi
if [ -f "$PHOBOS_DIR/${obf_conf_base}.conf" ]; then
rm -f "$PHOBOS_DIR/${obf_conf_base}.conf"
log " ✓ Удален конфиг obfuscator: $PHOBOS_DIR/${obf_conf_base}.conf"
fi
[ -f "$link_file" ] && rm -f "$link_file"
if [ -n "$linked_client" ] && [ -f "$PHOBOS_DIR/${linked_client}.conf" ]; then
rm -f "$PHOBOS_DIR/${linked_client}.conf"
log " ✓ Удален конфиг клиента: ${linked_client}.conf"
elif [ -n "$privkey_fallback" ]; then
for client_conf in "$PHOBOS_DIR"/*.conf; do
[ -f "$client_conf" ] || continue
case "$(basename "$client_conf")" in
wg-obfuscator*.conf) continue ;;
esac
if grep -qF "PrivateKey = ${privkey_fallback}" "$client_conf" 2>/dev/null; then
rm -f "$client_conf"
log " ✓ Удален конфиг клиента: $(basename "$client_conf")"
break
fi
done
fi
local remaining=0
for f in "$PHOBOS_DIR"/*.conf; do
[ -f "$f" ] && remaining=$((remaining + 1))
done
if [ "$remaining" -eq 0 ] && [ -d "$PHOBOS_DIR" ]; then
rm -rf "$PHOBOS_DIR"
log " ✓ Удалена директория: $PHOBOS_DIR"
fi
}
stop_obfuscator() {
log "Остановка wg-obfuscator..."
for f in /opt/etc/init.d/S[0-9]*wg-obfuscator*; do
[ -f "$f" ] && "$f" stop >/dev/null 2>&1 || true
done
for f in /etc/init.d/phobos-obfuscator*; do
if [ -f "$f" ]; then
"$f" stop >/dev/null 2>&1 || true
"$f" disable >/dev/null 2>&1 || true
fi
done
if command -v systemctl >/dev/null 2>&1; then
systemctl list-units --no-legend --plain 'phobos-obfuscator*.service' | awk '{print $1}' | while read -r unit; do
systemctl stop "$unit" >/dev/null 2>&1 || true
systemctl disable "$unit" >/dev/null 2>&1 || true
done
fi
if ps | grep -v grep | grep -q wg-obfuscator; then
log " Принудительное завершение процесса..."
pkill -f wg-obfuscator >/dev/null 2>&1 || true
fi
}
remove_wireguard_interfaces_keenetic() {
log "Удаление WireGuard интерфейсов Phobos (Keenetic)..."
if ! command -v curl >/dev/null 2>&1 || ! command -v jq >/dev/null 2>&1; then
log " curl или jq не установлен, пропускаем удаление интерфейсов"
return 0
fi
local interfaces=$(curl -s "http://127.0.0.1:79/rci/show/interface" 2>/dev/null || echo "")
if [ -z "$interfaces" ] || ! echo "$interfaces" | jq -e . >/dev/null 2>&1; then
log " RCI API недоступен или вернул некорректный JSON"
return 0
fi
local removed_count=0
local phobos_interfaces=$(echo "$interfaces" | jq -r 'to_entries[] | select(.value.description? // "" | startswith("Phobos-")) | .key' 2>/dev/null)
if [ -z "$phobos_interfaces" ]; then
log " Интерфейсы Phobos не найдены в системе"
return 0
fi
echo "$phobos_interfaces" | while read -r interface_id; do
if [ -z "$interface_id" ]; then
continue
fi
local interface_desc=$(echo "$interfaces" | jq -r --arg id "$interface_id" '.[$id].description // "unknown"' 2>/dev/null)
log " Удаление интерфейса: $interface_id ($interface_desc)"
local delete_json=$(cat <<EOF
{
"interface": {
"$interface_id": {
"no": true
}
}
}
EOF
)
local result=$(echo "$delete_json" | curl -s -X POST \
-H "Content-Type: application/json" \
-d @- \
"http://127.0.0.1:79/rci/" 2>/dev/null)
if echo "$result" | jq -e '.status == "error"' >/dev/null 2>&1; then
local error_msg=$(echo "$result" | jq -r '.message // "Unknown error"' 2>/dev/null)
log " ОШИБКА при удалении $interface_id: $error_msg"
else
log " ✓ Интерфейс $interface_id удален"
removed_count=$((removed_count + 1))
fi
done
local save_result=$(curl -s -X POST \
-H "Content-Type: application/json" \
-d '{"system":{"configuration":{"save":{}}}}' \
"http://127.0.0.1:79/rci/" 2>/dev/null)
if [ $removed_count -gt 0 ]; then
log "✓ Удалено интерфейсов: $removed_count"
log "✓ Конфигурация сохранена"
fi
}
remove_wireguard_interfaces_openwrt() {
log "Удаление WireGuard интерфейсов Phobos (OpenWRT)..."
if ! command -v uci >/dev/null 2>&1; then
log " uci не установлен, пропускаем удаление интерфейсов"
return 0
fi
local interface_name="phobos_wg"
if uci -q get network.${interface_name} >/dev/null 2>&1; then
log " Удаление интерфейса: ${interface_name}"
ifdown ${interface_name} >/dev/null 2>&1 || true
uci -q delete network.${interface_name} || true
local peers=$(uci show network 2>/dev/null | grep "wireguard_${interface_name}" | cut -d'.' -f2 | cut -d'=' -f1 | sort -u)
for peer in $peers; do
uci -q delete network.$peer || true
done
uci commit network
log " ✓ Интерфейс ${interface_name} удален"
else
log " Интерфейс ${interface_name} не найден"
fi
/etc/init.d/network reload >/dev/null 2>&1 || true
}
remove_firewall_zone_openwrt() {
log "Удаление файрволл зоны Phobos (OpenWRT)..."
if ! command -v uci >/dev/null 2>&1; then
log " uci не установлен, пропускаем удаление зоны"
return 0
fi
local zone_name="phobos"
if uci -q get firewall.${zone_name} >/dev/null 2>&1; then
log " Удаление зоны: ${zone_name}"
uci -q delete firewall.${zone_name} || true
uci commit firewall
log " ✓ Зона ${zone_name} удалена"
/etc/init.d/firewall reload >/dev/null 2>&1 || true
else
log " Зона ${zone_name} не найдена"
fi
}
remove_wireguard_interfaces_linux() {
log "Удаление WireGuard интерфейсов Phobos (Linux)..."
if ! command -v systemctl >/dev/null 2>&1; then
log " systemctl не найден, пропускаем удаление интерфейсов"
return 0
fi
for wg_conf in /etc/wireguard/phobos*.conf; do
[ -f "$wg_conf" ] || continue
local wg_interface
wg_interface=$(basename "$wg_conf" .conf)
if systemctl is-enabled --quiet wg-quick@${wg_interface} 2>/dev/null || systemctl is-active --quiet wg-quick@${wg_interface} 2>/dev/null; then
log " Остановка и удаление WireGuard сервиса: wg-quick@${wg_interface}"
systemctl stop wg-quick@${wg_interface} >/dev/null 2>&1 || true
systemctl disable wg-quick@${wg_interface} >/dev/null 2>&1 || true
log " ✓ Сервис wg-quick@${wg_interface} остановлен и отключен"
fi
if [ -d "/etc/systemd/system/wg-quick@${wg_interface}.service.d" ]; then
log " Удаление systemd override: /etc/systemd/system/wg-quick@${wg_interface}.service.d"
rm -rf "/etc/systemd/system/wg-quick@${wg_interface}.service.d"
log " ✓ Systemd override удален"
fi
log " Удаление конфигурации: $wg_conf"
rm -f "$wg_conf"
log " ✓ Конфигурационный файл WireGuard удален"
done
systemctl daemon-reload >/dev/null 2>&1 || true
}
remove_files() {
log "Удаление файлов Phobos..."
for f in /opt/etc/init.d/S[0-9]*wg-obfuscator*; do
if [ -f "$f" ]; then
rm -f "$f"
log " ✓ Удален init-скрипт: $f"
fi
done
for f in /etc/init.d/phobos-obfuscator*; do
if [ -f "$f" ]; then
rm -f "$f"
log " ✓ Удален procd init-скрипт: $f"
fi
done
for f in /opt/bin/wg-obfuscator*; do
if [ -f "$f" ]; then
rm -f "$f"
log " ✓ Удален бинарник: $f"
fi
done
for f in /usr/bin/wg-obfuscator*; do
if [ -f "$f" ]; then
rm -f "$f"
log " ✓ Удален бинарник: $f"
fi
done
for f in /usr/local/bin/wg-obfuscator*; do
if [ -f "$f" ]; then
rm -f "$f"
log " ✓ Удален бинарник: $f"
fi
done
local daemon_reload_needed=0
for f in /etc/systemd/system/phobos-obfuscator*.service; do
if [ -f "$f" ]; then
rm -f "$f"
daemon_reload_needed=1
log " ✓ Удален systemd сервис: $f"
fi
done
if [ $daemon_reload_needed -eq 1 ]; then
systemctl daemon-reload >/dev/null 2>&1 || true
fi
if [ -d "$PHOBOS_DIR" ]; then
rm -rf "$PHOBOS_DIR"
log " ✓ Удалена директория: $PHOBOS_DIR"
fi
}
show_final_info() {
log ""
log "╔════════════════════════════════════════════════════════════╗"
log "║ Phobos успешно удален ║"
log "╚════════════════════════════════════════════════════════════╝"
log ""
log "Удалены компоненты:"
log " - wg-obfuscator (процесс, init-скрипт/сервис, бинарник)"
log " - WireGuard интерфейсы Phobos"
log " - Конфигурационные файлы"
log ""
}
main() {
ROUTER_PLATFORM=$(detect_router_platform)
PHOBOS_DIR=$(detect_phobos_dir "$ROUTER_PLATFORM")
log "==> Начало удаления Phobos (платформа: $ROUTER_PLATFORM)"
log "==> Директория: $PHOBOS_DIR"
check_root
select_config_to_remove
if [ "$IS_FULL_REMOVAL" = "1" ]; then
stop_obfuscator
if [ "$ROUTER_PLATFORM" = "keenetic" ]; then
remove_wireguard_interfaces_keenetic
elif [ "$ROUTER_PLATFORM" = "openwrt" ]; then
remove_wireguard_interfaces_openwrt
remove_firewall_zone_openwrt
elif [ "$ROUTER_PLATFORM" = "linux" ]; then
remove_wireguard_interfaces_linux
else
log "ПРЕДУПРЕЖДЕНИЕ: Неизвестная платформа, пропускаем удаление WireGuard интерфейсов"
fi
remove_files
show_final_info
else
log "==> Удаление конфигурации: ${SELECTED_CONF}"
remove_single_obfuscator_instance "$SELECTED_CONF"
log ""
log "╔════════════════════════════════════════════════════════════╗"
log "║ Конфигурация успешно удалена ║"
log "╚════════════════════════════════════════════════════════════╝"
log ""
fi
log "==> Удаление завершено."
}
main "$@"