#!/bin/bash
# ═══════════════════════════════════════════════════════════
#  VPN Server Quick Deploy — Hysteria 2
#  Автоматически настраивает Hysteria 2 и выдаёт готовую ссылку
#
#  Использование:
#    bash deploy-vpn.sh                              # на сервере
#    ssh root@IP 'bash -s' < deploy-vpn.sh           # удалённо
#    ssh user@IP 'sudo bash -s' < deploy-vpn.sh      # через sudo
#
#  Опции:
#    --name NAME      Имя клиента в ссылке (по умолчанию: client1)
#    --port PORT      UDP порт для VPN (по умолчанию: случайный)
#    --pass PASSWORD  Пароль авторизации (по умолчанию: случайный)
#    --obfs PASS      Включить анти-ТСПУ обфускацию Salamander
# ═══════════════════════════════════════════════════════════
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'

# ── Параметры командной строки ──
CLIENT_NAME="client1"
CUSTOM_PORT=""
CUSTOM_PASS=""
OBFS_PASS=""

while [[ $# -gt 0 ]]; do
    case $1 in
        --name) CLIENT_NAME="$2"; shift 2 ;;
        --port) CUSTOM_PORT="$2"; shift 2 ;;
        --pass) CUSTOM_PASS="$2"; shift 2 ;;
        --obfs) OBFS_PASS="$2"; shift 2 ;;
        *) echo "Неизвестный параметр: $1"; exit 1 ;;
    esac
done

# ── Проверки ──
if [[ $EUID -ne 0 ]]; then
    echo -e "${RED}Запустите от root: sudo bash deploy-vpn.sh${NC}"
    exit 1
fi

# ── Генерация случайных значений ──
rand_port() { shuf -i 10000-59999 -n 1; }
rand_hex() { openssl rand -hex "$1"; }

# URL-encode for hysteria2:// userinfo and query (RFC 3986)
urlencode() {
    # Prefer python3 (usually present after apt openssl/curl); fallback: leave as-is for hex passwords
    if command -v python3 &>/dev/null; then
        python3 -c 'import urllib.parse,sys; print(urllib.parse.quote(sys.argv[1], safe=""))' "$1"
    else
        printf '%s' "$1"
    fi
}

VPN_PORT=${CUSTOM_PORT:-$(rand_port)}
PASSWORD=${CUSTOM_PASS:-$(rand_hex 12)}

# ── Определение прямого публичного IP-адреса сервера ──
SERVER_IP=$(ip -4 route get 1.1.1.1 2>/dev/null | awk '{print $7}' || true)
# Private / loopback → fall back to external look-up
if [[ -z "$SERVER_IP" \
   || "$SERVER_IP" =~ ^127\. \
   || "$SERVER_IP" =~ ^10\. \
   || "$SERVER_IP" =~ ^192\.168\. \
   || "$SERVER_IP" =~ ^172\.(1[6-9]|2[0-9]|3[0-1])\. ]]; then
    SERVER_IP=$(curl -s4 --max-time 5 ifconfig.me 2>/dev/null \
        || curl -s4 --max-time 5 ip.sb 2>/dev/null \
        || curl -s4 --max-time 5 ipinfo.io/ip 2>/dev/null \
        || echo "UNKNOWN")
fi

if [[ "$SERVER_IP" == "UNKNOWN" || -z "$SERVER_IP" ]]; then
    echo -e "${RED}Не удалось определить внешний IP${NC}"
    exit 1
fi

echo -e "${CYAN}╔═══════════════════════════════════════════╗${NC}"
echo -e "${CYAN}║     VPN Quick Deploy — Hysteria 2         ║${NC}"
echo -e "${CYAN}╠═══════════════════════════════════════════╣${NC}"
echo -e "${CYAN}║  Сервер IP:   ${GREEN}${SERVER_IP}${NC}"
echo -e "${CYAN}║  Имя клиента: ${GREEN}${CLIENT_NAME}${NC}"
echo -e "${CYAN}║  Порт UDP:    ${GREEN}${VPN_PORT}${NC}"
echo -e "${CYAN}╚═══════════════════════════════════════════╝${NC}"

# ═══════════════════════════════════════════
# Шаг 1: Система + BBR + Оптимизация UDP
# ═══════════════════════════════════════════
echo -e "\n${GREEN}[1/5]${NC} Настройка системы..."

export DEBIAN_FRONTEND=noninteractive
apt-get update -qq > /dev/null 2>&1 || true
apt-get install -y -qq curl wget openssl ca-certificates python3 > /dev/null 2>&1 || true

# BBR & UDP Buffers (критично для Hysteria / Brutal QUIC)
if ! sysctl net.ipv4.tcp_congestion_control 2>/dev/null | grep -q bbr; then
    cat >> /etc/sysctl.conf << 'SYSCTL'
