Перейти к содержимому
arckep.ru — все нейросети в одном месте без VPN Перейти
>AISTUDY_
Поддержать
AUTHORСвежий выпуск №028 → Контроль агентов без Approve: YOLO, пороги, irreversible

VPN и оплата AI-подписок

Назначение этой страницы

Это не материал по обходу блокировок. Данная страница — техническая документация в составе бесплатного образовательного курса «AI-агенты: от основ к практике». Её цель — обеспечить доступ к образовательным и практическим ресурсам: Claude API, OpenAI API, Cursor, GitHub Copilot и другим профессиональным инструментам, которые ограничивают доступ по геолокации.

Настройка собственного VPN-сервера — стандартная практика системного администрирования, описанная в документации Ubuntu, Red Hat, DigitalOcean и других платформ. Страница не является рекламой VPN-сервисов и не предоставляет услуги VPN третьим лицам.

Ст. 15.8 ФЗ-149: ограничения распространяются на операторов VPN-сервисов и владельцев анонимайзеров. Использование VPN для личных и профессиональных целей не является правонарушением.

Эта страница — часть курса по работе с AI-инструментами. Многие профессиональные сервисы (Claude API, OpenAI, Cursor) ограничивают доступ по геолокации. Собственный VPN-сервер — стандартная практика для разработчиков и специалистов по всему миру.

Всё, что нужно для доступа к рабочим AI-сервисам: свой VPN за 5 минут, оплата без иностранной карты, регистрация с виртуальным номером.

Что понадобится

  • VPS-сервер за пределами РФ — от 100 руб/мес (если никогда не работали с серверами — наш гайд «VDS для начинающих» поможет разобраться за 10 минут)
  • 5 минут времени
  • Базовые навыки — скопировать команду в терминал
VPS

Где арендовать сервер?

Рекомендуем FirstVDS — серверы в Нидерландах и Казахстане, оплата в рублях, от 100 руб/мес. Выбирайте Ubuntu 22.04/24.04, минимум 1 ГБ RAM.

FirstVDS →
ПРОМОКОД: 6481165030 -25%

Способ 1: Автоматический скрипт

Одна команда — и через 3 минуты VPN работает. Скрипт установит Hysteria 2, настроит UDP/QUIC-сервер, откроет порт в файрволе и выдаст готовую ссылку hysteria2://… для вставки в клиент.

Шаг 1. Скачайте и запустите

Подключитесь к серверу по SSH. Рекомендуем сначала скачать и просмотреть скрипт, а потом запустить:

рекомендуемый способ
# 1. Скачать скрипт
curl -sL https://ai.arckep.ru/deploy-vpn.sh -o deploy-vpn.sh

# 2. Просмотреть (убедиться что всё безопасно)
cat deploy-vpn.sh

# 3. Запустить
sudo bash deploy-vpn.sh

С указанием имени клиента:

bash
sudo bash deploy-vpn.sh --name "Моё имя"
Посмотреть содержимое скрипта deploy-vpn.sh
deploy-vpn.sh — 327 строк
#!/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"

Шаг 2. Сохраните данные

После установки скрипт покажет в терминале:

  • IP, UDP-порт, пароль — параметры сервера
  • Ссылку hysteria2://… — для вставки в VPN-приложение

Сохраните эту информацию. Данные также записываются в файл /root/hysteria-credentials.txt на сервере.

Шаг 3. Подключитесь

Телефон / GUI: скопируйте ссылку hysteria2://… и импортируйте в Hiddify или NekoBox (см. раздел «Приложения» ниже).

Linux / сервер / уже стоит Xray: отдельный скрипт ставит клиентский конфиг. Если Xray уже установлен — не переустанавливает ничего, только добавляет outbound (новый профиль) и печатает JSON + ссылку в терминал.

клиент: конфиг Hysteria / Xray
# 1. Скачать скрипт клиента
curl -sL https://ai.arckep.ru/install-hysteria-config.sh -o install-hysteria-config.sh

# 2. Вставить ссылку с сервера (из вывода deploy-vpn.sh)
bash install-hysteria-config.sh 'hysteria2://…'

