фича: полноценная поддержка нескольких VPS серверов и автоопределение по домену (v1.0.5)
This commit is contained in:
parent
e21d37a3e7
commit
e3c7163233
592
rproxy
592
rproxy
|
|
@ -3,10 +3,11 @@
|
||||||
# Публикация локальных сервисов через SSH-туннели + nginx на VPS
|
# Публикация локальных сервисов через SSH-туннели + nginx на VPS
|
||||||
# http://5.104.75.50:3000/Petro1990/rProxy
|
# http://5.104.75.50:3000/Petro1990/rProxy
|
||||||
|
|
||||||
VERSION="1.0.4"
|
VERSION="1.0.5"
|
||||||
CONF_DIR="/opt/etc/rproxy"
|
CONF_DIR="/opt/etc/rproxy"
|
||||||
CONF_FILE="$CONF_DIR/rproxy.conf"
|
CONF_FILE="$CONF_DIR/rproxy.conf"
|
||||||
SERVICES_DIR="$CONF_DIR/services"
|
SERVICES_DIR="$CONF_DIR/services"
|
||||||
|
VPS_DIR="$CONF_DIR/vps"
|
||||||
PID_DIR="/opt/var/run/rproxy"
|
PID_DIR="/opt/var/run/rproxy"
|
||||||
SSH_KEY="$CONF_DIR/id_ed25519"
|
SSH_KEY="$CONF_DIR/id_ed25519"
|
||||||
REMOTE_NGINX_DIR="/etc/nginx/sites-enabled"
|
REMOTE_NGINX_DIR="/etc/nginx/sites-enabled"
|
||||||
|
|
@ -56,6 +57,8 @@ check_conf() {
|
||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
. "$CONF_FILE"
|
. "$CONF_FILE"
|
||||||
|
# Для работы нужно, чтобы был хотя бы один VPS профиль
|
||||||
|
[ "$(ls -A "$VPS_DIR" 2>/dev/null)" ] || return 1
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -66,6 +69,47 @@ load_service() {
|
||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
. "$svc_file"
|
. "$svc_file"
|
||||||
|
# При загрузке сервиса также загружаем его VPS
|
||||||
|
if [ -n "$SVC_VPS" ]; then
|
||||||
|
load_vps "$SVC_VPS" || return 1
|
||||||
|
else
|
||||||
|
# Обратная совместимость: если VPS не указан, пробуем default
|
||||||
|
load_vps "default" || return 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
load_vps() {
|
||||||
|
local vps_id="$1"
|
||||||
|
local vps_file="$VPS_DIR/$vps_id.conf"
|
||||||
|
if [ ! -f "$vps_file" ]; then
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
# Сброс старых переменных перед загрузкой
|
||||||
|
VPS_HOST="" VPS_PORT="" VPS_USER="" VPS_AUTH="" VPS_PASS=""
|
||||||
|
. "$vps_file"
|
||||||
|
CUR_VPS_ID="$vps_id"
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
migrate_config() {
|
||||||
|
mkdir -p "$VPS_DIR" "$SERVICES_DIR" "$PID_DIR"
|
||||||
|
if [ -f "$CONF_FILE" ] && [ ! -f "$VPS_DIR/default.conf" ]; then
|
||||||
|
msg "Миграция конфигурации в новый формат..."
|
||||||
|
# Копируем параметры в профиль default
|
||||||
|
cat > "$VPS_DIR/default.conf" <<EOF
|
||||||
|
VPS_HOST="$VPS_HOST"
|
||||||
|
VPS_PORT="$VPS_PORT"
|
||||||
|
VPS_USER="$VPS_USER"
|
||||||
|
VPS_AUTH="$VPS_AUTH"
|
||||||
|
VPS_PASS="$VPS_PASS"
|
||||||
|
EOF
|
||||||
|
# В основном конфиге оставляем только глобальные настройки
|
||||||
|
cat > "$CONF_FILE.tmp" <<EOF
|
||||||
|
CERTBOT_EMAIL="$CERTBOT_EMAIL"
|
||||||
|
EOF
|
||||||
|
mv "$CONF_FILE.tmp" "$CONF_FILE"
|
||||||
|
chmod 600 "$VPS_DIR/default.conf" "$CONF_FILE"
|
||||||
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
ssh_cmd() {
|
ssh_cmd() {
|
||||||
|
|
@ -150,16 +194,19 @@ main_menu() {
|
||||||
continue
|
continue
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Подсчёт сервисов и статусов
|
# Подсчёт сервисов и статусов по всем VPS
|
||||||
local total=0 online=0
|
local total=0 online=0
|
||||||
for f in "$SERVICES_DIR"/*.conf; do
|
for f in "$SERVICES_DIR"/*.conf; do
|
||||||
[ -f "$f" ] || continue
|
[ -f "$f" ] || continue
|
||||||
total=$((total + 1))
|
total=$((total + 1))
|
||||||
|
(
|
||||||
. "$f"
|
. "$f"
|
||||||
is_running "$SVC_NAME" && online=$((online + 1))
|
is_running "$SVC_NAME" && exit 0
|
||||||
|
exit 1
|
||||||
|
) && online=$((online + 1))
|
||||||
done
|
done
|
||||||
|
|
||||||
printf " ${DIM}VPS:${NC} ${BOLD}$VPS_HOST${NC} "
|
printf " ${DIM}Серверов VPS:${NC} ${BOLD}$(ls -A "$VPS_DIR" | wc -l)${NC} "
|
||||||
printf "${DIM}Сервисов:${NC} ${BOLD}$total${NC} "
|
printf "${DIM}Сервисов:${NC} ${BOLD}$total${NC} "
|
||||||
printf "${DIM}Онлайн:${NC} ${GREEN}${BOLD}$online${NC}\n"
|
printf "${DIM}Онлайн:${NC} ${GREEN}${BOLD}$online${NC}\n"
|
||||||
draw_separator
|
draw_separator
|
||||||
|
|
@ -216,7 +263,8 @@ show_status() {
|
||||||
[ -f "$f" ] || continue
|
[ -f "$f" ] || continue
|
||||||
has_services=1
|
has_services=1
|
||||||
idx=$((idx + 1))
|
idx=$((idx + 1))
|
||||||
. "$f"
|
(
|
||||||
|
load_service "$(basename "$f" .conf)" >/dev/null 2>&1
|
||||||
|
|
||||||
local status_text
|
local status_text
|
||||||
if is_running "$SVC_NAME"; then
|
if is_running "$SVC_NAME"; then
|
||||||
|
|
@ -231,6 +279,7 @@ show_status() {
|
||||||
|
|
||||||
printf " %-4s %-14s %-22s %-7s ${status_text} %-18s${auto_text}\n" \
|
printf " %-4s %-14s %-22s %-7s ${status_text} %-18s${auto_text}\n" \
|
||||||
"$idx" "$SVC_NAME" "$SVC_TARGET_HOST:$SVC_TARGET_PORT" "$SVC_EXT_PORT" "$domain_text"
|
"$idx" "$SVC_NAME" "$SVC_TARGET_HOST:$SVC_TARGET_PORT" "$SVC_EXT_PORT" "$domain_text"
|
||||||
|
)
|
||||||
done
|
done
|
||||||
|
|
||||||
if [ "$has_services" -eq 0 ]; then
|
if [ "$has_services" -eq 0 ]; then
|
||||||
|
|
@ -242,6 +291,65 @@ show_status() {
|
||||||
pause
|
pause
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# ══════════════════════════════════════════════════════════════════════
|
||||||
|
# ══════════════════════════════════════════════════════════════════════
|
||||||
|
# ПОМОЩНИКИ VPS
|
||||||
|
# ══════════════════════════════════════════════════════════════════════
|
||||||
|
|
||||||
|
find_vps_by_domain() {
|
||||||
|
local dom="$1"
|
||||||
|
# Пытаемся получить IP через ping (BusyBox стиль)
|
||||||
|
local ip=$(ping -c 1 "$dom" 2>/dev/null | grep -o "[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}" | head -n 1)
|
||||||
|
# Если не вышло, пробуем nslookup
|
||||||
|
[ -z "$ip" ] && ip=$(nslookup "$dom" 2>/dev/null | grep "Address" | tail -n 1 | awk '{print $2}')
|
||||||
|
|
||||||
|
[ -z "$ip" ] && return 1
|
||||||
|
|
||||||
|
for f in "$VPS_DIR"/*.conf; do
|
||||||
|
[ -f "$f" ] || continue
|
||||||
|
(
|
||||||
|
VPS_HOST=""
|
||||||
|
. "$f"
|
||||||
|
if [ "$VPS_HOST" = "$ip" ]; then
|
||||||
|
basename "$f" .conf
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
exit 1
|
||||||
|
) && { basename "$f" .conf; return 0; }
|
||||||
|
done
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
select_vps_interactive() {
|
||||||
|
clear_screen
|
||||||
|
draw_box "Выберите VPS для сервиса"
|
||||||
|
printf "\n"
|
||||||
|
local vps_list=""
|
||||||
|
local idx=0
|
||||||
|
for f in "$VPS_DIR"/*.conf; do
|
||||||
|
[ -f "$f" ] || continue
|
||||||
|
idx=$((idx + 1))
|
||||||
|
(
|
||||||
|
. "$f"
|
||||||
|
printf " ${BOLD}%d)${NC} %s (${DIM}%s${NC})\n" "$idx" "$(basename "$f" .conf)" "$VPS_HOST"
|
||||||
|
)
|
||||||
|
vps_list="$vps_list $(basename "$f" .conf)"
|
||||||
|
done
|
||||||
|
|
||||||
|
printf " ${BOLD}n)${NC} ➕ Добавить новый VPS\n"
|
||||||
|
prompt "Выберите номер или 'n': "
|
||||||
|
|
||||||
|
if [ "$REPLY" = "n" ] || [ "$REPLY" = "N" ]; then
|
||||||
|
do_add_vps
|
||||||
|
# Возвращаем последний созданный (упрощение)
|
||||||
|
ls -t "$VPS_DIR"/*.conf | head -n 1 | xargs basename | sed 's/\.conf//'
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
local sel=$(echo "$vps_list" | cut -d' ' -f"$REPLY")
|
||||||
|
echo "$sel"
|
||||||
|
}
|
||||||
|
|
||||||
# ══════════════════════════════════════════════════════════════════════
|
# ══════════════════════════════════════════════════════════════════════
|
||||||
# ДОБАВИТЬ СЕРВИС (интерактивно)
|
# ДОБАВИТЬ СЕРВИС (интерактивно)
|
||||||
# ══════════════════════════════════════════════════════════════════════
|
# ══════════════════════════════════════════════════════════════════════
|
||||||
|
|
@ -256,11 +364,10 @@ do_add_interactive() {
|
||||||
|
|
||||||
if [ -f "$SERVICES_DIR/$name.conf" ]; then
|
if [ -f "$SERVICES_DIR/$name.conf" ]; then
|
||||||
err "Сервис '$name' уже существует"
|
err "Сервис '$name' уже существует"
|
||||||
pause
|
pause; return
|
||||||
return
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
prompt "Адрес локального сервиса (например, 192.168.1.100:8080): "
|
prompt "Адрес локального сервиса (например, 127.0.0.1:8080): "
|
||||||
local target="$REPLY"
|
local target="$REPLY"
|
||||||
[ -z "$target" ] && { warn "Адрес не может быть пустым"; pause; return; }
|
[ -z "$target" ] && { warn "Адрес не может быть пустым"; pause; return; }
|
||||||
|
|
||||||
|
|
@ -270,153 +377,92 @@ do_add_interactive() {
|
||||||
prompt "Выберите [2]: "
|
prompt "Выберите [2]: "
|
||||||
local mode="${REPLY:-2}"
|
local mode="${REPLY:-2}"
|
||||||
|
|
||||||
local domain=""
|
local domain="" ext_port="" use_ssl="no" vps_id=""
|
||||||
local ext_port=""
|
|
||||||
local use_ssl="no"
|
|
||||||
|
|
||||||
if [ "$mode" = "1" ]; then
|
if [ "$mode" = "1" ]; then
|
||||||
prompt "Доменное имя (например, mysite.example.com): "
|
prompt "Доменное имя (например, mysite.example.com): "
|
||||||
domain="$REPLY"
|
domain="$REPLY"
|
||||||
[ -z "$domain" ] && { warn "Домен не указан"; pause; return; }
|
[ -z "$domain" ] && { warn "Домен не указан"; pause; return; }
|
||||||
|
use_ssl="yes"; ext_port=443
|
||||||
|
|
||||||
# SSL теперь всегда включен для доменов по запросу пользователя
|
|
||||||
use_ssl="yes"
|
|
||||||
ext_port=443
|
|
||||||
if [ -z "$CERTBOT_EMAIL" ]; then
|
if [ -z "$CERTBOT_EMAIL" ]; then
|
||||||
prompt "Введите Email для регистрации сертификатов (Certbot): "
|
prompt "Введите Email для Certbot: "
|
||||||
CERTBOT_EMAIL="$REPLY"
|
CERTBOT_EMAIL="$REPLY"
|
||||||
# Сохраняем email в конфиг
|
|
||||||
sed -i "/CERTBOT_EMAIL=/d" "$CONF_FILE"
|
sed -i "/CERTBOT_EMAIL=/d" "$CONF_FILE"
|
||||||
echo "CERTBOT_EMAIL=\"$CERTBOT_EMAIL\"" >> "$CONF_FILE"
|
echo "CERTBOT_EMAIL=\"$CERTBOT_EMAIL\"" >> "$CONF_FILE"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# Автоопределение VPS по домену
|
||||||
|
msg "Проверяю куда направлен домен $domain..."
|
||||||
|
vps_id=$(find_vps_by_domain "$domain")
|
||||||
|
if [ -n "$vps_id" ]; then
|
||||||
|
msg "Домен $domain указывает на ваш VPS '$vps_id'. Выбираю его."
|
||||||
else
|
else
|
||||||
local suggested
|
warn "Не удалось автоматически определить VPS для $domain"
|
||||||
suggested=$(next_free_port)
|
|
||||||
prompt "Внешний порт [$suggested]: "
|
|
||||||
ext_port="${REPLY:-$suggested}"
|
|
||||||
use_ssl="no"
|
|
||||||
fi
|
fi
|
||||||
|
else
|
||||||
|
ext_port=$(next_free_port)
|
||||||
|
prompt "Внешний порт [$ext_port]: "
|
||||||
|
ext_port="${REPLY:-$ext_port}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Если VPS не определен автоматически — выбираем вручную
|
||||||
|
if [ -z "$vps_id" ]; then
|
||||||
|
vps_id=$(select_vps_interactive)
|
||||||
|
[ -z "$vps_id" ] && { warn "VPS не выбран"; pause; return; }
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Загружаем выбранный VPS для деплоя
|
||||||
|
load_vps "$vps_id" || { err "Не удалось загрузить VPS '$vps_id'"; pause; return; }
|
||||||
|
|
||||||
# Разбор адреса
|
# Разбор адреса
|
||||||
local target_host="${target%:*}"
|
local t_host="${target%:*}"
|
||||||
local target_port="${target#*:}"
|
local t_port="${target#*:}"
|
||||||
if [ "$target_host" = "$target_port" ]; then
|
[ "$t_host" = "$t_port" ] && { t_port="$t_host"; t_host="127.0.0.1"; }
|
||||||
target_port="$target_host"
|
|
||||||
target_host="127.0.0.1"
|
|
||||||
fi
|
|
||||||
|
|
||||||
local tunnel_port
|
local tunnel_port=$(next_free_port)
|
||||||
tunnel_port=$(next_free_port)
|
|
||||||
|
|
||||||
printf "\n"
|
printf "\n"
|
||||||
draw_separator
|
draw_separator
|
||||||
printf " ${BOLD}Сервис:${NC} $name\n"
|
printf " ${BOLD}Сервис:${NC} $name\n"
|
||||||
printf " ${BOLD}Цель:${NC} $target_host:$target_port\n"
|
printf " ${BOLD}VPS:${NC} $vps_id ($VPS_HOST)\n"
|
||||||
|
printf " ${BOLD}Цель:${NC} $t_host:$t_port\n"
|
||||||
printf " ${BOLD}Туннель:${NC} порт $tunnel_port\n"
|
printf " ${BOLD}Туннель:${NC} порт $tunnel_port\n"
|
||||||
[ -n "$domain" ] && printf " ${BOLD}Домен:${NC} $domain\n"
|
[ -n "$domain" ] && printf " ${BOLD}Домен:${NC} $domain\n"
|
||||||
printf " ${BOLD}Внешний порт:${NC} $ext_port\n"
|
printf " ${BOLD}Внешний порт:${NC} $ext_port\n"
|
||||||
[ "$use_ssl" = "yes" ] && printf " ${BOLD}SSL:${NC} Включен (Certbot)\n"
|
|
||||||
draw_separator
|
draw_separator
|
||||||
|
|
||||||
prompt "Всё верно? Добавить сервис? (д/н) [д]: "
|
prompt "Всё верно? Добавить сервис? (д/н) [д]: "
|
||||||
local confirm="${REPLY:-д}"
|
[ "${REPLY:-д}" != "д" ] && [ "${REPLY:-д}" != "y" ] && { msg "Отменено"; pause; return; }
|
||||||
case "$confirm" in
|
|
||||||
д|Д|y|Y|да|yes) ;;
|
|
||||||
*) msg "Отменено"; pause; return ;;
|
|
||||||
esac
|
|
||||||
|
|
||||||
printf "\n"
|
|
||||||
msg "Добавляю сервис '$name'..."
|
msg "Добавляю сервис '$name'..."
|
||||||
|
|
||||||
# Генерация конфига nginx
|
# Конфиг nginx (упрощенная генерация)
|
||||||
local nginx_conf=""
|
local nginx_conf
|
||||||
if [ -n "$domain" ]; then
|
if [ -n "$domain" ]; then
|
||||||
# Для домена всегда сначала создаем конфиг на 80 порт
|
nginx_conf="server { listen 80; server_name $domain; location / { proxy_pass http://127.0.0.1:$tunnel_port; proxy_set_header Host \$host; proxy_set_header X-Real-IP \$remote_addr; } }"
|
||||||
# Если нужен SSL, Certbot сам его проапгрейдит
|
|
||||||
nginx_conf="# rProxy: $name
|
|
||||||
server {
|
|
||||||
listen 80;
|
|
||||||
server_name $domain;
|
|
||||||
|
|
||||||
location / {
|
|
||||||
proxy_pass http://127.0.0.1:$tunnel_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;
|
|
||||||
proxy_connect_timeout 60s;
|
|
||||||
proxy_send_timeout 60s;
|
|
||||||
proxy_read_timeout 60s;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
"
|
|
||||||
else
|
else
|
||||||
nginx_conf="# rProxy: $name
|
nginx_conf="server { listen $ext_port; location / { proxy_pass http://127.0.0.1:$tunnel_port; proxy_set_header Host \$host; } }"
|
||||||
server {
|
|
||||||
listen $ext_port;
|
|
||||||
|
|
||||||
location / {
|
|
||||||
proxy_pass http://127.0.0.1:$tunnel_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;
|
|
||||||
proxy_connect_timeout 60s;
|
|
||||||
proxy_send_timeout 60s;
|
|
||||||
proxy_read_timeout 60s;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
"
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Деплой nginx конфига на VPS
|
# Деплой
|
||||||
msg "Загружаю конфигурацию nginx..."
|
local tmp="/tmp/rproxy_$name.conf"
|
||||||
local tmp_file="/tmp/rproxy_nginx_$name.conf"
|
echo "$nginx_conf" > "$tmp"
|
||||||
printf '%s' "$nginx_conf" > "$tmp_file"
|
scp_cmd "$tmp" "$VPS_USER@$VPS_HOST:$REMOTE_NGINX_DIR/rproxy_$name.conf" || { err "Ошибка деплоя nginx"; pause; return; }
|
||||||
scp_cmd "$tmp_file" "$VPS_USER@$VPS_HOST:$REMOTE_NGINX_DIR/rproxy_$name.conf" || {
|
ssh_cmd "nginx -t && systemctl reload nginx" >/dev/null 2>&1
|
||||||
err "Не удалось загрузить конфиг nginx на VPS"
|
|
||||||
rm -f "$tmp_file"
|
|
||||||
pause
|
|
||||||
return
|
|
||||||
}
|
|
||||||
rm -f "$tmp_file"
|
|
||||||
|
|
||||||
# Проверка и перезагрузка nginx
|
# SSL если нужно
|
||||||
msg "Проверяю конфигурацию nginx на VPS..."
|
|
||||||
local nginx_test
|
|
||||||
nginx_test=$(ssh_cmd "nginx -t 2>&1")
|
|
||||||
if [ $? -ne 0 ]; then
|
|
||||||
err "Ошибка в конфигурации nginx на VPS:"
|
|
||||||
printf " ${DIM}%s${NC}\n" "$nginx_test"
|
|
||||||
ssh_cmd "rm -f $REMOTE_NGINX_DIR/rproxy_$name.conf"
|
|
||||||
pause
|
|
||||||
return
|
|
||||||
fi
|
|
||||||
ssh_cmd "systemctl reload nginx" >/dev/null 2>&1
|
|
||||||
|
|
||||||
# Получение SSL сертификата если нужно
|
|
||||||
if [ "$use_ssl" = "yes" ]; then
|
if [ "$use_ssl" = "yes" ]; then
|
||||||
msg "Получаю SSL сертификат через Certbot (может занять время)..."
|
msg "Получаю SSL через Certbot (может занять время)..."
|
||||||
ssh_cmd "certbot --nginx -d $domain --non-interactive --agree-tos -m $CERTBOT_EMAIL" || {
|
ssh_cmd "certbot --nginx -d $domain --non-interactive --agree-tos -m $CERTBOT_EMAIL" || warn "Certbot вернул ошибку"
|
||||||
warn "Certbot не смог получить сертификат. Проверьте DNS и доступность порта 80."
|
|
||||||
use_ssl="no"
|
|
||||||
ext_port=80
|
|
||||||
}
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|
||||||
# Сохранение конфига сервиса
|
# Сохранение конфига сервиса
|
||||||
cat > "$SERVICES_DIR/$name.conf" <<EOF
|
cat > "$SERVICES_DIR/$name.conf" <<EOF
|
||||||
# rProxy сервис: $name
|
|
||||||
SVC_NAME="$name"
|
SVC_NAME="$name"
|
||||||
SVC_TARGET_HOST="$target_host"
|
SVC_VPS="$vps_id"
|
||||||
SVC_TARGET_PORT="$target_port"
|
SVC_TARGET_HOST="$t_host"
|
||||||
|
SVC_TARGET_PORT="$t_port"
|
||||||
SVC_TUNNEL_PORT="$tunnel_port"
|
SVC_TUNNEL_PORT="$tunnel_port"
|
||||||
SVC_EXT_PORT="$ext_port"
|
SVC_EXT_PORT="$ext_port"
|
||||||
SVC_DOMAIN="$domain"
|
SVC_DOMAIN="$domain"
|
||||||
|
|
@ -424,9 +470,7 @@ SVC_SSL="$use_ssl"
|
||||||
SVC_ENABLED="yes"
|
SVC_ENABLED="yes"
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
msg "Сервис '$name' добавлен!"
|
msg "Сервис '$name' добавлен на VPS '$vps_id'!"
|
||||||
|
|
||||||
# Автозапуск туннеля
|
|
||||||
do_start_service "$name"
|
do_start_service "$name"
|
||||||
pause
|
pause
|
||||||
}
|
}
|
||||||
|
|
@ -515,6 +559,13 @@ do_health_check() {
|
||||||
draw_box "Состояние VPS и SSL"
|
draw_box "Состояние VPS и SSL"
|
||||||
printf "\n"
|
printf "\n"
|
||||||
|
|
||||||
|
for f in "$VPS_DIR"/*.conf; do
|
||||||
|
[ -f "$f" ] || continue
|
||||||
|
local vps_id=$(basename "$f" .conf)
|
||||||
|
load_vps "$vps_id"
|
||||||
|
|
||||||
|
header "Сервер: $vps_id ($VPS_HOST)"
|
||||||
|
|
||||||
msg "Проверяю Nginx..."
|
msg "Проверяю Nginx..."
|
||||||
if ssh_cmd "systemctl is-active nginx >/dev/null 2>&1"; then
|
if ssh_cmd "systemctl is-active nginx >/dev/null 2>&1"; then
|
||||||
printf " Nginx: ${GREEN}${BOLD}Запущен${NC}\n"
|
printf " Nginx: ${GREEN}${BOLD}Запущен${NC}\n"
|
||||||
|
|
@ -529,7 +580,6 @@ do_health_check() {
|
||||||
local next_run=$(ssh_cmd "systemctl list-timers certbot.timer --no-legend 2>/dev/null | awk '{print \$1, \$2}'" | head -n 1)
|
local next_run=$(ssh_cmd "systemctl list-timers certbot.timer --no-legend 2>/dev/null | awk '{print \$1, \$2}'" | head -n 1)
|
||||||
[ -n "$next_run" ] && printf " Следующее: $next_run\n"
|
[ -n "$next_run" ] && printf " Следующее: $next_run\n"
|
||||||
else
|
else
|
||||||
# Проверка cron
|
|
||||||
if ssh_cmd "crontab -l 2>/dev/null | grep -q certbot"; then
|
if ssh_cmd "crontab -l 2>/dev/null | grep -q certbot"; then
|
||||||
printf " SSL Renewal: ${GREEN}${BOLD}Настроено (Cron)${NC}\n"
|
printf " SSL Renewal: ${GREEN}${BOLD}Настроено (Cron)${NC}\n"
|
||||||
else
|
else
|
||||||
|
|
@ -538,9 +588,15 @@ do_health_check() {
|
||||||
fi
|
fi
|
||||||
|
|
||||||
msg "Действующие сертификаты:"
|
msg "Действующие сертификаты:"
|
||||||
ssh_cmd "certbot certificates 2>/dev/null | grep -E 'Expiry Date:|Domains:'" | while read -r line; do
|
local certs=$(ssh_cmd "certbot certificates 2>/dev/null | grep -E 'Expiry Date:|Domains:'")
|
||||||
|
if [ -n "$certs" ]; then
|
||||||
|
echo "$certs" | while read -r line; do
|
||||||
printf " %s\n" "$line"
|
printf " %s\n" "$line"
|
||||||
done
|
done
|
||||||
|
else
|
||||||
|
printf " ${DIM}Сертификаты не найдены${NC}\n"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
printf "\n"
|
printf "\n"
|
||||||
msg "Утилиты на роутере:"
|
msg "Утилиты на роутере:"
|
||||||
|
|
@ -768,6 +824,7 @@ do_start_service() {
|
||||||
|
|
||||||
do_stop_service() {
|
do_stop_service() {
|
||||||
local name="$1"
|
local name="$1"
|
||||||
|
load_service "$name" || return # Загружаем VPS для правильной очистки
|
||||||
local pid_file
|
local pid_file
|
||||||
pid_file=$(get_pid_file "$name")
|
pid_file=$(get_pid_file "$name")
|
||||||
|
|
||||||
|
|
@ -779,7 +836,7 @@ do_stop_service() {
|
||||||
local pid
|
local pid
|
||||||
pid=$(cat "$pid_file")
|
pid=$(cat "$pid_file")
|
||||||
kill "$pid" 2>/dev/null
|
kill "$pid" 2>/dev/null
|
||||||
pkill -f "ssh.*:$name.*$VPS_HOST" 2>/dev/null
|
pkill -f "ssh.*:$SVC_TUNNEL_PORT:.*$VPS_HOST" 2>/dev/null
|
||||||
|
|
||||||
rm -f "$pid_file"
|
rm -f "$pid_file"
|
||||||
msg "Туннель '$name' остановлен"
|
msg "Туннель '$name' остановлен"
|
||||||
|
|
@ -802,190 +859,176 @@ do_stop_all() {
|
||||||
}
|
}
|
||||||
|
|
||||||
# ══════════════════════════════════════════════════════════════════════
|
# ══════════════════════════════════════════════════════════════════════
|
||||||
# НАСТРОЙКА VPS
|
# НАСТРОЙКА VPS (Менеджер профилей)
|
||||||
# ══════════════════════════════════════════════════════════════════════
|
# ══════════════════════════════════════════════════════════════════════
|
||||||
do_setup() {
|
do_setup() {
|
||||||
|
while true; do
|
||||||
clear_screen
|
clear_screen
|
||||||
draw_box "Настройка подключения к VPS"
|
draw_box "Управление VPS серверами"
|
||||||
printf "\n"
|
printf "\n"
|
||||||
|
|
||||||
# Показать текущие настройки, если есть
|
local vps_list=""
|
||||||
if check_conf; then
|
local idx=0
|
||||||
printf " ${DIM}Текущие настройки:${NC}\n"
|
for f in "$VPS_DIR"/*.conf; do
|
||||||
printf " Хост: ${BOLD}$VPS_HOST${NC} Порт: ${BOLD}$VPS_PORT${NC} Пользователь: ${BOLD}$VPS_USER${NC} Авторизация: ${BOLD}$VPS_AUTH${NC}\n"
|
[ -f "$f" ] || continue
|
||||||
draw_separator
|
idx=$((idx + 1))
|
||||||
printf "\n"
|
VPS_HOST="" # Сброс перед загрузкой
|
||||||
|
. "$f"
|
||||||
|
printf " ${BOLD}%d)${NC} %s (${DIM}%s@%s:%s${NC})\n" "$idx" "$(basename "$f" .conf)" "$VPS_USER" "$VPS_HOST" "$VPS_PORT"
|
||||||
|
vps_list="$vps_list $(basename "$f" .conf)"
|
||||||
|
done
|
||||||
|
|
||||||
|
if [ "$idx" -eq 0 ]; then
|
||||||
|
printf " ${YELLOW}Нет настроенных VPS серверов.${NC}\n"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
prompt "IP-адрес VPS: "
|
draw_separator
|
||||||
local vps_host="$REPLY"
|
printf " ${BOLD}n)${NC} ➕ Добавить новый VPS\n"
|
||||||
[ -z "$vps_host" ] && { warn "IP-адрес обязателен"; pause; return; }
|
[ "$idx" -gt 0 ] && printf " ${BOLD}d)${NC} ❌ Удалить VPS\n"
|
||||||
|
printf " ${BOLD}0)${NC} Назад\n"
|
||||||
|
|
||||||
prompt "SSH порт [22]: "
|
prompt "Выберите действие: "
|
||||||
local vps_port="${REPLY:-22}"
|
case "$REPLY" in
|
||||||
|
0) return ;;
|
||||||
|
n|N) do_add_vps ;;
|
||||||
|
d|D) [ "$idx" -gt 0 ] && do_delete_vps_interactive "$vps_list" ;;
|
||||||
|
[1-9]*)
|
||||||
|
local sel_vps=$(echo "$vps_list" | cut -d' ' -f"$REPLY")
|
||||||
|
[ -n "$sel_vps" ] && do_add_vps "$sel_vps"
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
prompt "SSH пользователь [root]: "
|
do_delete_vps_interactive() {
|
||||||
local vps_user="${REPLY:-root}"
|
local list="$1"
|
||||||
|
prompt "Введите номер VPS для удаления: "
|
||||||
|
local sel_vps=$(echo "$list" | cut -d' ' -f"$REPLY")
|
||||||
|
[ -z "$sel_vps" ] && { warn "Неверный выбор"; pause; return; }
|
||||||
|
|
||||||
local ssh_exec="/opt/bin/ssh"
|
prompt "Удалить профиль VPS '$sel_vps'? (д/н) [н]: "
|
||||||
[ ! -f "$ssh_exec" ] && ssh_exec="ssh"
|
case "$REPLY" in
|
||||||
|
д|Д|y|Y) rm -f "$VPS_DIR/$sel_vps.conf"; msg "Удалено" ;;
|
||||||
|
*) msg "Отменено" ;;
|
||||||
|
esac
|
||||||
|
pause
|
||||||
|
}
|
||||||
|
|
||||||
|
do_add_vps() {
|
||||||
|
local vps_id="${1:-}"
|
||||||
|
local is_new=0
|
||||||
|
[ -z "$vps_id" ] && is_new=1
|
||||||
|
|
||||||
|
if [ "$is_new" -eq 1 ]; then
|
||||||
|
prompt "Название сервера (например, amsterdam): "
|
||||||
|
vps_id=$(echo "$REPLY" | tr -dc 'a-zA-Z0-9_-')
|
||||||
|
[ -z "$vps_id" ] && { warn "Недопустимое название"; pause; return; }
|
||||||
|
fi
|
||||||
|
|
||||||
|
local vps_file="$VPS_DIR/$vps_id.conf"
|
||||||
|
local v_host="" v_port="22" v_user="root" v_auth="key" v_pass=""
|
||||||
|
|
||||||
|
if [ -f "$vps_file" ]; then
|
||||||
|
. "$vps_file"
|
||||||
|
v_host="$VPS_HOST"; v_port="$VPS_PORT"; v_user="$VPS_USER"; v_auth="$VPS_AUTH"; v_pass="$VPS_PASS"
|
||||||
|
fi
|
||||||
|
|
||||||
|
header "Настройка VPS: $vps_id"
|
||||||
|
prompt "IP-адрес VPS [$v_host]: "
|
||||||
|
v_host="${REPLY:-$v_host}"
|
||||||
|
[ -z "$v_host" ] && { warn "IP обязателен"; pause; return; }
|
||||||
|
|
||||||
|
prompt "SSH порт [$v_port]: "
|
||||||
|
v_port="${REPLY:-$v_port}"
|
||||||
|
|
||||||
|
prompt "SSH пользователь [$v_user]: "
|
||||||
|
v_user="${REPLY:-$v_user}"
|
||||||
|
|
||||||
printf "\n Метод авторизации:\n"
|
printf "\n Метод авторизации:\n"
|
||||||
printf " ${BOLD}1)${NC} SSH-ключ (рекомендуется)\n"
|
printf " ${BOLD}1)${NC} SSH-ключ (рекомендуется)\n"
|
||||||
printf " ${BOLD}2)${NC} Пароль\n"
|
printf " ${BOLD}2)${NC} Пароль\n"
|
||||||
prompt "Выберите [1]: "
|
prompt "Выберите [${v_auth/key/1}${v_auth/password/2}]: "
|
||||||
local auth_choice="${REPLY:-1}"
|
local choice="${REPLY:-${v_auth/key/1}${v_auth/password/2}}"
|
||||||
|
|
||||||
local vps_auth="key"
|
if [ "$choice" = "2" ]; then
|
||||||
local vps_pass=""
|
v_auth="password"
|
||||||
|
prompt "SSH пароль: "
|
||||||
if [ "$auth_choice" = "2" ]; then
|
v_pass="$REPLY"
|
||||||
if command -v sshpass >/dev/null 2>&1; then
|
|
||||||
vps_auth="password"
|
|
||||||
printf " SSH пароль: "
|
|
||||||
stty -echo 2>/dev/null
|
|
||||||
read -r vps_pass
|
|
||||||
stty echo 2>/dev/null
|
|
||||||
printf "\n"
|
|
||||||
else
|
else
|
||||||
printf "\n ${YELLOW}⚠ Утилита sshpass не найдена.${NC}\n"
|
v_auth="key"
|
||||||
printf " Для фоновой работы сервисов (туннелей) нужен либо пакет sshpass,\n"
|
# Проверка ключа (код ниже требует наличия SSH_KEY)
|
||||||
printf " либо использование SSH-ключа (рекомендуется).\n\n"
|
ensure_ssh_key
|
||||||
printf " ${CYAN}Решение (Обход):${NC}\n"
|
fi
|
||||||
printf " Используйте вариант ${BOLD}1 (SSH-ключ)${NC}. Скрипт сам создаст ключ,\n"
|
|
||||||
printf " попросит ваш пароль один раз, чтобы скопировать его на VPS,\n"
|
msg "Проверяю подключение к $v_host..."
|
||||||
printf " и дальше всё будет работать автоматически и БЕЗОПАСНО.\n"
|
local ssh_exec="/opt/bin/ssh"
|
||||||
pause
|
[ ! -f "$ssh_exec" ] && ssh_exec="ssh"
|
||||||
return
|
|
||||||
|
if [ "$v_auth" = "password" ]; then
|
||||||
|
if ! command -v sshpass >/dev/null 2>&1; then
|
||||||
|
err "Утилита sshpass не найдена."
|
||||||
|
pause; return
|
||||||
|
fi
|
||||||
|
if ! sshpass -p "$v_pass" $ssh_exec -o StrictHostKeyChecking=no -o ConnectTimeout=10 -p "$v_port" "$v_user@$v_host" "echo ok" >/dev/null 2>&1; then
|
||||||
|
err "Ошибка подключения."
|
||||||
|
pause; return
|
||||||
fi
|
fi
|
||||||
else
|
else
|
||||||
if [ ! -f "$SSH_KEY" ]; then
|
# Копирование ключа
|
||||||
msg "Генерирую SSH-ключ (ed25519)..."
|
local copy_id="/opt/bin/ssh-copy-id"
|
||||||
mkdir -p "$CONF_DIR"
|
[ ! -f "$copy_id" ] && copy_id="ssh-copy-id"
|
||||||
|
|
||||||
# Удаляем старые RSA ключи, если они есть (избегаем путаницы)
|
|
||||||
rm -f "$CONF_DIR/id_rsa" "$CONF_DIR/id_rsa.pub"
|
|
||||||
|
|
||||||
local keygen_cmd="/opt/bin/ssh-keygen"
|
|
||||||
[ ! -f "$keygen_cmd" ] && keygen_cmd="ssh-keygen"
|
|
||||||
|
|
||||||
# Создаем современный и компактный ed25519 ключ
|
|
||||||
# Он лучше всего совместим между OpenSSH и Dropbear
|
|
||||||
if ! $keygen_cmd -t ed25519 -f "$SSH_KEY" -N "" -q 2>/dev/null; then
|
|
||||||
# Танцы с бубном для старых версий
|
|
||||||
$keygen_cmd -t ed25519 -f "$SSH_KEY" -N ""
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Извлекаем публичный ключ, если он не создался
|
|
||||||
if [ ! -f "$SSH_KEY.pub" ] && [ -f "$SSH_KEY" ]; then
|
|
||||||
$keygen_cmd -y -f "$SSH_KEY" 2>/dev/null | grep "^ssh-ed25519" > "$SSH_KEY.pub"
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ -f "$SSH_KEY" ]; then
|
|
||||||
chmod 600 "$SSH_KEY"
|
|
||||||
msg "Ключ создан: $SSH_KEY"
|
|
||||||
else
|
|
||||||
err "Не удалось создать SSH-ключ"
|
|
||||||
pause
|
|
||||||
return
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Проверка подключения
|
|
||||||
printf "\n"
|
|
||||||
msg "Проверяю подключение к $vps_host..."
|
|
||||||
if [ "$vps_auth" = "password" ]; then
|
|
||||||
if ! sshpass -p "$vps_pass" $ssh_exec -o StrictHostKeyChecking=no -o ConnectTimeout=10 \
|
|
||||||
-p "$vps_port" "$vps_user@$vps_host" "echo ok" >/dev/null 2>&1; then
|
|
||||||
err "Не удалось подключиться к VPS. Проверьте параметры."
|
|
||||||
pause
|
|
||||||
return
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
msg "Копирую SSH-ключ на VPS..."
|
|
||||||
if [ ! -f "$SSH_KEY.pub" ]; then
|
|
||||||
err "Публичный ключ не найден: $SSH_KEY.pub"
|
|
||||||
pause
|
|
||||||
return
|
|
||||||
fi
|
|
||||||
|
|
||||||
local copy_id_exec="/opt/bin/ssh-copy-id"
|
|
||||||
[ ! -f "$copy_id_exec" ] && copy_id_exec="ssh-copy-id"
|
|
||||||
|
|
||||||
printf " Введите пароль VPS для копирования ключа:\n"
|
printf " Введите пароль VPS для копирования ключа:\n"
|
||||||
$copy_id_exec -i "$SSH_KEY.pub" -p "$vps_port" "$vps_user@$vps_host" 2>/dev/null || {
|
$copy_id -i "$SSH_KEY.pub" -p "$v_port" "$v_user@$v_host" 2>/dev/null || {
|
||||||
cat "$SSH_KEY.pub" | $ssh_exec -o StrictHostKeyChecking=no -p "$vps_port" "$vps_user@$vps_host" \
|
cat "$SSH_KEY.pub" | $ssh_exec -o StrictHostKeyChecking=no -p "$v_port" "$v_user@$v_host" \
|
||||||
"mkdir -p ~/.ssh && cat >> ~/.ssh/authorized_keys && chmod 700 ~/.ssh && chmod 600 ~/.ssh/authorized_keys"
|
"mkdir -p ~/.ssh && cat >> ~/.ssh/authorized_keys && chmod 700 ~/.ssh && chmod 600 ~/.ssh/authorized_keys"
|
||||||
}
|
}
|
||||||
|
if ! $ssh_exec -o StrictHostKeyChecking=no -o ConnectTimeout=10 -i "$SSH_KEY" -p "$v_port" "$v_user@$v_host" "echo ok" >/dev/null 2>&1; then
|
||||||
if ! $ssh_exec -o StrictHostKeyChecking=no -o ConnectTimeout=10 \
|
err "Ошибка подключения по ключу."
|
||||||
-i "$SSH_KEY" -p "$vps_port" "$vps_user@$vps_host" "echo ok" >/dev/null 2>&1; then
|
pause; return
|
||||||
err "Не удалось подключиться к VPS по ключу."
|
|
||||||
pause
|
|
||||||
return
|
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
msg "Подключение успешно!"
|
|
||||||
|
|
||||||
# Настройка nginx на VPS
|
# Сохраняем
|
||||||
msg "Настраиваю nginx на VPS..."
|
cat > "$vps_file" <<EOF
|
||||||
local ssh_setup_cmd
|
VPS_HOST="$v_host"
|
||||||
if [ "$vps_auth" = "password" ]; then
|
VPS_PORT="$v_port"
|
||||||
ssh_setup_cmd="sshpass -p \"$vps_pass\" ssh -o StrictHostKeyChecking=no -p $vps_port $vps_user@$vps_host"
|
VPS_USER="$v_user"
|
||||||
else
|
VPS_AUTH="$v_auth"
|
||||||
ssh_setup_cmd="ssh -o StrictHostKeyChecking=no -i $SSH_KEY -p $vps_port $vps_user@$vps_host"
|
VPS_PASS="$v_pass"
|
||||||
fi
|
EOF
|
||||||
|
chmod 600 "$vps_file"
|
||||||
|
msg "Профиль '$vps_id' сохранён."
|
||||||
|
|
||||||
eval $ssh_setup_cmd "'
|
# Настройка Nginx на новом VPS
|
||||||
|
msg "Настройка окружения на VPS..."
|
||||||
|
VPS_HOST="$v_host" VPS_PORT="$v_port" VPS_USER="$v_user" VPS_AUTH="$v_auth" VPS_PASS="$v_pass"
|
||||||
|
ssh_cmd "
|
||||||
if ! command -v nginx >/dev/null 2>&1; then
|
if ! command -v nginx >/dev/null 2>&1; then
|
||||||
echo \"Устанавливаю nginx...\"
|
apt-get update -qq && apt-get install -y -qq nginx || yum install -y nginx
|
||||||
apt-get update -qq && apt-get install -y -qq nginx >/dev/null 2>&1 || \
|
|
||||||
yum install -y nginx >/dev/null 2>&1 || {
|
|
||||||
echo \"FAIL: не удалось установить nginx\"
|
|
||||||
exit 1
|
|
||||||
}
|
|
||||||
fi
|
fi
|
||||||
mkdir -p /etc/nginx/sites-enabled
|
mkdir -p /etc/nginx/sites-enabled
|
||||||
if ! grep -q \"include.*sites-enabled\" /etc/nginx/nginx.conf 2>/dev/null; then
|
grep -q 'sites-enabled' /etc/nginx/nginx.conf || sed -i '/http {/a\ include /etc/nginx/sites-enabled/*.conf;' /etc/nginx/nginx.conf
|
||||||
sed -i \"/http {/a\\\\ include /etc/nginx/sites-enabled/*.conf;\" /etc/nginx/nginx.conf 2>/dev/null
|
command -v certbot >/dev/null 2>&1 || (apt-get update -qq && apt-get install -y -qq certbot python3-certbot-nginx || yum install -y certbot python3-certbot-nginx)
|
||||||
fi
|
systemctl enable nginx && systemctl start nginx
|
||||||
|
"
|
||||||
if ! command -v certbot >/dev/null 2>&1; then
|
|
||||||
echo \"Устанавливаю Certbot...\"
|
|
||||||
apt-get update -qq && apt-get install -y -qq certbot python3-certbot-nginx >/dev/null 2>&1 || \
|
|
||||||
yum install -y certbot python3-certbot-nginx >/dev/null 2>&1
|
|
||||||
fi
|
|
||||||
|
|
||||||
systemctl enable nginx 2>/dev/null
|
|
||||||
systemctl start nginx 2>/dev/null
|
|
||||||
echo OK
|
|
||||||
'" || {
|
|
||||||
warn "Не удалось автоматически настроить nginx. Убедитесь, что nginx установлен на VPS."
|
|
||||||
}
|
|
||||||
|
|
||||||
# Сохранение конфига
|
|
||||||
mkdir -p "$CONF_DIR" "$SERVICES_DIR" "$PID_DIR"
|
|
||||||
cat > "$CONF_FILE" <<EOF
|
|
||||||
# rProxy — настройки VPS
|
|
||||||
VPS_HOST="$vps_host"
|
|
||||||
VPS_PORT="$vps_port"
|
|
||||||
VPS_USER="$vps_user"
|
|
||||||
VPS_AUTH="$vps_auth"
|
|
||||||
VPS_PASS="$vps_pass"
|
|
||||||
CERTBOT_EMAIL="$CERTBOT_EMAIL"
|
|
||||||
EOF
|
|
||||||
chmod 600 "$CONF_FILE"
|
|
||||||
|
|
||||||
msg "Конфигурация сохранена!"
|
|
||||||
printf "\n ${GREEN}${BOLD}VPS настроен и готов к работе.${NC}\n"
|
|
||||||
pause
|
pause
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ensure_ssh_key() {
|
||||||
|
if [ ! -f "$SSH_KEY" ]; then
|
||||||
|
msg "Генерирую SSH-ключ (ed25519)..."
|
||||||
|
local keygen="/opt/bin/ssh-keygen"
|
||||||
|
[ ! -f "$keygen" ] && keygen="ssh-keygen"
|
||||||
|
$keygen -t ed25519 -f "$SSH_KEY" -N "" -q
|
||||||
|
[ ! -f "$SSH_KEY.pub" ] && $keygen -y -f "$SSH_KEY" > "$SSH_KEY.pub"
|
||||||
|
chmod 600 "$SSH_KEY"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
# ══════════════════════════════════════════════════════════════════════
|
# ══════════════════════════════════════════════════════════════════════
|
||||||
# ТОЧКА ВХОДА
|
# ТОЧКА ВХОДА
|
||||||
# ══════════════════════════════════════════════════════════════════════
|
# ══════════════════════════════════════════════════════════════════════
|
||||||
mkdir -p "$CONF_DIR" "$SERVICES_DIR" "$PID_DIR" 2>/dev/null
|
migrate_config 2>/dev/null
|
||||||
|
|
||||||
# Поддержка прямых команд для init-скрипта и автоматизации
|
# Поддержка прямых команд для init-скрипта и автоматизации
|
||||||
case "${1:-}" in
|
case "${1:-}" in
|
||||||
|
|
@ -996,12 +1039,15 @@ case "${1:-}" in
|
||||||
check_conf || { err "VPS не настроен"; exit 1; }
|
check_conf || { err "VPS не настроен"; exit 1; }
|
||||||
for f in "$SERVICES_DIR"/*.conf; do
|
for f in "$SERVICES_DIR"/*.conf; do
|
||||||
[ -f "$f" ] || continue
|
[ -f "$f" ] || continue
|
||||||
. "$f"
|
local name=$(basename "$f" .conf)
|
||||||
|
(
|
||||||
|
load_service "$name" >/dev/null 2>&1
|
||||||
local state="остановлен"
|
local state="остановлен"
|
||||||
is_running "$SVC_NAME" && state="работает"
|
is_running "$SVC_NAME" && state="работает"
|
||||||
local info="$SVC_NAME $SVC_TARGET_HOST:$SVC_TARGET_PORT → :$SVC_EXT_PORT"
|
local info="$SVC_NAME $SVC_TARGET_HOST:$SVC_TARGET_PORT → VPS($CUR_VPS_ID):$SVC_TUNNEL_PORT"
|
||||||
[ -n "$SVC_DOMAIN" ] && info="$info ($SVC_DOMAIN)"
|
[ -n "$SVC_DOMAIN" ] && info="$info ($SVC_DOMAIN)"
|
||||||
echo "$info [$state]"
|
echo "$info [$state]"
|
||||||
|
)
|
||||||
done
|
done
|
||||||
;;
|
;;
|
||||||
-v|--version) echo "rProxy v$VERSION" ;;
|
-v|--version) echo "rProxy v$VERSION" ;;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue