fix: stabilize installer flows, managers, and terminal output
This commit is contained in:
@@ -53,7 +53,7 @@
|
||||
### Одна команда (рекомендуется)
|
||||
|
||||
```bash
|
||||
bash <(curl -Ls https://raw.githubusercontent.com/houseassassin/proxy-core/main/install.sh)
|
||||
sudo bash <(curl -Ls https://raw.githubusercontent.com/houseassassin/proxy-core/main/install.sh)
|
||||
```
|
||||
|
||||
### Альтернативный метод
|
||||
|
||||
@@ -27,7 +27,7 @@ show_gradient_banner() {
|
||||
echo -e "${CYAN}║${CYAN} ██║ ██║ ██║╚██████╔╝██╔╝ ██╗ ██║ ╚██████╗╚██████╔╝ ${CYAN}║${NC}"
|
||||
echo -e "${CYAN}║${CYAN} ╚═╝ ╚═╝ ╚═╝ ╚═════╝ ╚═╝ ╚═╝ ╚═╝ ╚═════╝ ╚═════╝ ${CYAN}║${NC}"
|
||||
echo -e "${CYAN}║ ║${NC}"
|
||||
echo -e "${CYAN}║${WHITE} 🚀 Advanced VPN & Proxy Panel Auto-Installer 🚀 ${CYAN}║${NC}"
|
||||
echo -e "${CYAN}║${WHITE} Advanced VPN & Proxy Panel Auto-Installer ${CYAN}║${NC}"
|
||||
echo -e "${CYAN}╚═══════════════════════════════════════════════════════════════════════╝${NC}"
|
||||
echo ""
|
||||
echo -e " ${GREEN}┌─────────────────────────────────────────────────────────────────┐${NC}"
|
||||
|
||||
+332
-95
@@ -14,6 +14,13 @@ set -euo pipefail
|
||||
SCRIPT_VERSION="2.1.1"
|
||||
PROJECT_DIR="/opt/proxy-core"
|
||||
LANG_FILE="${PROJECT_DIR}/.selected_language"
|
||||
REPO_ARCHIVE_URL="https://github.com/houseassassin/proxy-core/archive/refs/heads/main.tar.gz"
|
||||
THREEXUI_INSTALL_URL="https://raw.githubusercontent.com/mhsanaei/3x-ui/master/install.sh"
|
||||
WG_PORT_MIN=51820
|
||||
WG_PORT_MAX=51900
|
||||
HYSTERIA_PORT_MIN=36712
|
||||
HYSTERIA_PORT_MAX=36800
|
||||
MTPROXY_PORT_DEFAULT=8443
|
||||
|
||||
# Colors and styles
|
||||
RED='\033[0;31m'
|
||||
@@ -39,29 +46,64 @@ BG_BLUE='\033[44m'
|
||||
BG_MAGENTA='\033[45m'
|
||||
BG_CYAN='\033[46m'
|
||||
|
||||
# Create project directory first
|
||||
mkdir -p "$PROJECT_DIR"
|
||||
USE_UNICODE=1
|
||||
if ! locale charmap 2>/dev/null | grep -qi "utf-8"; then
|
||||
USE_UNICODE=0
|
||||
fi
|
||||
|
||||
if [ ! -t 1 ] || [ "${TERM:-}" = "dumb" ] || [ "${NO_COLOR:-}" = "1" ]; then
|
||||
RED=""
|
||||
GREEN=""
|
||||
YELLOW=""
|
||||
BLUE=""
|
||||
MAGENTA=""
|
||||
CYAN=""
|
||||
GRAY=""
|
||||
WHITE=""
|
||||
NC=""
|
||||
BOLD=""
|
||||
DIM=""
|
||||
UNDERLINE=""
|
||||
BLINK=""
|
||||
BG_RED=""
|
||||
BG_GREEN=""
|
||||
BG_BLUE=""
|
||||
BG_MAGENTA=""
|
||||
BG_CYAN=""
|
||||
fi
|
||||
|
||||
if [ "$USE_UNICODE" -eq 1 ]; then
|
||||
SYM_INFO="ℹ"
|
||||
SYM_WARN="⚠"
|
||||
SYM_ERR="✗"
|
||||
SYM_OK="✓"
|
||||
else
|
||||
SYM_INFO="i"
|
||||
SYM_WARN="!"
|
||||
SYM_ERR="x"
|
||||
SYM_OK="+"
|
||||
fi
|
||||
|
||||
# Logging
|
||||
LOGFILE="${PROJECT_DIR}/installer.log"
|
||||
LOGFILE="/tmp/proxy-core-installer.log"
|
||||
|
||||
log() {
|
||||
echo -e " ${CYAN}ℹ${NC} ${WHITE}$1${NC}"
|
||||
echo -e " ${CYAN}${SYM_INFO}${NC} ${WHITE}$1${NC}"
|
||||
echo "[$(date '+%Y-%m-%d %H:%M:%S')] [INFO] $1" >> "$LOGFILE" 2>/dev/null
|
||||
}
|
||||
|
||||
warn() {
|
||||
echo -e " ${YELLOW}⚠${NC} ${YELLOW}$1${NC}"
|
||||
echo -e " ${YELLOW}${SYM_WARN}${NC} ${YELLOW}$1${NC}"
|
||||
echo "[$(date '+%Y-%m-%d %H:%M:%S')] [WARN] $1" >> "$LOGFILE" 2>/dev/null
|
||||
}
|
||||
|
||||
error() {
|
||||
echo -e " ${RED}✗${NC} ${RED}$1${NC}"
|
||||
echo -e " ${RED}${SYM_ERR}${NC} ${RED}$1${NC}"
|
||||
echo "[$(date '+%Y-%m-%d %H:%M:%S')] [ERROR] $1" >> "$LOGFILE" 2>/dev/null
|
||||
}
|
||||
|
||||
success() {
|
||||
echo -e " ${GREEN}✓${NC} ${GREEN}$1${NC}"
|
||||
echo -e " ${GREEN}${SYM_OK}${NC} ${GREEN}$1${NC}"
|
||||
echo "[$(date '+%Y-%m-%d %H:%M:%S')] [SUCCESS] $1" >> "$LOGFILE" 2>/dev/null
|
||||
}
|
||||
|
||||
@@ -69,7 +111,10 @@ success() {
|
||||
spinner() {
|
||||
local pid=$1
|
||||
local text=$2
|
||||
local frames=("⠋" "⠙" "⠹" "⠸" "⠼" "⠴" "⠦" "⠧" "⠇" "⠏")
|
||||
local frames=("|" "/" "-" "\\")
|
||||
if [ "$USE_UNICODE" -eq 1 ]; then
|
||||
frames=("⠋" "⠙" "⠹" "⠸" "⠼" "⠴" "⠦" "⠧" "⠇" "⠏")
|
||||
fi
|
||||
|
||||
while kill -0 "$pid" 2>/dev/null; do
|
||||
for frame in "${frames[@]}"; do
|
||||
@@ -77,52 +122,9 @@ spinner() {
|
||||
sleep 0.1
|
||||
done
|
||||
done
|
||||
printf "\r ${GREEN}✓${NC} ${WHITE}%s${NC}\n" "$text"
|
||||
printf "\r ${GREEN}${SYM_OK}${NC} ${WHITE}%s${NC}\n" "$text"
|
||||
}
|
||||
|
||||
# Language support
|
||||
declare -A LANG_EN=(
|
||||
[MENU_TITLE]="VPN Panel Installer"
|
||||
[MENU_INSTALL]="Install Panel"
|
||||
[MENU_MANAGE]="Manage Services"
|
||||
[MENU_BACKUP]="Backup & Restore"
|
||||
[MENU_UPDATE]="Update Components"
|
||||
[MENU_UNINSTALL]="Uninstall"
|
||||
[MENU_EXIT]="Exit"
|
||||
[SELECT_PANEL]="Select panel to install"
|
||||
[WIREGUARD]="WireGuard VPN"
|
||||
[3XUI]="3x-ui Panel"
|
||||
[REMNAWAVE]="Remnawave Panel"
|
||||
[HYSTERIA2]="Hysteria2 Proxy"
|
||||
[MTPROXY]="MTProxy (Telegram)"
|
||||
[SELECT_REVERSE_PROXY]="Select Reverse Proxy"
|
||||
[NGINX]="Nginx"
|
||||
[CADDY]="Caddy"
|
||||
[SELFSTEAL]="Install Selfsteal Template"
|
||||
[ALL]="Install All"
|
||||
)
|
||||
|
||||
declare -A LANG_RU=(
|
||||
[MENU_TITLE]="Установщик VPN панелей"
|
||||
[MENU_INSTALL]="Установить панель"
|
||||
[MENU_MANAGE]="Управление сервисами"
|
||||
[MENU_BACKUP]="Резервное копирование"
|
||||
[MENU_UPDATE]="Обновить компоненты"
|
||||
[MENU_UNINSTALL]="Удалить"
|
||||
[MENU_EXIT]="Выход"
|
||||
[SELECT_PANEL]="Выберите панель для установки"
|
||||
[WIREGUARD]="WireGuard VPN"
|
||||
[3XUI]="Панель 3x-ui"
|
||||
[REMNAWAVE]="Панель Remnawave"
|
||||
[HYSTERIA2]="Прокси Hysteria2"
|
||||
[MTPROXY]="MTProxy (Telegram)"
|
||||
[SELECT_REVERSE_PROXY]="Выберите Reverse Proxy"
|
||||
[NGINX]="Nginx"
|
||||
[CADDY]="Caddy"
|
||||
[SELFSTEAL]="Установить Selfsteal шаблон"
|
||||
[ALL]="Установить всё"
|
||||
)
|
||||
|
||||
MENU_LANG="en"
|
||||
|
||||
load_language() {
|
||||
@@ -139,14 +141,22 @@ save_language() {
|
||||
|
||||
L() {
|
||||
local key="$1"
|
||||
local var_name="LANG_${MENU_LANG^^}_${key}"
|
||||
echo "${!var_name:-$key}"
|
||||
case "$MENU_LANG:$key" in
|
||||
"ru:SELECT_REVERSE_PROXY") echo "Выберите Reverse Proxy" ;;
|
||||
"ru:NGINX") echo "Nginx" ;;
|
||||
"ru:CADDY") echo "Caddy" ;;
|
||||
"en:SELECT_REVERSE_PROXY") echo "Select Reverse Proxy" ;;
|
||||
"en:NGINX") echo "Nginx" ;;
|
||||
"en:CADDY") echo "Caddy" ;;
|
||||
*) echo "$key" ;;
|
||||
esac
|
||||
}
|
||||
|
||||
# System checks
|
||||
check_root() {
|
||||
if [[ $EUID -ne 0 ]]; then
|
||||
error "Этот скрипт должен быть запущен с правами root"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
@@ -157,10 +167,112 @@ detect_os() {
|
||||
VER=$VERSION_ID
|
||||
else
|
||||
error "Не удалось определить операционную систему"
|
||||
exit 1
|
||||
fi
|
||||
log "Обнаружена ОС: $OS $VER"
|
||||
}
|
||||
|
||||
reload_firewall() {
|
||||
if command -v firewall-cmd >/dev/null 2>&1; then
|
||||
firewall-cmd --reload >/dev/null 2>&1 || true
|
||||
fi
|
||||
}
|
||||
|
||||
open_firewall_port() {
|
||||
local port=$1
|
||||
local protocol=$2
|
||||
|
||||
if command -v ufw >/dev/null 2>&1; then
|
||||
ufw allow "${port}/${protocol}" >/dev/null 2>&1 || true
|
||||
return 0
|
||||
fi
|
||||
|
||||
if command -v firewall-cmd >/dev/null 2>&1; then
|
||||
firewall-cmd --permanent --add-port="${port}/${protocol}" >/dev/null 2>&1 || true
|
||||
reload_firewall
|
||||
fi
|
||||
}
|
||||
|
||||
run_remote_script() {
|
||||
local url=$1
|
||||
local tmp_script
|
||||
tmp_script="$(mktemp /tmp/proxy-core-remote.XXXXXX.sh)"
|
||||
curl -fsSL "$url" -o "$tmp_script"
|
||||
chmod 700 "$tmp_script"
|
||||
bash "$tmp_script"
|
||||
rm -f "$tmp_script"
|
||||
}
|
||||
|
||||
ensure_project_files() {
|
||||
mkdir -p "$PROJECT_DIR"
|
||||
LOGFILE="${PROJECT_DIR}/installer.log"
|
||||
|
||||
local need_bootstrap=0
|
||||
local required_files=(
|
||||
"manage.sh"
|
||||
"wg-manager.sh"
|
||||
"update.sh"
|
||||
"mtproxy-manager.sh"
|
||||
"reverse-proxy-manager.sh"
|
||||
"banner.sh"
|
||||
)
|
||||
|
||||
for file in "${required_files[@]}"; do
|
||||
if [ ! -f "$PROJECT_DIR/$file" ]; then
|
||||
need_bootstrap=1
|
||||
break
|
||||
fi
|
||||
done
|
||||
|
||||
if [ "$need_bootstrap" -eq 0 ] && [ -d "$PROJECT_DIR/lib" ] && [ -d "$PROJECT_DIR/config" ]; then
|
||||
return 0
|
||||
fi
|
||||
|
||||
local script_dir
|
||||
script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
if [ -f "$script_dir/manage.sh" ] && [ -d "$script_dir/lib" ] && [ -d "$script_dir/config" ]; then
|
||||
cp -f "$script_dir/"*.sh "$PROJECT_DIR/" 2>/dev/null || true
|
||||
cp -rf "$script_dir/lib" "$PROJECT_DIR/"
|
||||
cp -rf "$script_dir/config" "$PROJECT_DIR/"
|
||||
chmod +x "$PROJECT_DIR/"*.sh 2>/dev/null || true
|
||||
return 0
|
||||
fi
|
||||
|
||||
log "Загружаем файлы проекта в $PROJECT_DIR..."
|
||||
local archive
|
||||
archive="$(mktemp /tmp/proxy-core-src.XXXXXX.tar.gz)"
|
||||
curl -fsSL "$REPO_ARCHIVE_URL" -o "$archive"
|
||||
tar -xzf "$archive" --strip-components=1 -C "$PROJECT_DIR"
|
||||
rm -f "$archive"
|
||||
chmod +x "$PROJECT_DIR/"*.sh 2>/dev/null || true
|
||||
}
|
||||
|
||||
run_project_script() {
|
||||
local script_name=$1
|
||||
if [ -f "$PROJECT_DIR/$script_name" ]; then
|
||||
bash "$PROJECT_DIR/$script_name"
|
||||
else
|
||||
error "$script_name не найден в $PROJECT_DIR"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
load_defaults() {
|
||||
local defaults_path=""
|
||||
local script_dir
|
||||
script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
if [ -f "$PROJECT_DIR/config/defaults.conf" ]; then
|
||||
defaults_path="$PROJECT_DIR/config/defaults.conf"
|
||||
elif [ -f "$script_dir/config/defaults.conf" ]; then
|
||||
defaults_path="$script_dir/config/defaults.conf"
|
||||
fi
|
||||
|
||||
if [ -n "$defaults_path" ]; then
|
||||
source "$defaults_path"
|
||||
log "Загружены настройки по умолчанию: $defaults_path"
|
||||
fi
|
||||
}
|
||||
|
||||
check_memory() {
|
||||
local mem_mb=$(free -m | grep Mem: | awk '{print $2}')
|
||||
if [ $mem_mb -lt 2000 ]; then
|
||||
@@ -203,9 +315,11 @@ install_docker() {
|
||||
fi
|
||||
|
||||
log "Установка Docker..."
|
||||
curl -fsSL https://get.docker.com -o /tmp/get-docker.sh
|
||||
sh /tmp/get-docker.sh
|
||||
rm /tmp/get-docker.sh
|
||||
local docker_installer
|
||||
docker_installer="$(mktemp /tmp/get-docker.XXXXXX.sh)"
|
||||
curl -fsSL https://get.docker.com -o "$docker_installer"
|
||||
sh "$docker_installer"
|
||||
rm -f "$docker_installer"
|
||||
|
||||
systemctl enable docker
|
||||
systemctl start docker
|
||||
@@ -249,6 +363,14 @@ install_packages() {
|
||||
ufw --force enable >/dev/null 2>&1
|
||||
fi
|
||||
|
||||
if command -v firewall-cmd >/dev/null 2>&1; then
|
||||
systemctl enable firewalld >/dev/null 2>&1 || true
|
||||
systemctl start firewalld >/dev/null 2>&1 || true
|
||||
firewall-cmd --permanent --add-service=ssh >/dev/null 2>&1 || true
|
||||
firewall-cmd --permanent --add-service=https >/dev/null 2>&1 || true
|
||||
reload_firewall
|
||||
fi
|
||||
|
||||
success "Системные пакеты установлены"
|
||||
}
|
||||
|
||||
@@ -273,7 +395,7 @@ install_wireguard() {
|
||||
SERVER_PRIVATE_KEY=$(cat server_private.key)
|
||||
SERVER_PUBLIC_KEY=$(cat server_public.key)
|
||||
SERVER_IP=$(get_server_ip)
|
||||
WG_PORT=$(get_random_port 51820 51900)
|
||||
WG_PORT=$(get_random_port "$WG_PORT_MIN" "$WG_PORT_MAX")
|
||||
|
||||
cat > /etc/wireguard/wg0.conf <<EOF
|
||||
[Interface]
|
||||
@@ -290,7 +412,7 @@ EOF
|
||||
systemctl enable wg-quick@wg0
|
||||
systemctl start wg-quick@wg0
|
||||
|
||||
ufw allow $WG_PORT/udp 2>/dev/null || firewall-cmd --permanent --add-port=$WG_PORT/udp 2>/dev/null
|
||||
open_firewall_port "$WG_PORT" "udp"
|
||||
|
||||
success "WireGuard установлен на порту $WG_PORT"
|
||||
|
||||
@@ -303,7 +425,7 @@ EOF
|
||||
# 3x-ui installation
|
||||
install_3xui() {
|
||||
log "Установка 3x-ui..."
|
||||
bash <(curl -Ls https://raw.githubusercontent.com/mhsanaei/3x-ui/master/install.sh)
|
||||
run_remote_script "$THREEXUI_INSTALL_URL"
|
||||
success "3x-ui установлен"
|
||||
}
|
||||
|
||||
@@ -339,8 +461,8 @@ EOF
|
||||
|
||||
success "Remnawave установлен"
|
||||
echo ""
|
||||
log "Админ логин: admin"
|
||||
log "Админ пароль: $ADMIN_PASSWORD"
|
||||
echo -e " ${CYAN}${SYM_INFO}${NC} ${WHITE}Админ логин: admin${NC}"
|
||||
echo -e " ${CYAN}${SYM_INFO}${NC} ${WHITE}Админ пароль: ${ADMIN_PASSWORD}${NC}"
|
||||
warn "Сохраните эти данные!"
|
||||
}
|
||||
|
||||
@@ -349,14 +471,16 @@ install_hysteria2() {
|
||||
log "Установка Hysteria2..."
|
||||
|
||||
HYSTERIA_VERSION=$(curl -s https://api.github.com/repos/apernet/hysteria/releases/latest | grep tag_name | cut -d '"' -f 4)
|
||||
wget -O /tmp/hysteria "https://github.com/apernet/hysteria/releases/download/${HYSTERIA_VERSION}/hysteria-linux-amd64"
|
||||
chmod +x /tmp/hysteria
|
||||
mv /tmp/hysteria /usr/local/bin/hysteria
|
||||
local hysteria_bin
|
||||
hysteria_bin="$(mktemp /tmp/hysteria.XXXXXX)"
|
||||
wget -O "$hysteria_bin" "https://github.com/apernet/hysteria/releases/download/${HYSTERIA_VERSION}/hysteria-linux-amd64"
|
||||
chmod +x "$hysteria_bin"
|
||||
mv "$hysteria_bin" /usr/local/bin/hysteria
|
||||
|
||||
mkdir -p /etc/hysteria
|
||||
|
||||
HYSTERIA_PASSWORD=$(openssl rand -base64 32)
|
||||
HYSTERIA_PORT=$(get_random_port 36712 36800)
|
||||
HYSTERIA_PORT=$(get_random_port "$HYSTERIA_PORT_MIN" "$HYSTERIA_PORT_MAX")
|
||||
|
||||
cat > /etc/hysteria/config.yaml <<EOF
|
||||
listen: :$HYSTERIA_PORT
|
||||
@@ -397,12 +521,12 @@ EOF
|
||||
systemctl enable hysteria-server
|
||||
systemctl start hysteria-server
|
||||
|
||||
ufw allow $HYSTERIA_PORT/udp 2>/dev/null || firewall-cmd --permanent --add-port=$HYSTERIA_PORT/udp 2>/dev/null
|
||||
open_firewall_port "$HYSTERIA_PORT" "udp"
|
||||
|
||||
success "Hysteria2 установлен"
|
||||
echo ""
|
||||
log "Порт: $HYSTERIA_PORT"
|
||||
log "Пароль: $HYSTERIA_PASSWORD"
|
||||
echo -e " ${CYAN}${SYM_INFO}${NC} ${WHITE}Пароль: ${HYSTERIA_PASSWORD}${NC}"
|
||||
warn "Сохраните эти данные!"
|
||||
}
|
||||
|
||||
@@ -433,8 +557,12 @@ install_mtproxy() {
|
||||
|
||||
SECRET=$(head -c 16 /dev/urandom | xxd -ps)
|
||||
|
||||
read -p "Введите порт для MTProxy (по умолчанию 8443): " MTPROXY_PORT
|
||||
MTPROXY_PORT=${MTPROXY_PORT:-8443}
|
||||
read -p "Введите порт для MTProxy (по умолчанию ${MTPROXY_PORT_DEFAULT}): " MTPROXY_PORT
|
||||
MTPROXY_PORT=${MTPROXY_PORT:-$MTPROXY_PORT_DEFAULT}
|
||||
if ! [[ "$MTPROXY_PORT" =~ ^[0-9]+$ ]] || [ "$MTPROXY_PORT" -lt 1 ] || [ "$MTPROXY_PORT" -gt 65535 ]; then
|
||||
error "Неверный порт: $MTPROXY_PORT"
|
||||
return 1
|
||||
fi
|
||||
|
||||
cat > /etc/systemd/system/mtproxy.service <<EOF
|
||||
[Unit]
|
||||
@@ -455,7 +583,7 @@ EOF
|
||||
systemctl enable mtproxy
|
||||
systemctl start mtproxy
|
||||
|
||||
ufw allow $MTPROXY_PORT/tcp 2>/dev/null || firewall-cmd --permanent --add-port=$MTPROXY_PORT/tcp 2>/dev/null
|
||||
open_firewall_port "$MTPROXY_PORT" "tcp"
|
||||
|
||||
cat > /opt/MTProxy/.config <<EOF
|
||||
MTPROXY_PORT=$MTPROXY_PORT
|
||||
@@ -658,63 +786,158 @@ EOF
|
||||
success "Selfsteal шаблон установлен"
|
||||
}
|
||||
|
||||
backup_configs() {
|
||||
local backup_dir="/root/proxy-core-backup-$(date +%Y%m%d-%H%M%S)"
|
||||
mkdir -p "$backup_dir"
|
||||
|
||||
[ -d "/etc/wireguard" ] && cp -r /etc/wireguard "$backup_dir/"
|
||||
[ -d "/etc/hysteria" ] && cp -r /etc/hysteria "$backup_dir/"
|
||||
[ -d "/opt/MTProxy" ] && cp -r /opt/MTProxy/.config "$backup_dir/mtproxy.config" 2>/dev/null || true
|
||||
[ -f "/etc/systemd/system/mtproxy.service" ] && cp /etc/systemd/system/mtproxy.service "$backup_dir/"
|
||||
[ -f "/etc/systemd/system/hysteria-server.service" ] && cp /etc/systemd/system/hysteria-server.service "$backup_dir/"
|
||||
[ -d "/opt/remnawave" ] && cp -r /opt/remnawave "$backup_dir/remnawave" 2>/dev/null || true
|
||||
|
||||
success "Резервная копия создана: $backup_dir"
|
||||
}
|
||||
|
||||
uninstall_panels_menu() {
|
||||
echo ""
|
||||
echo -e "${YELLOW}Выберите компонент для удаления:${NC}"
|
||||
echo "1) WireGuard"
|
||||
echo "2) 3x-ui"
|
||||
echo "3) Remnawave"
|
||||
echo "4) Hysteria2"
|
||||
echo "5) MTProxy"
|
||||
echo "6) Удалить всё"
|
||||
echo "0) Назад"
|
||||
echo ""
|
||||
read -p "Ваш выбор: " uninstall_choice
|
||||
|
||||
case $uninstall_choice in
|
||||
1)
|
||||
systemctl disable --now wg-quick@wg0 >/dev/null 2>&1 || true
|
||||
rm -rf /etc/wireguard
|
||||
success "WireGuard удален"
|
||||
;;
|
||||
2)
|
||||
if command -v x-ui >/dev/null 2>&1; then
|
||||
x-ui uninstall || warn "Не удалось выполнить x-ui uninstall, проверьте вручную"
|
||||
else
|
||||
warn "x-ui не найден, возможно уже удален"
|
||||
fi
|
||||
;;
|
||||
3)
|
||||
if [ -d "/opt/remnawave" ]; then
|
||||
cd /opt/remnawave
|
||||
docker compose down >/dev/null 2>&1 || true
|
||||
cd /opt
|
||||
rm -rf /opt/remnawave
|
||||
success "Remnawave удален"
|
||||
else
|
||||
warn "Remnawave не найден"
|
||||
fi
|
||||
;;
|
||||
4)
|
||||
systemctl disable --now hysteria-server >/dev/null 2>&1 || true
|
||||
rm -f /etc/systemd/system/hysteria-server.service
|
||||
systemctl daemon-reload
|
||||
rm -rf /etc/hysteria
|
||||
rm -f /usr/local/bin/hysteria
|
||||
success "Hysteria2 удален"
|
||||
;;
|
||||
5)
|
||||
local mtproxy_port=""
|
||||
if [ -f "/opt/MTProxy/.config" ]; then
|
||||
mtproxy_port="$(grep '^MTPROXY_PORT=' /opt/MTProxy/.config | cut -d= -f2)"
|
||||
fi
|
||||
systemctl disable --now mtproxy >/dev/null 2>&1 || true
|
||||
rm -f /etc/systemd/system/mtproxy.service
|
||||
systemctl daemon-reload
|
||||
rm -rf /opt/MTProxy
|
||||
if [ -n "$mtproxy_port" ] && command -v ufw >/dev/null 2>&1; then
|
||||
ufw delete allow "${mtproxy_port}/tcp" >/dev/null 2>&1 || true
|
||||
fi
|
||||
success "MTProxy удален"
|
||||
;;
|
||||
6)
|
||||
systemctl disable --now wg-quick@wg0 >/dev/null 2>&1 || true
|
||||
systemctl disable --now hysteria-server >/dev/null 2>&1 || true
|
||||
systemctl disable --now mtproxy >/dev/null 2>&1 || true
|
||||
rm -f /etc/systemd/system/hysteria-server.service /etc/systemd/system/mtproxy.service
|
||||
systemctl daemon-reload
|
||||
rm -rf /etc/wireguard /etc/hysteria /opt/MTProxy /opt/remnawave
|
||||
if command -v x-ui >/dev/null 2>&1; then
|
||||
x-ui uninstall >/dev/null 2>&1 || true
|
||||
fi
|
||||
success "Основные компоненты удалены"
|
||||
;;
|
||||
0)
|
||||
return 0
|
||||
;;
|
||||
*)
|
||||
warn "Неверный выбор"
|
||||
return 1
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
# Main menu
|
||||
show_main_menu() {
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
|
||||
# Source banner
|
||||
if [ -f "$SCRIPT_DIR/banner.sh" ]; then
|
||||
if [ "$USE_UNICODE" -eq 1 ] && [ -f "$SCRIPT_DIR/banner.sh" ]; then
|
||||
source "$SCRIPT_DIR/banner.sh"
|
||||
show_gradient_banner
|
||||
else
|
||||
clear
|
||||
echo -e "${MAGENTA}╔════════════════════════════════════════╗${NC}"
|
||||
echo -e "${MAGENTA}║ 🚀 Proxy-Core Installer ║${NC}"
|
||||
echo -e "${MAGENTA}║ Proxy-Core Installer ║${NC}"
|
||||
echo -e "${MAGENTA}║ Version: ${SCRIPT_VERSION} ║${NC}"
|
||||
echo -e "${MAGENTA}╚════════════════════════════════════════╝${NC}"
|
||||
echo ""
|
||||
fi
|
||||
|
||||
echo -e " ${CYAN}╔═══════════════════════════════════════════════════════════════╗${NC}"
|
||||
echo -e " ${CYAN}║${NC} ${WHITE}📦 УСТАНОВКА${NC} ${CYAN}║${NC}"
|
||||
echo -e " ${CYAN}║${NC} ${WHITE}УСТАНОВКА${NC} ${CYAN}║${NC}"
|
||||
echo -e " ${CYAN}╚═══════════════════════════════════════════════════════════════╝${NC}"
|
||||
echo ""
|
||||
echo -e " ${YELLOW}1.${NC} 🔧 ${WHITE}Установить панель${NC}"
|
||||
echo -e " ${YELLOW}1.${NC} ${WHITE}Установить панель${NC}"
|
||||
echo -e " ${GRAY}WireGuard, 3x-ui, Remnawave, Hysteria2, MTProxy${NC}"
|
||||
echo ""
|
||||
|
||||
echo -e " ${CYAN}╔═══════════════════════════════════════════════════════════════╗${NC}"
|
||||
echo -e " ${CYAN}║${NC} ${WHITE}⚙️ УПРАВЛЕНИЕ${NC} ${CYAN}║${NC}"
|
||||
echo -e " ${CYAN}║${NC} ${WHITE}УПРАВЛЕНИЕ${NC} ${CYAN}║${NC}"
|
||||
echo -e " ${CYAN}╚═══════════════════════════════════════════════════════════════╝${NC}"
|
||||
echo ""
|
||||
echo -e " ${YELLOW}2.${NC} 🎮 ${WHITE}Управление сервисами${NC}"
|
||||
echo -e " ${YELLOW}2.${NC} ${WHITE}Управление сервисами${NC}"
|
||||
echo -e " ${GRAY}Запуск, остановка, перезапуск панелей${NC}"
|
||||
echo ""
|
||||
echo -e " ${YELLOW}3.${NC} 💾 ${WHITE}Резервное копирование${NC}"
|
||||
echo -e " ${YELLOW}3.${NC} ${WHITE}Резервное копирование${NC}"
|
||||
echo -e " ${GRAY}Создание и восстановление бэкапов${NC}"
|
||||
echo ""
|
||||
echo -e " ${YELLOW}4.${NC} 🔄 ${WHITE}Обновить компоненты${NC}"
|
||||
echo -e " ${YELLOW}4.${NC} ${WHITE}Обновить компоненты${NC}"
|
||||
echo -e " ${GRAY}Обновление установленных панелей${NC}"
|
||||
echo ""
|
||||
|
||||
echo -e " ${CYAN}╔═══════════════════════════════════════════════════════════════╗${NC}"
|
||||
echo -e " ${CYAN}║${NC} ${WHITE}🌐 ДОПОЛНИТЕЛЬНО${NC} ${CYAN}║${NC}"
|
||||
echo -e " ${CYAN}║${NC} ${WHITE}ДОПОЛНИТЕЛЬНО${NC} ${CYAN}║${NC}"
|
||||
echo -e " ${CYAN}╚═══════════════════════════════════════════════════════════════╝${NC}"
|
||||
echo ""
|
||||
echo -e " ${YELLOW}5.${NC} 🗑️ ${WHITE}Удалить панель${NC}"
|
||||
echo -e " ${YELLOW}5.${NC} ${WHITE}Удалить панель${NC}"
|
||||
echo -e " ${GRAY}Полное удаление установленных компонентов${NC}"
|
||||
echo ""
|
||||
echo -e " ${YELLOW}6.${NC} 🎭 ${WHITE}Установить Selfsteal${NC}"
|
||||
echo -e " ${YELLOW}6.${NC} ${WHITE}Установить Selfsteal${NC}"
|
||||
echo -e " ${GRAY}Маскировка трафика под обычный сайт${NC}"
|
||||
echo ""
|
||||
echo -e " ${YELLOW}7.${NC} 🌐 ${WHITE}Настроить Reverse Proxy${NC}"
|
||||
echo -e " ${YELLOW}7.${NC} ${WHITE}Настроить Reverse Proxy${NC}"
|
||||
echo -e " ${GRAY}Nginx, Caddy, HAProxy - установка и настройка${NC}"
|
||||
echo ""
|
||||
|
||||
echo -e " ${GRAY}─────────────────────────────────────────────────────────────────${NC}"
|
||||
echo ""
|
||||
echo -e " ${YELLOW}9.${NC} 🌍 ${WHITE}Сменить язык / Change language${NC}"
|
||||
echo -e " ${YELLOW}0.${NC} 🚪 ${WHITE}Выход / Exit${NC}"
|
||||
echo -e " ${YELLOW}9.${NC} ${WHITE}Сменить язык / Change language${NC}"
|
||||
echo -e " ${YELLOW}0.${NC} ${WHITE}Выход / Exit${NC}"
|
||||
echo ""
|
||||
echo -e " ${GRAY}─────────────────────────────────────────────────────────────────${NC}"
|
||||
echo ""
|
||||
@@ -724,39 +947,39 @@ show_install_menu() {
|
||||
clear
|
||||
echo ""
|
||||
echo -e " ${GREEN}╔═══════════════════════════════════════════════════════════════╗${NC}"
|
||||
echo -e " ${GREEN}║${NC} ${WHITE}📦 Выберите панель для установки${NC} ${GREEN}║${NC}"
|
||||
echo -e " ${GREEN}║${NC} ${WHITE}Выберите панель для установки${NC} ${GREEN}║${NC}"
|
||||
echo -e " ${GREEN}╚═══════════════════════════════════════════════════════════════╝${NC}"
|
||||
echo ""
|
||||
echo -e " ${YELLOW}1.${NC} 🔐 ${WHITE}WireGuard VPN${NC}"
|
||||
echo -e " ${YELLOW}1.${NC} ${WHITE}WireGuard VPN${NC}"
|
||||
echo -e " ${GRAY}Современный, быстрый и безопасный VPN${NC}"
|
||||
echo ""
|
||||
echo -e " ${YELLOW}2.${NC} 🌐 ${WHITE}3x-ui Panel${NC}"
|
||||
echo -e " ${YELLOW}2.${NC} ${WHITE}3x-ui Panel${NC}"
|
||||
echo -e " ${GRAY}VLESS, VMess, Trojan, Shadowsocks${NC}"
|
||||
echo ""
|
||||
echo -e " ${YELLOW}3.${NC} 🐳 ${WHITE}Remnawave Panel${NC}"
|
||||
echo -e " ${YELLOW}3.${NC} ${WHITE}Remnawave Panel${NC}"
|
||||
echo -e " ${GRAY}Современная панель с Docker${NC}"
|
||||
echo ""
|
||||
echo -e " ${YELLOW}4.${NC} ⚡ ${WHITE}Hysteria2 Proxy${NC}"
|
||||
echo -e " ${YELLOW}4.${NC} ${WHITE}Hysteria2 Proxy${NC}"
|
||||
echo -e " ${GRAY}Высокоскоростной прокси с маскировкой${NC}"
|
||||
echo ""
|
||||
echo -e " ${YELLOW}5.${NC} 📱 ${WHITE}MTProxy (Telegram)${NC}"
|
||||
echo -e " ${YELLOW}5.${NC} ${WHITE}MTProxy (Telegram)${NC}"
|
||||
echo -e " ${GRAY}Официальный прокси для Telegram${NC}"
|
||||
echo ""
|
||||
echo -e " ${GRAY}─────────────────────────────────────────────────────────────────${NC}"
|
||||
echo ""
|
||||
echo -e " ${YELLOW}6.${NC} 🚀 ${WHITE}Установить всё${NC}"
|
||||
echo -e " ${YELLOW}6.${NC} ${WHITE}Установить всё${NC}"
|
||||
echo -e " ${GRAY}Последовательная установка всех панелей${NC}"
|
||||
echo ""
|
||||
echo -e " ${YELLOW}0.${NC} ⬅️ ${WHITE}Назад / Back${NC}"
|
||||
echo -e " ${YELLOW}0.${NC} ${WHITE}Назад / Back${NC}"
|
||||
echo ""
|
||||
}
|
||||
|
||||
main() {
|
||||
check_root
|
||||
ensure_project_files
|
||||
load_defaults
|
||||
detect_os
|
||||
check_memory
|
||||
|
||||
mkdir -p "$PROJECT_DIR"
|
||||
load_language
|
||||
|
||||
while true; do
|
||||
@@ -813,6 +1036,20 @@ main() {
|
||||
read -p "Нажмите Enter / Press Enter..."
|
||||
fi
|
||||
;;
|
||||
2)
|
||||
run_project_script "manage.sh"
|
||||
;;
|
||||
3)
|
||||
backup_configs
|
||||
read -p "Нажмите Enter / Press Enter..."
|
||||
;;
|
||||
4)
|
||||
run_project_script "update.sh"
|
||||
;;
|
||||
5)
|
||||
uninstall_panels_menu
|
||||
read -p "Нажмите Enter / Press Enter..."
|
||||
;;
|
||||
7)
|
||||
# Запуск Reverse Proxy Manager
|
||||
if [ -f "$PROJECT_DIR/reverse-proxy-manager.sh" ]; then
|
||||
|
||||
+14
-2
@@ -23,8 +23,12 @@ get_next_wg_ip() {
|
||||
if [ -z "$LAST_IP" ]; then
|
||||
echo "10.0.0.2"
|
||||
else
|
||||
LAST_NUM=$(echo $LAST_IP | cut -d. -f4)
|
||||
LAST_NUM=$(echo "$LAST_IP" | cut -d. -f4)
|
||||
NEXT_NUM=$((LAST_NUM + 1))
|
||||
if [ "$NEXT_NUM" -gt 254 ]; then
|
||||
error "Пул адресов WireGuard исчерпан (10.0.0.2-10.0.0.254)"
|
||||
return 1
|
||||
fi
|
||||
echo "10.0.0.$NEXT_NUM"
|
||||
fi
|
||||
}
|
||||
@@ -147,7 +151,15 @@ remove_wireguard_client() {
|
||||
return 0
|
||||
fi
|
||||
|
||||
sed -i "/# $client_name/,+2d" $WG_CONF
|
||||
local tmp_conf
|
||||
tmp_conf="$(mktemp)"
|
||||
awk -v marker="# ${client_name}" '
|
||||
BEGIN {skip=0}
|
||||
$0 == marker {skip=1; next}
|
||||
skip && /^\[Peer\]/ {skip=0}
|
||||
!skip {print}
|
||||
' "$WG_CONF" > "$tmp_conf"
|
||||
mv "$tmp_conf" "$WG_CONF"
|
||||
rm -rf "$CLIENT_DIR"
|
||||
|
||||
systemctl restart wg-quick@wg0
|
||||
|
||||
@@ -19,6 +19,38 @@ warn() { echo -e "${YELLOW}[WARN]${NC} $1"; }
|
||||
error() { echo -e "${RED}[ERROR]${NC} $1"; }
|
||||
success() { echo -e "${GREEN}[SUCCESS]${NC} $1"; }
|
||||
|
||||
get_server_ip() {
|
||||
curl -s -4 ifconfig.me || curl -s -4 api.ipify.org || curl -s -4 ipinfo.io/ip
|
||||
}
|
||||
|
||||
validate_client_name() {
|
||||
local client_name=$1
|
||||
[[ "$client_name" =~ ^[a-zA-Z0-9_-]+$ ]]
|
||||
}
|
||||
|
||||
remove_wg_peer_block() {
|
||||
local client_name=$1
|
||||
local tmp_conf
|
||||
tmp_conf="$(mktemp)"
|
||||
awk -v marker="# ${client_name}" '
|
||||
BEGIN {skip=0}
|
||||
$0 == marker {skip=1; next}
|
||||
skip && /^\[Peer\]/ {skip=0}
|
||||
!skip {print}
|
||||
' /etc/wireguard/wg0.conf > "$tmp_conf"
|
||||
mv "$tmp_conf" /etc/wireguard/wg0.conf
|
||||
}
|
||||
|
||||
run_remote_script() {
|
||||
local url=$1
|
||||
local tmp_script
|
||||
tmp_script="$(mktemp /tmp/proxy-core-remote.XXXXXX.sh)"
|
||||
curl -fsSL "$url" -o "$tmp_script"
|
||||
chmod 700 "$tmp_script"
|
||||
bash "$tmp_script"
|
||||
rm -f "$tmp_script"
|
||||
}
|
||||
|
||||
# WireGuard Management
|
||||
manage_wireguard() {
|
||||
if ! systemctl is-active --quiet wg-quick@wg0; then
|
||||
@@ -84,6 +116,10 @@ add_wireguard_client() {
|
||||
error "Имя не может быть пустым"
|
||||
return 1
|
||||
fi
|
||||
if ! validate_client_name "$CLIENT_NAME"; then
|
||||
error "Неверное имя: только буквы, цифры, _ и -"
|
||||
return 1
|
||||
fi
|
||||
|
||||
CLIENT_DIR="/etc/wireguard/clients/$CLIENT_NAME"
|
||||
|
||||
@@ -102,7 +138,7 @@ add_wireguard_client() {
|
||||
CLIENT_PRIVATE_KEY=$(cat private.key)
|
||||
CLIENT_PUBLIC_KEY=$(cat public.key)
|
||||
SERVER_PUBLIC_KEY=$(cat /etc/wireguard/server_public.key)
|
||||
SERVER_IP=$(curl -s ifconfig.me)
|
||||
SERVER_IP=$(get_server_ip)
|
||||
SERVER_PORT=$(grep ListenPort /etc/wireguard/wg0.conf | awk '{print $3}')
|
||||
|
||||
# Get next available IP
|
||||
@@ -112,6 +148,10 @@ add_wireguard_client() {
|
||||
else
|
||||
LAST_NUM=$(echo $LAST_IP | cut -d. -f4)
|
||||
NEXT_NUM=$((LAST_NUM + 1))
|
||||
if [ "$NEXT_NUM" -gt 254 ]; then
|
||||
error "Пул адресов WireGuard исчерпан (10.0.0.2-10.0.0.254)"
|
||||
return 1
|
||||
fi
|
||||
CLIENT_IP="10.0.0.$NEXT_NUM"
|
||||
fi
|
||||
|
||||
@@ -146,7 +186,11 @@ EOF
|
||||
|
||||
echo ""
|
||||
log "QR-код для мобильных устройств:"
|
||||
if command -v qrencode >/dev/null 2>&1; then
|
||||
qrencode -t ansiutf8 < client.conf
|
||||
else
|
||||
warn "qrencode не установлен, пропускаем QR-код"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
read -p "Нажмите Enter..."
|
||||
@@ -182,6 +226,10 @@ remove_wireguard_client() {
|
||||
error "Имя не может быть пустым"
|
||||
return 1
|
||||
fi
|
||||
if ! validate_client_name "$CLIENT_NAME"; then
|
||||
error "Неверное имя: только буквы, цифры, _ и -"
|
||||
return 1
|
||||
fi
|
||||
|
||||
CLIENT_DIR="/etc/wireguard/clients/$CLIENT_NAME"
|
||||
|
||||
@@ -190,7 +238,7 @@ remove_wireguard_client() {
|
||||
return 1
|
||||
fi
|
||||
|
||||
sed -i "/# $CLIENT_NAME/,+2d" /etc/wireguard/wg0.conf
|
||||
remove_wg_peer_block "$CLIENT_NAME"
|
||||
rm -rf "$CLIENT_DIR"
|
||||
|
||||
systemctl restart wg-quick@wg0
|
||||
@@ -206,6 +254,10 @@ show_wireguard_qr() {
|
||||
error "Имя не может быть пустым"
|
||||
return 1
|
||||
fi
|
||||
if ! validate_client_name "$CLIENT_NAME"; then
|
||||
error "Неверное имя: только буквы, цифры, _ и -"
|
||||
return 1
|
||||
fi
|
||||
|
||||
CLIENT_DIR="/etc/wireguard/clients/$CLIENT_NAME"
|
||||
|
||||
@@ -220,7 +272,11 @@ show_wireguard_qr() {
|
||||
|
||||
echo ""
|
||||
log "QR-код:"
|
||||
if command -v qrencode >/dev/null 2>&1; then
|
||||
qrencode -t ansiutf8 < "$CLIENT_DIR/client.conf"
|
||||
else
|
||||
warn "qrencode не установлен, пропускаем QR-код"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
read -p "Нажмите Enter..."
|
||||
@@ -274,7 +330,7 @@ manage_3xui() {
|
||||
x-ui log
|
||||
;;
|
||||
6)
|
||||
bash <(curl -Ls https://raw.githubusercontent.com/mhsanaei/3x-ui/master/install.sh)
|
||||
run_remote_script "https://raw.githubusercontent.com/mhsanaei/3x-ui/master/install.sh"
|
||||
success "3x-ui обновлен"
|
||||
sleep 2
|
||||
;;
|
||||
|
||||
+59
-6
@@ -3,10 +3,13 @@
|
||||
# MTProxy Manager
|
||||
# Author: houseassassin
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
BLUE='\033[0;34m'
|
||||
CYAN='\033[0;36m'
|
||||
NC='\033[0m'
|
||||
|
||||
log() { echo -e "${GREEN}[INFO]${NC} $1"; }
|
||||
@@ -16,6 +19,18 @@ success() { echo -e "${GREEN}[SUCCESS]${NC} $1"; }
|
||||
|
||||
MTPROXY_DIR="/opt/MTProxy"
|
||||
|
||||
get_server_ip() {
|
||||
curl -s -4 ifconfig.me || curl -s -4 api.ipify.org || curl -s -4 ipinfo.io/ip
|
||||
}
|
||||
|
||||
validate_port() {
|
||||
local port=$1
|
||||
if ! [[ "$port" =~ ^[0-9]+$ ]] || [ "$port" -lt 1 ] || [ "$port" -gt 65535 ]; then
|
||||
return 1
|
||||
fi
|
||||
return 0
|
||||
}
|
||||
|
||||
check_installed() {
|
||||
if [ ! -d "$MTPROXY_DIR" ]; then
|
||||
error "MTProxy не установлен"
|
||||
@@ -30,7 +45,7 @@ get_connection_link() {
|
||||
fi
|
||||
|
||||
source "$MTPROXY_DIR/.config"
|
||||
SERVER_IP=$(curl -s ifconfig.me)
|
||||
SERVER_IP=$(get_server_ip)
|
||||
|
||||
echo ""
|
||||
log "Ссылка для подключения:"
|
||||
@@ -60,12 +75,29 @@ regenerate_secret() {
|
||||
return 0
|
||||
fi
|
||||
|
||||
source "$MTPROXY_DIR/.config"
|
||||
NEW_SECRET=$(head -c 16 /dev/urandom | xxd -ps)
|
||||
|
||||
# Обновляем конфигурацию
|
||||
sed -i "s/SECRET=.*/SECRET=$NEW_SECRET/" "$MTPROXY_DIR/.config"
|
||||
|
||||
cat > /etc/systemd/system/mtproxy.service <<EOF
|
||||
[Unit]
|
||||
Description=MTProxy Telegram Proxy
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
WorkingDirectory=$MTPROXY_DIR
|
||||
ExecStart=$MTPROXY_DIR/objs/bin/mtproto-proxy -u nobody -p $MTPROXY_PORT -H $MTPROXY_PORT -S $NEW_SECRET --aes-pwd proxy-secret proxy-multi.conf -M 1
|
||||
Restart=on-failure
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
EOF
|
||||
|
||||
# Перезапускаем сервис
|
||||
systemctl daemon-reload
|
||||
systemctl restart mtproxy
|
||||
|
||||
success "Новый секрет сгенерирован: $NEW_SECRET"
|
||||
@@ -81,6 +113,10 @@ change_port() {
|
||||
error "Порт не может быть пустым"
|
||||
return 1
|
||||
fi
|
||||
if ! validate_port "$NEW_PORT"; then
|
||||
error "Неверный порт: $NEW_PORT"
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Проверяем, что порт свободен
|
||||
if ss -ltun | grep -q ":$NEW_PORT "; then
|
||||
@@ -88,6 +124,9 @@ change_port() {
|
||||
return 1
|
||||
fi
|
||||
|
||||
source "$MTPROXY_DIR/.config"
|
||||
local old_port="$MTPROXY_PORT"
|
||||
|
||||
# Обновляем конфигурацию
|
||||
sed -i "s/MTPROXY_PORT=.*/MTPROXY_PORT=$NEW_PORT/" "$MTPROXY_DIR/.config"
|
||||
|
||||
@@ -113,8 +152,14 @@ EOF
|
||||
systemctl restart mtproxy
|
||||
|
||||
# Обновляем firewall
|
||||
ufw delete allow $MTPROXY_PORT/tcp 2>/dev/null
|
||||
ufw allow $NEW_PORT/tcp 2>/dev/null
|
||||
if command -v ufw >/dev/null 2>&1; then
|
||||
ufw delete allow $old_port/tcp 2>/dev/null || true
|
||||
ufw allow $NEW_PORT/tcp 2>/dev/null || true
|
||||
elif command -v firewall-cmd >/dev/null 2>&1; then
|
||||
firewall-cmd --permanent --remove-port="${old_port}/tcp" >/dev/null 2>&1 || true
|
||||
firewall-cmd --permanent --add-port="${NEW_PORT}/tcp" >/dev/null 2>&1 || true
|
||||
firewall-cmd --reload >/dev/null 2>&1 || true
|
||||
fi
|
||||
|
||||
success "Порт изменен на $NEW_PORT"
|
||||
get_connection_link
|
||||
@@ -156,7 +201,7 @@ show_stats() {
|
||||
# Количество подключений
|
||||
echo ""
|
||||
log "Активные подключения:"
|
||||
ss -tn | grep -c ":$(source $MTPROXY_DIR/.config && echo $MTPROXY_PORT) " || echo "0"
|
||||
ss -tn | grep -c ":$MTPROXY_PORT " || echo "0"
|
||||
|
||||
echo ""
|
||||
}
|
||||
@@ -183,6 +228,9 @@ uninstall_mtproxy() {
|
||||
return 0
|
||||
fi
|
||||
|
||||
source "$MTPROXY_DIR/.config" 2>/dev/null || true
|
||||
local mtproxy_port="${MTPROXY_PORT:-}"
|
||||
|
||||
# Остановка и удаление сервиса
|
||||
systemctl stop mtproxy
|
||||
systemctl disable mtproxy
|
||||
@@ -193,8 +241,12 @@ uninstall_mtproxy() {
|
||||
rm -rf "$MTPROXY_DIR"
|
||||
|
||||
# Удаление правила firewall
|
||||
source "$MTPROXY_DIR/.config" 2>/dev/null
|
||||
ufw delete allow $MTPROXY_PORT/tcp 2>/dev/null
|
||||
if [ -n "$mtproxy_port" ] && command -v ufw >/dev/null 2>&1; then
|
||||
ufw delete allow $mtproxy_port/tcp 2>/dev/null || true
|
||||
elif [ -n "$mtproxy_port" ] && command -v firewall-cmd >/dev/null 2>&1; then
|
||||
firewall-cmd --permanent --remove-port="${mtproxy_port}/tcp" >/dev/null 2>&1 || true
|
||||
firewall-cmd --reload >/dev/null 2>&1 || true
|
||||
fi
|
||||
|
||||
success "MTProxy удален"
|
||||
exit 0
|
||||
@@ -270,3 +322,4 @@ if [[ $EUID -ne 0 ]]; then
|
||||
fi
|
||||
|
||||
main_menu
|
||||
source "$MTPROXY_DIR/.config"
|
||||
|
||||
+68
-25
@@ -17,6 +17,7 @@ YELLOW='\033[1;33m'
|
||||
BLUE='\033[0;34m'
|
||||
MAGENTA='\033[0;35m'
|
||||
CYAN='\033[0;36m'
|
||||
WHITE='\033[1;37m'
|
||||
NC='\033[0m'
|
||||
|
||||
# Configuration
|
||||
@@ -115,6 +116,49 @@ configure_nginx_3xui() {
|
||||
read -p "Введите домен (например, vpn.example.com): " DOMAIN
|
||||
read -p "Введите порт 3x-ui (по умолчанию 2053): " XRAY_PORT
|
||||
XRAY_PORT=${XRAY_PORT:-2053}
|
||||
if ! [[ "$XRAY_PORT" =~ ^[0-9]+$ ]] || [ "$XRAY_PORT" -lt 1 ] || [ "$XRAY_PORT" -gt 65535 ]; then
|
||||
error "Неверный порт: $XRAY_PORT"
|
||||
return 1
|
||||
fi
|
||||
|
||||
cat > "$NGINX_DIR/sites-available/3xui" <<EOF
|
||||
server {
|
||||
listen 80;
|
||||
listen [::]:80;
|
||||
server_name $DOMAIN;
|
||||
|
||||
location /.well-known/acme-challenge/ {
|
||||
root /var/www/html;
|
||||
}
|
||||
|
||||
location / {
|
||||
return 301 https://\$server_name\$request_uri;
|
||||
}
|
||||
}
|
||||
|
||||
server {
|
||||
listen 443;
|
||||
listen [::]:443;
|
||||
server_name $DOMAIN;
|
||||
|
||||
location / {
|
||||
proxy_pass http://127.0.0.1:$XRAY_PORT;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Upgrade \$http_upgrade;
|
||||
proxy_set_header Connection "upgrade";
|
||||
proxy_set_header Host \$host;
|
||||
proxy_set_header X-Real-IP \$remote_addr;
|
||||
proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto \$scheme;
|
||||
}
|
||||
}
|
||||
EOF
|
||||
|
||||
ln -sf "$NGINX_DIR/sites-available/3xui" "$NGINX_DIR/sites-enabled/"
|
||||
nginx -t
|
||||
|
||||
log "Получение SSL сертификата..."
|
||||
certbot certonly --nginx -d $DOMAIN --non-interactive --agree-tos --email admin@$DOMAIN
|
||||
|
||||
cat > "$NGINX_DIR/sites-available/3xui" <<EOF
|
||||
server {
|
||||
@@ -155,11 +199,6 @@ server {
|
||||
}
|
||||
EOF
|
||||
|
||||
ln -sf "$NGINX_DIR/sites-available/3xui" "$NGINX_DIR/sites-enabled/"
|
||||
|
||||
log "Получение SSL сертификата..."
|
||||
certbot certonly --nginx -d $DOMAIN --non-interactive --agree-tos --email admin@$DOMAIN
|
||||
|
||||
nginx -t && systemctl reload nginx
|
||||
|
||||
success "Nginx настроен для 3x-ui на домене $DOMAIN"
|
||||
@@ -201,6 +240,10 @@ configure_haproxy_loadbalancer() {
|
||||
log "Настройка HAProxy для балансировки нагрузки..."
|
||||
|
||||
read -p "Введите количество backend серверов: " BACKEND_COUNT
|
||||
if ! [[ "$BACKEND_COUNT" =~ ^[0-9]+$ ]] || [ "$BACKEND_COUNT" -lt 1 ]; then
|
||||
error "Введите число больше 0"
|
||||
return 1
|
||||
fi
|
||||
|
||||
echo ""
|
||||
log "Введите IP адреса backend серверов:"
|
||||
@@ -306,12 +349,12 @@ show_tips() {
|
||||
clear
|
||||
echo ""
|
||||
echo -e "${MAGENTA}╔════════════════════════════════════════════════════════════════════╗${NC}"
|
||||
echo -e "${MAGENTA}║${NC} ${WHITE}💡 Подсказки по настройке Reverse Proxy${NC} ${MAGENTA}║${NC}"
|
||||
echo -e "${MAGENTA}║${NC} ${WHITE}Подсказки по настройке Reverse Proxy${NC} ${MAGENTA}║${NC}"
|
||||
echo -e "${MAGENTA}╚════════════════════════════════════════════════════════════════════╝${NC}"
|
||||
echo ""
|
||||
|
||||
echo -e " ${CYAN}╔═══════════════════════════════════════════════════════════════╗${NC}"
|
||||
echo -e " ${CYAN}║${NC} ${WHITE}🔧 Nginx${NC} ${CYAN}║${NC}"
|
||||
echo -e " ${CYAN}║${NC} ${WHITE}Nginx${NC} ${CYAN}║${NC}"
|
||||
echo -e " ${CYAN}╚═══════════════════════════════════════════════════════════════╝${NC}"
|
||||
echo -e " ${GREEN}✓${NC} Лучший выбор для высоких нагрузок"
|
||||
echo -e " ${GREEN}✓${NC} Отличное кэширование и обработка статики"
|
||||
@@ -320,7 +363,7 @@ show_tips() {
|
||||
echo ""
|
||||
|
||||
echo -e " ${CYAN}╔═══════════════════════════════════════════════════════════════╗${NC}"
|
||||
echo -e " ${CYAN}║${NC} ${WHITE}🚀 Caddy${NC} ${CYAN}║${NC}"
|
||||
echo -e " ${CYAN}║${NC} ${WHITE}Caddy${NC} ${CYAN}║${NC}"
|
||||
echo -e " ${CYAN}╚═══════════════════════════════════════════════════════════════╝${NC}"
|
||||
echo -e " ${GREEN}✓${NC} Автоматический SSL из коробки"
|
||||
echo -e " ${GREEN}✓${NC} Простая конфигурация"
|
||||
@@ -329,7 +372,7 @@ show_tips() {
|
||||
echo ""
|
||||
|
||||
echo -e " ${CYAN}╔═══════════════════════════════════════════════════════════════╗${NC}"
|
||||
echo -e " ${CYAN}║${NC} ${WHITE}⚖️ HAProxy${NC} ${CYAN}║${NC}"
|
||||
echo -e " ${CYAN}║${NC} ${WHITE}HAProxy${NC} ${CYAN}║${NC}"
|
||||
echo -e " ${CYAN}╚═══════════════════════════════════════════════════════════════╝${NC}"
|
||||
echo -e " ${GREEN}✓${NC} Лучший для балансировки нагрузки"
|
||||
echo -e " ${GREEN}✓${NC} TCP и HTTP режимы"
|
||||
@@ -338,7 +381,7 @@ show_tips() {
|
||||
echo ""
|
||||
|
||||
echo -e " ${CYAN}╔═══════════════════════════════════════════════════════════════╗${NC}"
|
||||
echo -e " ${CYAN}║${NC} ${WHITE}🔄 Гибридные решения${NC} ${CYAN}║${NC}"
|
||||
echo -e " ${CYAN}║${NC} ${WHITE}Гибридные решения${NC} ${CYAN}║${NC}"
|
||||
echo -e " ${CYAN}╚═══════════════════════════════════════════════════════════════╝${NC}"
|
||||
echo -e " ${BLUE}•${NC} Nginx + Caddy: статика + автоSSL"
|
||||
echo -e " ${BLUE}•${NC} HAProxy + Nginx: балансировка + кэш"
|
||||
@@ -346,7 +389,7 @@ show_tips() {
|
||||
echo ""
|
||||
|
||||
echo -e " ${YELLOW}╔═══════════════════════════════════════════════════════════════╗${NC}"
|
||||
echo -e " ${YELLOW}║${NC} ${WHITE}📋 Рекомендации${NC} ${YELLOW}║${NC}"
|
||||
echo -e " ${YELLOW}║${NC} ${WHITE}Рекомендации${NC} ${YELLOW}║${NC}"
|
||||
echo -e " ${YELLOW}╚═══════════════════════════════════════════════════════════════╝${NC}"
|
||||
echo -e " ${WHITE}1.${NC} Для простых VPN панелей: ${GREEN}Caddy${NC}"
|
||||
echo -e " ${WHITE}2.${NC} Для высоких нагрузок: ${GREEN}Nginx${NC}"
|
||||
@@ -364,7 +407,7 @@ show_main_menu() {
|
||||
clear
|
||||
echo ""
|
||||
echo -e "${CYAN}╔═══════════════════════════════════════════════════════════════════════╗${NC}"
|
||||
echo -e "${CYAN}║${MAGENTA} 🌐 REVERSE PROXY MANAGER ${CYAN}║${NC}"
|
||||
echo -e "${CYAN}║${MAGENTA} REVERSE PROXY MANAGER ${CYAN}║${NC}"
|
||||
echo -e "${CYAN}║${BLUE} Nginx • Caddy • HAProxy ${CYAN}║${NC}"
|
||||
echo -e "${CYAN}╚═══════════════════════════════════════════════════════════════════════╝${NC}"
|
||||
echo ""
|
||||
@@ -378,50 +421,50 @@ show_main_menu() {
|
||||
echo ""
|
||||
|
||||
echo -e " ${CYAN}╔═══════════════════════════════════════════════════════════════╗${NC}"
|
||||
echo -e " ${CYAN}║${NC} ${WHITE}📦 УСТАНОВКА${NC} ${CYAN}║${NC}"
|
||||
echo -e " ${CYAN}║${NC} ${WHITE}УСТАНОВКА${NC} ${CYAN}║${NC}"
|
||||
echo -e " ${CYAN}╚═══════════════════════════════════════════════════════════════╝${NC}"
|
||||
echo ""
|
||||
echo -e " ${YELLOW}1.${NC} 🔧 ${WHITE}Установить Nginx${NC}"
|
||||
echo -e " ${YELLOW}1.${NC} ${WHITE}Установить Nginx${NC}"
|
||||
echo -e " ${GRAY}Высокая производительность и кэширование${NC}"
|
||||
echo ""
|
||||
echo -e " ${YELLOW}2.${NC} 🚀 ${WHITE}Установить Caddy${NC}"
|
||||
echo -e " ${YELLOW}2.${NC} ${WHITE}Установить Caddy${NC}"
|
||||
echo -e " ${GRAY}Автоматический SSL из коробки${NC}"
|
||||
echo ""
|
||||
echo -e " ${YELLOW}3.${NC} ⚖️ ${WHITE}Установить HAProxy${NC}"
|
||||
echo -e " ${YELLOW}3.${NC} ${WHITE}Установить HAProxy${NC}"
|
||||
echo -e " ${GRAY}Балансировка нагрузки${NC}"
|
||||
echo ""
|
||||
|
||||
echo -e " ${CYAN}╔═══════════════════════════════════════════════════════════════╗${NC}"
|
||||
echo -e " ${CYAN}║${NC} ${WHITE}⚙️ НАСТРОЙКА${NC} ${CYAN}║${NC}"
|
||||
echo -e " ${CYAN}║${NC} ${WHITE}НАСТРОЙКА${NC} ${CYAN}║${NC}"
|
||||
echo -e " ${CYAN}╚═══════════════════════════════════════════════════════════════╝${NC}"
|
||||
echo ""
|
||||
echo -e " ${YELLOW}4.${NC} 🌐 ${WHITE}Настроить Nginx для 3x-ui${NC}"
|
||||
echo -e " ${YELLOW}4.${NC} ${WHITE}Настроить Nginx для 3x-ui${NC}"
|
||||
echo -e " ${GRAY}Автоматическая настройка с SSL${NC}"
|
||||
echo ""
|
||||
echo -e " ${YELLOW}5.${NC} 🔐 ${WHITE}Настроить Caddy для 3x-ui${NC}"
|
||||
echo -e " ${YELLOW}5.${NC} ${WHITE}Настроить Caddy для 3x-ui${NC}"
|
||||
echo -e " ${GRAY}Автоматический HTTPS${NC}"
|
||||
echo ""
|
||||
echo -e " ${YELLOW}6.${NC} ⚖️ ${WHITE}Настроить HAProxy (балансировка)${NC}"
|
||||
echo -e " ${YELLOW}6.${NC} ${WHITE}Настроить HAProxy (балансировка)${NC}"
|
||||
echo -e " ${GRAY}Распределение нагрузки между серверами${NC}"
|
||||
echo ""
|
||||
echo -e " ${YELLOW}7.${NC} 🔄 ${WHITE}Настроить Nginx + Caddy (гибрид)${NC}"
|
||||
echo -e " ${YELLOW}7.${NC} ${WHITE}Настроить Nginx + Caddy (гибрид)${NC}"
|
||||
echo -e " ${GRAY}Статика + автоматический SSL${NC}"
|
||||
echo ""
|
||||
|
||||
echo -e " ${CYAN}╔═══════════════════════════════════════════════════════════════╗${NC}"
|
||||
echo -e " ${CYAN}║${NC} ${WHITE}ℹ️ ИНФОРМАЦИЯ${NC} ${CYAN}║${NC}"
|
||||
echo -e " ${CYAN}║${NC} ${WHITE}ИНФОРМАЦИЯ${NC} ${CYAN}║${NC}"
|
||||
echo -e " ${CYAN}╚═══════════════════════════════════════════════════════════════╝${NC}"
|
||||
echo ""
|
||||
echo -e " ${YELLOW}8.${NC} 💡 ${WHITE}Показать подсказки${NC}"
|
||||
echo -e " ${YELLOW}8.${NC} ${WHITE}Показать подсказки${NC}"
|
||||
echo -e " ${GRAY}Рекомендации по выбору${NC}"
|
||||
echo ""
|
||||
echo -e " ${YELLOW}9.${NC} 📊 ${WHITE}Статус сервисов${NC}"
|
||||
echo -e " ${YELLOW}9.${NC} ${WHITE}Статус сервисов${NC}"
|
||||
echo -e " ${GRAY}Проверка работы установленных proxy${NC}"
|
||||
echo ""
|
||||
|
||||
echo -e " ${GRAY}─────────────────────────────────────────────────────────────────${NC}"
|
||||
echo ""
|
||||
echo -e " ${YELLOW}0.${NC} 🚪 ${WHITE}Выход${NC}"
|
||||
echo -e " ${YELLOW}0.${NC} ${WHITE}Выход${NC}"
|
||||
echo ""
|
||||
echo -e " ${GRAY}─────────────────────────────────────────────────────────────────${NC}"
|
||||
echo ""
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
# Author: houseassassin
|
||||
# GitHub: https://github.com/houseassassin/proxy-core
|
||||
|
||||
set -e
|
||||
set -euo pipefail
|
||||
|
||||
GREEN='\033[0;32m'
|
||||
RED='\033[0;31m'
|
||||
@@ -19,6 +19,16 @@ print_error() {
|
||||
echo -e "${RED}[ERROR]${NC} $1"
|
||||
}
|
||||
|
||||
run_remote_script() {
|
||||
local url=$1
|
||||
local tmp_script
|
||||
tmp_script="$(mktemp /tmp/proxy-core-remote.XXXXXX.sh)"
|
||||
curl -fsSL "$url" -o "$tmp_script"
|
||||
chmod 700 "$tmp_script"
|
||||
bash "$tmp_script"
|
||||
rm -f "$tmp_script"
|
||||
}
|
||||
|
||||
check_root() {
|
||||
if [[ $EUID -ne 0 ]]; then
|
||||
print_error "Требуются права root"
|
||||
@@ -28,7 +38,7 @@ check_root() {
|
||||
|
||||
update_3xui() {
|
||||
print_msg "Обновление 3x-ui..."
|
||||
bash <(curl -Ls https://raw.githubusercontent.com/mhsanaei/3x-ui/master/install.sh)
|
||||
run_remote_script "https://raw.githubusercontent.com/mhsanaei/3x-ui/master/install.sh"
|
||||
print_msg "3x-ui обновлен"
|
||||
}
|
||||
|
||||
|
||||
+55
-9
@@ -5,7 +5,7 @@
|
||||
# Author: houseassassin
|
||||
# GitHub: https://github.com/houseassassin/proxy-core
|
||||
|
||||
set -e
|
||||
set -euo pipefail
|
||||
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
@@ -30,6 +30,28 @@ check_root() {
|
||||
fi
|
||||
}
|
||||
|
||||
validate_client_name() {
|
||||
local client_name=$1
|
||||
[[ "$client_name" =~ ^[a-zA-Z0-9_-]+$ ]]
|
||||
}
|
||||
|
||||
get_server_ip() {
|
||||
curl -s -4 ifconfig.me || curl -s -4 api.ipify.org || curl -s -4 ipinfo.io/ip
|
||||
}
|
||||
|
||||
remove_peer_block() {
|
||||
local client_name=$1
|
||||
local tmp_conf
|
||||
tmp_conf="$(mktemp)"
|
||||
awk -v marker="# ${client_name}" '
|
||||
BEGIN {skip=0}
|
||||
$0 == marker {skip=1; next}
|
||||
skip && /^\[Peer\]/ {skip=0}
|
||||
!skip {print}
|
||||
' "$WG_CONF" > "$tmp_conf"
|
||||
mv "$tmp_conf" "$WG_CONF"
|
||||
}
|
||||
|
||||
get_next_ip() {
|
||||
if [ ! -f "$WG_CONF" ]; then
|
||||
echo "10.0.0.2"
|
||||
@@ -41,8 +63,12 @@ get_next_ip() {
|
||||
if [ -z "$LAST_IP" ]; then
|
||||
echo "10.0.0.2"
|
||||
else
|
||||
LAST_NUM=$(echo $LAST_IP | cut -d. -f4)
|
||||
LAST_NUM=$(echo "$LAST_IP" | cut -d. -f4)
|
||||
NEXT_NUM=$((LAST_NUM + 1))
|
||||
if [ "$NEXT_NUM" -gt 254 ]; then
|
||||
print_error "Пул адресов WireGuard исчерпан (10.0.0.2-10.0.0.254)"
|
||||
return 1
|
||||
fi
|
||||
echo "10.0.0.$NEXT_NUM"
|
||||
fi
|
||||
}
|
||||
@@ -54,6 +80,10 @@ add_client() {
|
||||
print_error "Имя клиента не может быть пустым"
|
||||
exit 1
|
||||
fi
|
||||
if ! validate_client_name "$CLIENT_NAME"; then
|
||||
print_error "Неверное имя: только буквы, цифры, _ и -"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
CLIENT_DIR="$WG_DIR/clients/$CLIENT_NAME"
|
||||
|
||||
@@ -70,12 +100,12 @@ add_client() {
|
||||
|
||||
CLIENT_PRIVATE_KEY=$(cat private.key)
|
||||
CLIENT_PUBLIC_KEY=$(cat public.key)
|
||||
SERVER_PUBLIC_KEY=$(cat $WG_DIR/server_public.key)
|
||||
SERVER_IP=$(curl -s ifconfig.me)
|
||||
SERVER_PORT=$(grep ListenPort $WG_CONF | awk '{print $3}')
|
||||
SERVER_PUBLIC_KEY=$(cat "$WG_DIR/server_public.key")
|
||||
SERVER_IP=$(get_server_ip)
|
||||
SERVER_PORT=$(grep ListenPort "$WG_CONF" | awk '{print $3}')
|
||||
CLIENT_IP=$(get_next_ip)
|
||||
|
||||
cat >> $WG_CONF <<EOF
|
||||
cat >> "$WG_CONF" <<EOF
|
||||
|
||||
[Peer]
|
||||
# $CLIENT_NAME
|
||||
@@ -104,7 +134,11 @@ EOF
|
||||
|
||||
echo ""
|
||||
print_msg "QR-код для мобильных устройств:"
|
||||
if command -v qrencode >/dev/null 2>&1; then
|
||||
qrencode -t ansiutf8 < client.conf
|
||||
else
|
||||
print_error "qrencode не установлен, пропускаем QR-код"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
print_msg "Конфигурация клиента:"
|
||||
@@ -120,10 +154,10 @@ list_clients() {
|
||||
return
|
||||
fi
|
||||
|
||||
for client in $WG_DIR/clients/*; do
|
||||
for client in "$WG_DIR"/clients/*; do
|
||||
if [ -d "$client" ]; then
|
||||
CLIENT_NAME=$(basename "$client")
|
||||
CLIENT_IP=$(grep -A 2 "# $CLIENT_NAME" $WG_CONF | grep AllowedIPs | awk '{print $3}' | cut -d/ -f1)
|
||||
CLIENT_IP=$(grep -A 2 "# $CLIENT_NAME" "$WG_CONF" | grep AllowedIPs | awk '{print $3}' | cut -d/ -f1)
|
||||
echo "- $CLIENT_NAME ($CLIENT_IP)"
|
||||
fi
|
||||
done
|
||||
@@ -136,6 +170,10 @@ remove_client() {
|
||||
print_error "Имя клиента не может быть пустым"
|
||||
exit 1
|
||||
fi
|
||||
if ! validate_client_name "$CLIENT_NAME"; then
|
||||
print_error "Неверное имя: только буквы, цифры, _ и -"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
CLIENT_DIR="$WG_DIR/clients/$CLIENT_NAME"
|
||||
|
||||
@@ -144,7 +182,7 @@ remove_client() {
|
||||
exit 1
|
||||
fi
|
||||
|
||||
sed -i "/# $CLIENT_NAME/,+2d" $WG_CONF
|
||||
remove_peer_block "$CLIENT_NAME"
|
||||
rm -rf "$CLIENT_DIR"
|
||||
|
||||
systemctl restart wg-quick@wg0
|
||||
@@ -159,6 +197,10 @@ show_client() {
|
||||
print_error "Имя клиента не может быть пустым"
|
||||
exit 1
|
||||
fi
|
||||
if ! validate_client_name "$CLIENT_NAME"; then
|
||||
print_error "Неверное имя: только буквы, цифры, _ и -"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
CLIENT_DIR="$WG_DIR/clients/$CLIENT_NAME"
|
||||
|
||||
@@ -172,7 +214,11 @@ show_client() {
|
||||
|
||||
echo ""
|
||||
print_msg "QR-код:"
|
||||
if command -v qrencode >/dev/null 2>&1; then
|
||||
qrencode -t ansiutf8 < "$CLIENT_DIR/client.conf"
|
||||
else
|
||||
print_error "qrencode не установлен, пропускаем QR-код"
|
||||
fi
|
||||
}
|
||||
|
||||
show_menu() {
|
||||
|
||||
Reference in New Issue
Block a user