# Одной строкой:
curl -sL https://ai.arckep.ru/install-hysteria-config.sh | bash -s -- 'hysteria2://…'
Посмотреть install-hysteria-config.sh
install-hysteria-config.sh — 514 строк
#!/bin/bash
# ═══════════════════════════════════════════════════════════
#  Hysteria 2 — установка клиентского конфига
#
#  - Пишет native-конфиг Hysteria (config.yaml)
#  - Если уже стоит Xray — добавляет outbound JSON и печатает
#    его в терминал (бинарь Hysteria не трогает)
#  - Всегда печатает ссылку и пути к файлам
#
#  Использование:
#    bash install-hysteria-config.sh 'hysteria2://…'
#    curl -sL https://ai.arckep.ru/install-hysteria-config.sh | bash -s -- 'hysteria2://…'
#
#  Опции:
#    --uri URI         ссылка (то же, что позиционный аргумент)
#    --dir DIR         каталог (по умолчанию: ~/.config/hysteria)
#    --name NAME       имя профиля / tag outbound (из #fragment ссылки)
#    --socks PORT      SOCKS5 (default 1080)
#    --http PORT       HTTP-прокси (default 8080)
#    --no-install      не ставить бинарь Hysteria
#    --force-hysteria  ставить/искать Hysteria даже если есть Xray
#    --start           запустить native-клиент (foreground)
# ═══════════════════════════════════════════════════════════
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'

URI=""
CONFIG_DIR="${HOME}/.config/hysteria"
PROFILE_NAME=""
SOCKS_PORT="1080"
HTTP_PORT="8080"
NO_INSTALL=false
FORCE_HYSTERIA=false
DO_START=false

while [[ $# -gt 0 ]]; do
    case $1 in
        --uri) URI="$2"; shift 2 ;;
        --dir) CONFIG_DIR="$2"; shift 2 ;;
        --name) PROFILE_NAME="$2"; shift 2 ;;
        --socks) SOCKS_PORT="$2"; shift 2 ;;
        --http) HTTP_PORT="$2"; shift 2 ;;
        --no-install) NO_INSTALL=true; shift ;;
        --force-hysteria) FORCE_HYSTERIA=true; shift ;;
        --start) DO_START=true; shift ;;
        -h|--help)
            sed -n '2,24p' "$0" | sed 's/^# \?//'
            exit 0
            ;;
        hysteria2://*|hy2://*)
            URI="$1"; shift
            ;;
        *)
            echo -e "${RED}Неизвестный параметр: $1${NC}"
            echo "Пример: bash install-hysteria-config.sh 'hysteria2://pass@1.2.3.4:443/?insecure=1&sni=www.bing.com'"
            exit 1
            ;;
    esac
done

if [[ -z "$URI" ]]; then
    echo -e "${RED}Нужна ссылка hysteria2://…${NC}"
    echo ""
    echo "  bash install-hysteria-config.sh 'hysteria2://…'"
    echo "  curl -sL https://ai.arckep.ru/install-hysteria-config.sh | bash -s -- 'hysteria2://…'"
    exit 1
fi

case "$URI" in
    hy2://*) URI="hysteria2://${URI#hy2://}" ;;
    hysteria2://*) ;;
    *)
        echo -e "${RED}Ссылка должна начинаться с hysteria2:// или hy2://${NC}"
        exit 1
        ;;
esac

# ── python3 ──
if ! command -v python3 &>/dev/null; then
    if [[ $EUID -eq 0 ]]; then
        export DEBIAN_FRONTEND=noninteractive
        apt-get update -qq >/dev/null 2>&1 || true
        apt-get install -y -qq python3 >/dev/null 2>&1 || true
    fi
fi
if ! command -v python3 &>/dev/null; then
    echo -e "${RED}Нужен python3 для разбора ссылки${NC}"
    exit 1
fi

# ── Разбор URI ──
eval "$(python3 - "$URI" "${PROFILE_NAME}" <<'PY'
import sys, urllib.parse, shlex, re
raw = sys.argv[1]
forced_name = sys.argv[2] if len(sys.argv) > 2 else ""
u = urllib.parse.urlparse(raw)
if u.scheme not in ("hysteria2", "hy2"):
    print("echo -e \"${RED}Неверная схема URI${NC}\"; exit 1"); sys.exit(0)
qs = urllib.parse.parse_qs(u.query)
host = u.hostname or ""
port = u.port or 443
auth = urllib.parse.unquote(u.username or "")
if u.password:
    auth = f"{auth}:{urllib.parse.unquote(u.password)}"
sni = (qs.get("sni") or [""])[0]
insecure = (qs.get("insecure") or ["0"])[0] in ("1", "true", "True")
obfs = (qs.get("obfs") or [""])[0]
obfs_pass = (qs.get("obfs-password") or [""])[0]
pin = (qs.get("pinSHA256") or qs.get("pinsha256") or [""])[0]
name = forced_name or urllib.parse.unquote(u.fragment or "") or "hysteria2"
# safe filename / xray tag
safe = re.sub(r"[^A-Za-z0-9._-]+", "-", name).strip("-") or "hysteria2"
if not host or not auth:
    print("echo -e \"${RED}В ссылке нет хоста или пароля${NC}\"; exit 1"); sys.exit(0)
