Files
MSWP/manage-users.sh
T

171 lines
7.0 KiB
Bash
Raw Normal View History

#!/bin/bash
# =============================================================================
# mita — управление пользователями
# Использование:
# ./manage-users.sh add <имя> — добавить (пароль генерируется автоматически)
# ./manage-users.sh remove <имя>
# ./manage-users.sh list
# ./manage-users.sh quota <имя> <дней> <GB>
# =============================================================================
set -euo pipefail
RED='\033[0;31m'; GREEN='\033[0;32m'; YELLOW='\033[1;33m'
CYAN='\033[0;36m'; BOLD='\033[1m'; NC='\033[0m'
CONFIG_FILE="/etc/mita/server_config.json"
[[ $EUID -ne 0 ]] && { echo -e "${RED}Запустите от root${NC}"; exit 1; }
[[ ! -f "$CONFIG_FILE" ]] && { echo -e "${RED}Конфиг не найден: $CONFIG_FILE${NC}"; exit 1; }
# ---------- Генерация пароля ----------
# 48 случайных байт → base64 → убираем +/= → берём 64 символа
gen_password() {
# Расширенный набор без символов ломающих protobuf (&<>|()[]{}\")
openssl rand -base64 48 | tr -d '/+=' | head -c 48
}
# ---------- Получить параметры сервера из конфига ----------
get_server_info() {
SERVER_IP=$(curl -s --max-time 5 ifconfig.me 2>/dev/null \
|| hostname -I | awk '{print $1}')
# Читаем первый portBinding из конфига
FIRST_BINDING=$(jq -r '.portBindings[0]' "$CONFIG_FILE")
PORT_PROTOCOL=$(echo "$FIRST_BINDING" | jq -r '.protocol // "TCP"')
# Может быть portRange или port
if echo "$FIRST_BINDING" | jq -e '.portRange' &>/dev/null; then
PORT_VALUE=$(echo "$FIRST_BINDING" | jq -r '.portRange')
PORT_JSON_KEY="portRange"
else
PORT_VALUE=$(echo "$FIRST_BINDING" | jq -r '.port | tostring')
PORT_JSON_KEY="port"
fi
}
# ---------- Вывод клиентского конфига ----------
print_client_config() {
local name="$1" pass="$2"
# Строим portBindings для клиентского конфига
if [[ "$PORT_JSON_KEY" == "portRange" ]]; then
PORT_BINDING_JSON=$(jq -n \
--arg r "$PORT_VALUE" --arg p "$PORT_PROTOCOL" \
'[{portRange: $r, protocol: $p}]')
else
PORT_BINDING_JSON=$(jq -n \
--argjson port "$PORT_VALUE" --arg p "$PORT_PROTOCOL" \
'[{port: $port, protocol: $p}]')
fi
CLIENT_JSON=$(jq -n \
--arg name "$name" \
--arg pass "$pass" \
--arg ip "$SERVER_IP" \
--argjson pb "$PORT_BINDING_JSON" \
'{
profiles: [{
profileName: "default",
user: {name: $name, password: $pass},
servers: [{
ipAddress: $ip,
portBindings: $pb
}]
}],
activeProfile: "default",
rpcPort: 8964,
socks5Port: 1080
}')
echo ""
echo -e "${CYAN}╔══════════════════════════════════════════════════════════════╗${NC}"
echo -e "${CYAN}║ КОНФИГ КЛИЕНТА — скопируйте целиком ║${NC}"
echo -e "${CYAN}╚══════════════════════════════════════════════════════════════╝${NC}"
echo ""
echo -e "${BOLD}Файл:${NC} mieru_client_config.json"
echo ""
echo "$CLIENT_JSON" | jq .
echo ""
echo -e "${CYAN}┌──────────────────────────────────────────────────────────────┐${NC}"
echo -e "${CYAN}│ Команды на устройстве клиента: │${NC}"
echo -e "${CYAN}${NC} mieru apply config mieru_client_config.json ${CYAN}${NC}"
echo -e "${CYAN}${NC} mieru start ${CYAN}${NC}"
echo -e "${CYAN}└──────────────────────────────────────────────────────────────┘${NC}"
echo ""
echo -e "${YELLOW}⚠ Сохраните пароль — он нигде не хранится в открытом виде:${NC}"
echo -e " Пользователь: ${BOLD}$name${NC}"
echo -e " Пароль: ${BOLD}$pass${NC}"
echo ""
}
cmd="${1:-list}"
case "$cmd" in
# ------------------------------------------------------------------
add)
[[ $# -lt 2 ]] && { echo "Использование: $0 add <имя>"; exit 1; }
NAME="$2"
# Проверить не существует ли уже
EXISTS=$(jq --arg n "$NAME" '.users[] | select(.name == $n)' "$CONFIG_FILE")
[[ -n "$EXISTS" ]] && { echo -e "${YELLOW}Пользователь '$NAME' уже существует${NC}"; exit 1; }
# Сгенерировать пароль
PASS=$(gen_password)
# Добавить пользователя в конфиг
jq --arg n "$NAME" --arg p "$PASS" \
'.users += [{name: $n, password: $p}]' \
"$CONFIG_FILE" > "${CONFIG_FILE}.tmp" && mv "${CONFIG_FILE}.tmp" "$CONFIG_FILE"
# Применить конфиг
mita apply config "$CONFIG_FILE"
echo -e "${GREEN}✓ Пользователь '${NAME}' добавлен${NC}"
# Показать клиентский конфиг
get_server_info
print_client_config "$NAME" "$PASS"
;;
# ------------------------------------------------------------------
remove)
[[ $# -lt 2 ]] && { echo "Использование: $0 remove <имя>"; exit 1; }
NAME="$2"
jq --arg n "$NAME" 'del(.users[] | select(.name == $n))' \
"$CONFIG_FILE" > "${CONFIG_FILE}.tmp" && mv "${CONFIG_FILE}.tmp" "$CONFIG_FILE"
mita apply config "$CONFIG_FILE"
echo -e "${GREEN}✓ Пользователь '$NAME' удалён${NC}"
;;
# ------------------------------------------------------------------
list)
echo -e "${CYAN}Пользователи в конфиге:${NC}"
jq -r '.users[] | " \(.name)"' "$CONFIG_FILE"
echo ""
echo -e "${CYAN}Статистика (из mita):${NC}"
mita get users 2>/dev/null || echo " (mita не запущен)"
;;
# ------------------------------------------------------------------
quota)
[[ $# -lt 4 ]] && { echo "Использование: $0 quota <имя> <дней> <GB>"; exit 1; }
NAME="$2"; DAYS="$3"; GB="$4"
MB=$(echo "$GB * 1024" | bc | cut -d. -f1)
jq --arg n "$NAME" --argjson d "$DAYS" --argjson m "$MB" \
'(.users[] | select(.name == $n)).quotas = [{days: $d, megabytes: $m}]' \
"$CONFIG_FILE" > "${CONFIG_FILE}.tmp" && mv "${CONFIG_FILE}.tmp" "$CONFIG_FILE"
mita apply config "$CONFIG_FILE"
echo -e "${GREEN}✓ Квота для '$NAME': ${GB}GB / ${DAYS} дней${NC}"
;;
*)
echo "Команды: add | remove | list | quota"
exit 1
;;
esac