# VPN Optimization for QUIC & TCP
net.core.default_qdisc = fq
net.ipv4.tcp_congestion_control = bbr
net.ipv4.tcp_fastopen = 3
net.core.rmem_max = 16777216
net.core.wmem_max = 16777216
net.core.rmem_default = 262144
net.core.wmem_default = 262144
SYSCTL
    sysctl -p > /dev/null 2>&1 || true
    echo -e "  BBR и UDP-буферы ${GREEN}включены${NC}"
else
    echo -e "  BBR ${GREEN}уже активен${NC}, буферы UDP оптимизированы"
fi

# ═══════════════════════════════════════════
# Шаг 2: Открытие портов
# ═══════════════════════════════════════════
echo -e "\n${GREEN}[2/5]${NC} Открытие UDP порта ${BOLD}${VPN_PORT}${NC}..."

open_ports() {
    local port="$1"
    local proto="$2"
    local opened=false

    # --- UFW ---
    if command -v ufw &>/dev/null; then
        if ! ufw status 2>/dev/null | grep -q "active"; then
            ufw --force enable > /dev/null 2>&1 || true
            ufw default allow outgoing > /dev/null 2>&1
            ufw default deny incoming > /dev/null 2>&1
            ufw allow ssh > /dev/null 2>&1
        fi
        ufw allow "$port"/"$proto" > /dev/null 2>&1
        ufw reload > /dev/null 2>&1 || true
        echo -e "  ufw: порт $port/$proto ${GREEN}открыт${NC}"
        opened=true
    fi

    # --- firewalld ---
    if command -v firewall-cmd &>/dev/null && systemctl is-active --quiet firewalld 2>/dev/null; then
        firewall-cmd --permanent --add-port="$port"/"$proto" > /dev/null 2>&1
        firewall-cmd --reload > /dev/null 2>&1
        echo -e "  firewalld: порт $port/$proto ${GREEN}открыт${NC}"
        opened=true
    fi

    # --- iptables (fallback) ---
    if command -v iptables &>/dev/null; then
        if ! iptables -C INPUT -p "$proto" --dport "$port" -j ACCEPT 2>/dev/null; then
            iptables -I INPUT -p "$proto" --dport "$port" -j ACCEPT 2>/dev/null || true
        fi
        if command -v netfilter-persistent &>/dev/null; then
            netfilter-persistent save > /dev/null 2>&1 || true
        elif command -v iptables-save &>/dev/null; then
            iptables-save > /etc/iptables.rules 2>/dev/null || true
        fi
        if [[ "$opened" == false ]]; then
            echo -e "  iptables: порт $port/$proto ${GREEN}открыт${NC}"
        fi
    fi
}

open_ports "$VPN_PORT" "udp"

# ═══════════════════════════════════════════
# Шаг 3: Сертификат SSL
# ═══════════════════════════════════════════
echo -e "\n${GREEN}[3/5]${NC} Настройка SSL-сертификатов..."

mkdir -p /etc/hysteria
CERT_PATH="/etc/hysteria/server.crt"
KEY_PATH="/etc/hysteria/server.key"

echo -e "  Генерация SSL сертификата (маскировка под www.bing.com)..."
openssl req -x509 -nodes -newkey rsa:2048 \
    -keyout "$KEY_PATH" \
    -out "$CERT_PATH" \
    -subj "/CN=www.bing.com" \
    -days 3650 >/dev/null 2>&1
echo -e "  SSL сертификат ${GREEN}создан${NC}"

# ═══════════════════════════════════════════
# Шаг 4: Установка и настройка Hysteria 2
# ═══════════════════════════════════════════
echo -e "\n${GREEN}[4/5]${NC} Установка Hysteria 2..."

if command -v hysteria &>/dev/null; then
    echo -e "  Hysteria 2 ${GREEN}уже установлена${NC}"
else
    echo -e "  Запуск официального установщика Hysteria..."
    curl -fsSL https://get.hy2.sh/ | bash
fi

# Запись конфига /etc/hysteria/config.yaml
if [[ -n "$OBFS_PASS" ]]; then
cat > /etc/hysteria/config.yaml << EOF
listen: :${VPN_PORT}

tls:
  cert: ${CERT_PATH}
  key: ${KEY_PATH}

auth:
  type: password
  password: ${PASSWORD}

obfs:
  type: salamander
  salamander:
    password: ${OBFS_PASS}

masquerade:
  type: proxy
  proxy:
    url: https://www.bing.com
    rewriteHost: true
EOF
else
cat > /etc/hysteria/config.yaml << EOF
listen: :${VPN_PORT}

tls:
  cert: ${CERT_PATH}
  key: ${KEY_PATH}

auth:
  type: password
  password: ${PASSWORD}