def exp(k, v):
    print(f"{k}={shlex.quote(str(v))}")
exp("P_HOST", host)
exp("P_PORT", port)
exp("P_AUTH", auth)
exp("P_SNI", sni)
exp("P_INSECURE", "1" if insecure else "0")
exp("P_OBFS", obfs)
exp("P_OBFS_PASS", obfs_pass)
exp("P_PIN", pin)
exp("P_NAME", name)
exp("P_SAFE", safe)
PY
)"

# ── Поиск Xray ──
find_xray() {
    if command -v xray &>/dev/null; then
        command -v xray
        return 0
    fi
    local c
    for c in \
        /usr/local/bin/xray \
        /usr/bin/xray \
        /usr/local/x-ui/bin/xray-linux-amd64 \
        /usr/local/x-ui/bin/xray-linux-arm64
    do
        if [[ -x "$c" ]]; then
            echo "$c"
            return 0
        fi
    done
    # any xray-linux-* under 3x-ui
    local found
    found=$(find /usr/local/x-ui/bin -name 'xray-linux-*' -type f -executable 2>/dev/null | head -1 || true)
    if [[ -n "$found" ]]; then
        echo "$found"
        return 0
    fi
    return 1
}

XRAY_BIN=""
HAS_XRAY=false
if XRAY_BIN=$(find_xray); then
    HAS_XRAY=true
fi

HAS_HYSTERIA=false
if command -v hysteria &>/dev/null; then
    HAS_HYSTERIA=true
fi

echo -e "${CYAN}╔═══════════════════════════════════════════╗${NC}"
echo -e "${CYAN}║  Hysteria 2 — клиентский конфиг           ║${NC}"
echo -e "${CYAN}╠═══════════════════════════════════════════╣${NC}"
echo -e "${CYAN}║  Сервер:  ${GREEN}${P_HOST}:${P_PORT}${NC}"
echo -e "${CYAN}║  Профиль: ${GREEN}${P_NAME}${NC}"
echo -e "${CYAN}║  Каталог: ${GREEN}${CONFIG_DIR}${NC}"
if [[ "$HAS_XRAY" == true ]]; then
echo -e "${CYAN}║  Xray:    ${GREEN}найден${NC} (${XRAY_BIN})"
else
echo -e "${CYAN}║  Xray:    ${YELLOW}не найден${NC}"
fi
if [[ "$HAS_HYSTERIA" == true ]]; then
echo -e "${CYAN}║  Hysteria:${GREEN} найден${NC} ($(command -v hysteria))"
else
echo -e "${CYAN}║  Hysteria:${YELLOW} не найден${NC}"
fi
echo -e "${CYAN}╚═══════════════════════════════════════════╝${NC}"

mkdir -p "$CONFIG_DIR"

# Имена файлов профиля (не затираем чужие — новый файл на каждый профиль)
HY_CFG="${CONFIG_DIR}/config-${P_SAFE}.yaml"
HY_CFG_DEFAULT="${CONFIG_DIR}/config.yaml"
URI_FILE="${CONFIG_DIR}/share-${P_SAFE}.uri"
EXPANDED="${CONFIG_DIR}/config-${P_SAFE}.expanded.yaml"
XRAY_OUT="${CONFIG_DIR}/xray-outbound-${P_SAFE}.json"
XRAY_SNIPPET="${CONFIG_DIR}/xray-outbound-${P_SAFE}.snippet.json"

# ── Native Hysteria config ──
python3 - "$URI" "$P_NAME" "$P_HOST" "$P_PORT" "$SOCKS_PORT" "$HTTP_PORT" "$HY_CFG" <<'PY'
import json, sys, datetime
uri, name, host, port, socks, http, path = sys.argv[1:8]
doc = f"""# Generated by install-hysteria-config.sh — {datetime.datetime.now():%Y-%m-%d %H:%M}
# Profile: {name}
# Server:  {host}:{port}

server: {json.dumps(uri)}

bandwidth:
  up: 50 mbps
  down: 200 mbps

socks5:
  listen: 127.0.0.1:{socks}

http:
  listen: 127.0.0.1:{http}
"""
open(path, "w", encoding="utf-8").write(doc)
PY

# expanded human view
{
    echo "# Expanded view (reference). Active: $(basename "$HY_CFG")"
    echo "server: ${P_HOST}:${P_PORT}"
    echo "auth: ${P_AUTH}"
    echo "tls:"
    [[ -n "$P_SNI" ]] && echo "  sni: ${P_SNI}"
    [[ "$P_INSECURE" == "1" ]] && echo "  insecure: true"
    [[ -n "$P_PIN" ]] && echo "  pinSHA256: ${P_PIN}"
    if [[ -n "$P_OBFS" ]]; then
        echo "obfs:"
        echo "  type: ${P_OBFS}"
        if [[ -n "$P_OBFS_PASS" ]]; then
            echo "  ${P_OBFS}:"
            echo "    password: ${P_OBFS_PASS}"
        fi
    fi
    echo "socks5:"
    echo "  listen: 127.0.0.1:${SOCKS_PORT}"
    echo "http:"
    echo "  listen: 127.0.0.1:${HTTP_PORT}"
} > "$EXPANDED"

printf '%s\n' "$URI" > "$URI_FILE"

# default symlink/copy for plain `hysteria` without -c
cp -f "$HY_CFG" "$HY_CFG_DEFAULT"
chmod 600 "$HY_CFG" "$HY_CFG_DEFAULT" "$EXPANDED" "$URI_FILE" 2>/dev/null || true

# ── Xray outbound (если Xray есть — основной сценарий «уже стоит») ──
if [[ "$HAS_XRAY" == true ]]; then
    python3 - "$P_SAFE" "$P_HOST" "$P_PORT" "$P_AUTH" "$P_SNI" "$P_INSECURE" "$P_OBFS" "$P_OBFS_PASS" "$P_PIN" "$XRAY_OUT" "$XRAY_SNIPPET" <<'PY'
import json, sys
tag, host, port, auth, sni, insecure, obfs, obfs_pass, pin, path_full, path_snip = sys.argv[1:12]
port = int(port)
insecure = insecure in ("1", "true", "True")

hysteria_settings = {
    "version": 2,
    "auth": auth,
    "up": "50mbps",
    "down": "200mbps",
    "udpIdleTimeout": 120,
}
if obfs:
    # Xray salamander field names vary by version; keep both common forms
    hysteria_settings["obfs"] = {
        "type": obfs,
        "password": obfs_pass or "",
        "salamanderPassword": obfs_pass or "",
    }

tls = {
    "serverName": sni or host,
    "allowInsecure": insecure,
    "alpn": ["h3"],
}
if pin:
    tls["pinnedPeerCertSha256"] = pin

outbound = {
    "tag": f"hy2-{tag}",
    "protocol": "hysteria",
    "settings": {
        "version": 2,
        "address": host,
        "port": port,
    },
    "streamSettings": {
        "network": "hysteria",
        "security": "tls",
        "tlsSettings": tls,
        "hysteriaSettings": hysteria_settings,
    },
}

# Full minimal config (standalone run: xray run -c file)
full = {
    "log": {"loglevel": "warning"},
    "inbounds": [
        {
            "tag": "socks-in",
            "listen": "127.0.0.1",
            "port": 1080,
            "protocol": "socks",
            "settings": {"udp": True},
        },
        {
            "tag": "http-in",
            "listen": "127.0.0.1",
            "port": 8080,
            "protocol": "http",
        },
    ],
    "outbounds": [
        outbound,
        {"tag": "direct", "protocol": "freedom"},
        {"tag": "block", "protocol": "blackhole"},
    ],
    "routing": {
        "domainStrategy": "AsIs",
        "rules": [
            {"type": "field", "outboundTag": f"hy2-{tag}", "network": "tcp,udp"}
        ],
    },
}

open(path_full, "w", encoding="utf-8").write(json.dumps(full, ensure_ascii=False, indent=2) + "\n")
open(path_snip, "w", encoding="utf-8").write(json.dumps(outbound, ensure_ascii=False, indent=2) + "\n")
PY
    chmod 600 "$XRAY_OUT" "$XRAY_SNIPPET" 2>/dev/null || true

    # Аккуратно добавить outbound в существующий config.json Xray (writable)
    CANDIDATE_CONFIGS=(
        "${HOME}/.config/xray/config.json"
        "${HOME}/xray/config.json"
        "/usr/local/etc/xray/config.json"
        "/etc/xray/config.json"
        "/usr/local/x-ui/bin/config.json"
    )
    MERGED=""
    for cfg in "${CANDIDATE_CONFIGS[@]}"; do
        [[ -f "$cfg" && -w "$cfg" ]] || continue
        merge_result=$(python3 - "$cfg" "$XRAY_SNIPPET" <<'PY'
import json, sys, shutil, time
cfg_path, snip_path = sys.argv[1], sys.argv[2]
try:
    with open(cfg_path, encoding="utf-8") as f:
        data = json.load(f)
    with open(snip_path, encoding="utf-8") as f:
        outbound = json.load(f)
except Exception as e:
    print(f"skip:{e}")
    sys.exit(0)
outs = data.get("outbounds")
if not isinstance(outs, list):
    print("skip:no-outbounds")
    sys.exit(0)
tag = outbound.get("tag")
if any(isinstance(o, dict) and o.get("tag") == tag for o in outs):
    data["outbounds"] = [
        outbound if (isinstance(o, dict) and o.get("tag") == tag) else o for o in outs
    ]
    action = "replaced"
else:
    insert_at = len(outs)
    for i, o in enumerate(outs):
        if isinstance(o, dict) and o.get("protocol") in ("freedom", "blackhole"):
            insert_at = i
            break
    outs.insert(insert_at, outbound)
    data["outbounds"] = outs
    action = "added"
bak = cfg_path + ".bak." + time.strftime("%Y%m%d%H%M%S")
shutil.copy2(cfg_path, bak)
with open(cfg_path, "w", encoding="utf-8") as f:
    json.dump(data, f, ensure_ascii=False, indent=2)
    f.write("\n")
print(f"ok:{action}:{cfg_path} (backup {bak})")
PY
)
        if [[ "$merge_result" == ok:* ]]; then
            MERGED="$merge_result"
            break
        fi
    done