masquerade:
  type: proxy
  proxy:
    url: https://www.bing.com
    rewriteHost: true
EOF
fi

echo -e "  Конфигурация '/etc/hysteria/config.yaml' ${GREEN}записана${NC}"

# Права доступа
if id "hysteria" &>/dev/null; then
    chown -R hysteria:hysteria /etc/hysteria
    chmod 750 /etc/hysteria
    chmod 640 "$KEY_PATH" || true
    chmod 644 "$CERT_PATH" || true
    chmod 644 /etc/hysteria/config.yaml || true
fi

# Запуск службы
systemctl daemon-reload
systemctl enable --now hysteria-server >/dev/null 2>&1 || true
systemctl restart hysteria-server

sleep 2

if systemctl is-active --quiet hysteria-server; then
    echo -e "  Служба hysteria-server ${GREEN}успешно запущена${NC}"
else
    echo -e "  ${RED}Ошибка запуска службы!${NC} Логи:"
    journalctl -u hysteria-server -n 20 --no-pager
    exit 1
fi

# ═══════════════════════════════════════════
# Шаг 5: Формирование рабочей ссылки
# ═══════════════════════════════════════════
echo -e "\n${GREEN}[5/5]${NC} Формирование ссылки..."

PASS_ENC=$(urlencode "$PASSWORD")
NAME_ENC=$(urlencode "Hysteria2-${CLIENT_NAME}")

if [[ -n "$OBFS_PASS" ]]; then
    OBFS_ENC=$(urlencode "$OBFS_PASS")
    HY2_LINK="hysteria2://${PASS_ENC}@${SERVER_IP}:${VPN_PORT}/?insecure=1&sni=www.bing.com&alpn=h3&obfs=salamander&obfs-password=${OBFS_ENC}#${NAME_ENC}"
else
    HY2_LINK="hysteria2://${PASS_ENC}@${SERVER_IP}:${VPN_PORT}/?insecure=1&sni=www.bing.com&alpn=h3#${NAME_ENC}"
fi

echo ""
echo -e "${CYAN}═══════════════════════════════════════════${NC}"
echo -e "${CYAN}  ${BOLD}ДАННЫЕ ПОДКЛЮЧЕНИЯ HYSTERIA 2${NC}"
echo -e "${CYAN}═══════════════════════════════════════════${NC}"
echo -e "  Сервер (IP): ${GREEN}${SERVER_IP}${NC}"
echo -e "  Порт:        ${GREEN}${VPN_PORT} (UDP)${NC}"
echo -e "  Пароль:      ${GREEN}${PASSWORD}${NC}"
if [[ -n "$OBFS_PASS" ]]; then
echo -e "  Обфускация:  ${GREEN}salamander${NC} (пароль: ${GREEN}${OBFS_PASS}${NC})"
fi
echo -e "  SSL:         ${YELLOW}Самоподписанный (insecure=1)${NC}"

echo ""
echo -e "${CYAN}═══════════════════════════════════════════${NC}"
echo -e "${CYAN}  ${BOLD}ССЫЛКА ДЛЯ VPN-КЛИЕНТА${NC}"
echo -e "${CYAN}═══════════════════════════════════════════${NC}"
echo -e "  Скопируйте и импортируйте в клиент:\n"
echo -e "  ${GREEN}${HY2_LINK}${NC}"

echo ""
echo -e "${CYAN}═══════════════════════════════════════════${NC}"
echo -e "${CYAN}  ${BOLD}КАК ПОДКЛЮЧИТЬСЯ${NC}"
echo -e "${CYAN}═══════════════════════════════════════════${NC}"
echo -e "  ${BOLD}iPhone/iPad/Mac/Android/Windows:${NC}"
echo -e "  Используйте ${BOLD}Hiddify${NC} или ${BOLD}NekoBox${NC}."
echo -e "  1. Скопируйте ссылку выше."
echo -e "  2. В приложении нажмите ${BOLD}'+ Добавить конфигурацию'${NC} -> ${BOLD}'Импортировать из буфера обмена'${NC}."
echo -e "  3. Подключайтесь!"

# Сохранение в файл
CREDS_FILE="/root/hysteria-credentials.txt"
cat > "$CREDS_FILE" << CREDEOF
Hysteria 2 Server Credentials
Created:   $(date '+%Y-%m-%d %H:%M')
Server IP: ${SERVER_IP}

UDP Port:  ${VPN_PORT}
Password:  ${PASSWORD}
$([ -n "$OBFS_PASS" ] && echo "Obfs Type: salamander" && echo "Obfs Pass: $OBFS_PASS")

Client Link:
${HY2_LINK}
CREDEOF
chmod 600 "$CREDS_FILE"

echo ""
echo -e "${GREEN}Данные подключения сохранены в: ${CREDS_FILE}${NC}\n"