fi

# ── Бинарь Hysteria: не ставим, если Xray уже есть (если не --force-hysteria) ──
ensure_hysteria() {
    if [[ "$HAS_HYSTERIA" == true ]]; then
        echo -e "  Бинарь hysteria ${GREEN}уже есть${NC}: $(command -v hysteria)"
        return 0
    fi
    if [[ "$NO_INSTALL" == true ]]; then
        echo -e "  ${YELLOW}--no-install: бинарь не ставим${NC}"
        return 0
    fi
    if [[ "$HAS_XRAY" == true && "$FORCE_HYSTERIA" != true ]]; then
        echo -e "  Xray уже стоит — ${GREEN}бинарь Hysteria не ставим${NC}"
        echo -e "  (нужен native Hysteria → перезапустите с ${BOLD}--force-hysteria${NC})"
        return 0
    fi
    echo -e "  Установка Hysteria 2…"
    if [[ $EUID -eq 0 ]]; then
        curl -fsSL https://get.hy2.sh/ | bash
    elif command -v sudo &>/dev/null; then
        curl -fsSL https://get.hy2.sh/ | sudo bash
    else
        echo -e "  ${YELLOW}Нет root/sudo — качаю бинарь в ~/.local/bin${NC}"
        mkdir -p "${HOME}/.local/bin"
        local arch os url
        arch=$(uname -m)
        case "$arch" in
            x86_64|amd64) arch="amd64" ;;
            aarch64|arm64) arch="arm64" ;;
            *)
                echo -e "${RED}Неизвестная архитектура: $arch${NC}"
                return 1
                ;;
        esac
        os=$(uname -s | tr '[:upper:]' '[:lower:]')
        url=$(curl -fsSL "https://api.github.com/repos/apernet/hysteria/releases/latest" \
            | python3 -c "import sys,json,re; j=json.load(sys.stdin); arch=sys.argv[1]; osn=sys.argv[2];
assets=j.get('assets') or [];
pat=re.compile(rf'hysteria-{osn}-{arch}(\.exe)?$', re.I);
cands=[a for a in assets if pat.search(a['name']) and 'avx' not in a['name'].lower() and 'fips' not in a['name'].lower()]
if not cands:
  cands=[a for a in assets if arch in a['name'] and osn in a['name']]
print(cands[0]['browser_download_url'] if cands else '')" "$arch" "$os")
        if [[ -z "$url" ]]; then
            echo -e "${RED}Не удалось найти релиз${NC}"
            return 1
        fi
        curl -fsSL "$url" -o "${HOME}/.local/bin/hysteria"
        chmod +x "${HOME}/.local/bin/hysteria"
        export PATH="${HOME}/.local/bin:${PATH}"
        echo -e "  Установлен в ${GREEN}~/.local/bin/hysteria${NC}"
    fi
    if command -v hysteria &>/dev/null; then
        HAS_HYSTERIA=true
        echo -e "  Бинарь ${GREEN}готов${NC}: $(command -v hysteria)"
    fi
}

echo ""
echo -e "${GREEN}[1/2]${NC} Конфиги…"
echo -e "  Hysteria: ${GREEN}${HY_CFG}${NC}"
if [[ "$HAS_XRAY" == true ]]; then
    echo -e "  Xray full: ${GREEN}${XRAY_OUT}${NC}"
    echo -e "  Xray snip: ${GREEN}${XRAY_SNIPPET}${NC}"
    if [[ -n "${MERGED:-}" ]]; then
        echo -e "  В существующий config.json: ${GREEN}${MERGED#ok:}${NC}"
    else
        echo -e "  ${YELLOW}Живой config.json Xray не трогали${NC} (нет writable / уже ок)"
        echo -e "  Вставьте snippet в outbounds вручную или:"
        echo -e "  ${BOLD}xray run -c ${XRAY_OUT}${NC}"
    fi
fi

echo ""
echo -e "${GREEN}[2/2]${NC} Бинарь…"
ensure_hysteria

# ── Вывод в терминал ──
echo ""
echo -e "${CYAN}═══════════════════════════════════════════${NC}"
echo -e "${CYAN}  ${BOLD}ССЫЛКА (для Hiddify / NekoBox / буфер)${NC}"
echo -e "${CYAN}═══════════════════════════════════════════${NC}"
echo -e "  ${GREEN}${URI}${NC}"
echo ""

if [[ "$HAS_XRAY" == true ]]; then
    echo -e "${CYAN}═══════════════════════════════════════════${NC}"
    echo -e "${CYAN}  ${BOLD}XRAY OUTBOUND (добавлен / для вставки)${NC}"
    echo -e "${CYAN}═══════════════════════════════════════════${NC}"
    cat "$XRAY_SNIPPET"
    echo ""
    echo -e "  Полный минимальный конфиг Xray:"
    echo -e "  ${BOLD}${XRAY_OUT}${NC}"
    echo -e "  Запуск: ${BOLD}\"${XRAY_BIN}\" run -c ${XRAY_OUT}${NC}"
    echo ""
fi

echo -e "${CYAN}═══════════════════════════════════════════${NC}"
echo -e "${CYAN}  ${BOLD}NATIVE HYSTERIA${NC}"
echo -e "${CYAN}═══════════════════════════════════════════${NC}"
echo -e "  Конфиг: ${BOLD}${HY_CFG}${NC}"
echo -e "  (также скопирован в ${HY_CFG_DEFAULT})"
if command -v hysteria &>/dev/null; then
    echo -e "  Запуск: ${BOLD}hysteria -c ${HY_CFG}${NC}"
else
    echo -e "  ${YELLOW}Бинарь hysteria не установлен${NC} — для GUI хватит ссылки выше"
fi
echo ""
echo -e "  SOCKS5: ${GREEN}127.0.0.1:${SOCKS_PORT}${NC}   HTTP: ${GREEN}127.0.0.1:${HTTP_PORT}${NC}"
echo ""
echo -e "${GREEN}Готово. Новый профиль «${P_NAME}» добавлен, старые файлы не удалялись.${NC}"
echo ""

if [[ "$DO_START" == true ]]; then
    if command -v hysteria &>/dev/null; then
        echo -e "${GREEN}Запуск native-клиента…${NC} (Ctrl+C — стоп)"
        exec hysteria -c "$HY_CFG"
    elif [[ "$HAS_XRAY" == true ]]; then
        echo -e "${GREEN}Запуск Xray…${NC} (Ctrl+C — стоп)"
        exec "$XRAY_BIN" run -c "$XRAY_OUT"
    else
        echo -e "${RED}Нечего запускать: нет hysteria и xray${NC}"
        exit 1
    fi
fi

Что делает клиентский скрипт:

  • Пишет native-конфиг Hysteria (~/.config/hysteria/config-….yaml)
  • Если Xray уже стоит — не трогает установку, добавляет outbound hy2-… в config.json (если находит writable) и печатает JSON в терминал
  • Повторный запуск с другой ссылкой = новый профиль (старые не удаляет)
  • Печатает hysteria2://… для копипаста в GUI

Безопасность: серверный скрипт генерирует случайный UDP-порт (10000–59999) и пароль. Веб-панели нет. Если хостинг режет UDP — откройте порт у провайдера. Опция --obfs на сервере включает Salamander против DPI.

Что делает скрипт

  • Включает BBR и увеличивает UDP-буферы (нужно для QUIC/Hysteria)
  • Устанавливает Hysteria 2 с официального установщика
  • Создаёт самоподписанный TLS-сертификат (SNI www.bing.com) и конфиг сервера
  • Открывает UDP-порт в файрволе (ufw, firewalld, iptables)
  • Генерирует случайный порт и пароль, печатает ссылку hysteria2://… в терминал
  • Сохраняет креды в /root/hysteria-credentials.txt

Опции: --name, --port, --pass, --obfs (Salamander).

Способ 2: Ручная установка Hysteria 2

Если предпочитаете контролировать каждый шаг (то же, что делает авто-скрипт).

1. Подключитесь к серверу

ssh root@ваш-IP-сервера

2. Обновите систему, BBR и UDP-буферы

bash
# Обновление
apt update && apt upgrade -y
apt install -y curl openssl ca-certificates

# BBR + буферы (нужно для QUIC/Hysteria)
cat >> /etc/sysctl.conf << 'EOF'
net.core.default_qdisc = fq
net.ipv4.tcp_congestion_control = bbr
net.core.rmem_max = 16777216
net.core.wmem_max = 16777216
EOF
sysctl -p

3. Установите Hysteria 2

bash
bash <(curl -fsSL https://get.hy2.sh/)

Официальный установщик поставит бинарь и unit hysteria-server.

4. Сертификат и конфиг сервера

Самоподписанный TLS (в ссылке клиента будет insecure=1). Порт и пароль замените на свои:

bash
mkdir -p /etc/hysteria
openssl req -x509 -nodes -newkey rsa:2048 \
  -keyout /etc/hysteria/server.key \
  -out /etc/hysteria/server.crt \
  -subj "/CN=www.bing.com" -days 3650

cat > /etc/hysteria/config.yaml << 'EOF'
listen: :45123

tls:
  cert: /etc/hysteria/server.crt
  key: /etc/hysteria/server.key

auth:
  type: password
  password: ЗАМЕНИТЕ_НА_СЛУЧАЙНЫЙ_ПАРОЛЬ

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

systemctl enable --now hysteria-server
systemctl restart hysteria-server
systemctl status hysteria-server --no-pager

Опционально: блок obfs с типом salamander — против DPI (тот же пароль потом в ссылке как obfs-password).

5. Откройте UDP-порт в файрволе

Hysteria 2 работает по UDP (не TCP). Порт = тот, что в listen:

bash
# UFW (Ubuntu/Debian)
ufw allow 45123/udp
ufw reload

# Firewalld
firewall-cmd --permanent --add-port=45123/udp
firewall-cmd --reload

# iptables
iptables -I INPUT -p udp --dport 45123 -j ACCEPT

6. Соберите ссылку для клиента

Подставьте IP сервера, порт и пароль:

hysteria2://ПАРОЛЬ@IP:45123/?insecure=1&sni=www.bing.com&alpn=h3#my-vpn

Эту ссылку вставьте в Hiddify/NekoBox или передайте клиентскому скрипту install-hysteria-config.sh. Данные также можно хранить в /root/hysteria-credentials.txt.

Важно: часть хостингов режет UDP на уровне инфраструктуры. Если порт открыт в ufw, но с телефона не коннектится — откройте UDP в панели хостинга (Firewall / Security Groups). Hetzner, Vultr, DigitalOcean обычно открыты по умолчанию.

Безопасность: веб-панели нет — только конфиг и пароль. Берите случайный UDP-порт в диапазоне 10000–59999 (не 443/8443). Пароль — длинный случайный; не светите ссылку в публичных чатах.

Приложения для подключения

Нужна поддержка Hysteria 2 и импорт ссылки hysteria2://…. Обычные «только VLESS» клиенты (многие сборки V2RayNG) эту ссылку не поймут.

Hiddify

Windows, macOS, Linux, Android, iOS

Рекомендуемый клиент. Hysteria 2 из коробки, импорт из буфера. Open-source.

GitHub Releases →

NekoBox

Android, desktop-сборки

Лёгкий клиент на sing-box. Хорошо тянет Hysteria 2 и импорт ссылок.

GitHub Releases →

Streisand

iPhone, iPad, macOS

Удобный клиент для Apple. Импорт hysteria2:// из буфера / QR.

App Store →

CLI / Xray

Linux, сервер, VPS

Скрипт install-hysteria-config.sh: native Hysteria или outbound в уже стоящий Xray + вывод в терминал.

Скачать скрипт →

Как добавить конфиг в приложение

  1. Скопируйте ссылку hysteria2://… (из вывода серверного скрипта или из /root/hysteria-credentials.txt)
  2. Откройте Hiddify / NekoBox / Streisand
  3. Нажмите +Import from clipboard («Импорт из буфера»)
  4. Конфигурация добавится автоматически
  5. Нажмите Connect

Подключение и оплата подписок

VPN — первый шаг. Дальше нужно зарегистрироваться и оплатить подписку на AI-сервис. Вот как это сделать из России.

Оплата без иностранной карты

Сервис МТС Оплата позволяет оплачивать зарубежные подписки рублями через СБП или российскую банковскую карту.

МТС

МТС Оплата — зарубежные подписки

34+ сервисов: ChatGPT, Claude, Cursor, Midjourney, Figma, Spotify, Netflix и другие. Оплата через СБП или карту, ваучер на почту за 15 минут. Комиссия 0 ₽.

Как это работает:

  1. Откройте payment.mts.ru/tools и выберите сервис
  2. Укажите email и выберите номинал подписки
  3. Оплатите через СБП или банковскую карту
  4. Получите ваучер с инструкцией на почту (до 15 минут)
  5. Активируйте подписку по инструкции из письма

Важно: ваучеры МТС работают для аккаунтов региона США. При регистрации нового аккаунта используйте почту gmail.com и VPN с американским IP.

Регистрация с иностранным номером

Многие AI-сервисы (ChatGPT, Claude) требуют иностранный номер телефона при регистрации. Сервис HeroSMS позволяет получить виртуальный номер из 180+ стран для приёма SMS. Интерфейс на английском, но принимает оплату из России.

SIM

HeroSMS — виртуальные номера

Виртуальные номера из 180+ стран для приёма SMS. Номера для 700+ сервисов и приложений. Сайт на английском языке, но принимает СБП и карты Мир.

Способы оплаты из России:

  • СБП по QR-коду — комиссия 6% (самый выгодный)
  • Российские банковские карты (Мир) — комиссия 10.5%
  • Visa / Mastercard — комиссия 7% + $0.25
  • Криптовалюта — Bitcoin, USDT, ETH и другие

Как зарегистрироваться в AI-сервисе:

  1. Зарегистрируйтесь на hero-sms.com и пополните баланс
  2. Выберите сервис (OpenAI / Claude) и страну (Великобритания, Нидерланды и др.)
  3. Получите виртуальный номер — он активен 20 минут
  4. Укажите этот номер при регистрации в AI-сервисе
  5. SMS с кодом подтверждения появится на сайте HeroSMS
HeroSMS →

Мы не связаны с HeroSMS и не несём ответственности за работу сервиса — просто подсказываем рабочий вариант. Как и с любым подобным сервисом, не храните крупные суммы на балансе — пополняйте ровно столько, сколько нужно для конкретной активации.

Совет: включите VPN (США или Великобритания) до начала регистрации в AI-сервисе. Сервисы проверяют IP при создании аккаунта, а не только при входе.

Решение проблем

Не подключается

  • Порт должен быть открыт как UDP (не TCP) в ufw и в панели хостинга
  • Сервис: systemctl status hysteria-server — должен быть active
  • Логи: journalctl -u hysteria-server -n 50 --no-pager
  • Клиент: в ссылке есть insecure=1 (самоподписанный сертификат)
  • Клиент понимает Hysteria 2 (Hiddify / NekoBox), а не «только VLESS»

Служба не стартует

  • Проверьте YAML: hysteria server -c /etc/hysteria/config.yaml (ошибки парсинга в stdout)
  • Права на ключ: chmod 640 /etc/hysteria/server.key, владелец user hysteria если unit от него
  • Перезапуск: systemctl restart hysteria-server

Как дать доступ ещё одному человеку

По умолчанию у сервера один общий пароль — достаточно выдать ту же ссылку hysteria2://… (или прогнать install-hysteria-config.sh на его машине). Если нужен отдельный пароль — в /etc/hysteria/config.yaml смените auth.type на userpass и перечислите пользователей, затем systemctl restart hysteria-server и соберите новую ссылку с новым паролем.

Частые вопросы

Это легально?
Использование VPN для личных и рабочих целей в России не является административным правонарушением. Под ограничения подпадает предоставление публичных VPN-сервисов без лицензии и их реклама. Данная страница является технической документацией в составе образовательного курса.

Какой хостинг выбрать?
FirstVDS — оплата в рублях, серверы в Нидерландах/Казахстане, от 100 руб/мес, промокод 6481165030 даёт -25%. Hetzner, Vultr, DigitalOcean — тоже хороший выбор, но оплата в валюте. Важно: UDP не режется файрволом провайдера.

Почему Hysteria 2, а не WireGuard?
WireGuard легко узнаётся по сигнатуре. Hysteria 2 работает поверх QUIC/TLS (выглядит как HTTP/3), умеет маскировку (masquerade) и при необходимости обфускацию Salamander — обычно стабильнее на «шумных» и ограниченных каналах.

Чем это отличается от старых VLESS/3x-ui гайдов?
Авто-скрипт на этой странице ставит Hysteria 2, не 3x-ui. Ссылка начинается с hysteria2://, порт — UDP, веб-панели нет. Клиент — Hiddify/NekoBox (или CLI-скрипт).

Сколько пользователей на одном сервере?
Минимальный VPS (1–2 ядра, 1–2 ГБ) спокойно тянет десятки одновременных подключений для личного/командного использования. Упираетесь в канал, не в CPU.

// Обсуждение

Можно писать анонимно. Укажите email, чтобы получать уведомления об ответах.