diff --git a/initializator/README.md b/initializator/README.md new file mode 100644 index 0000000..ebe8980 --- /dev/null +++ b/initializator/README.md @@ -0,0 +1,196 @@ +# Initializator + +Набор скриптов для быстрой настройки нового VPS-сервера с нуля: файрвол, веб-сервер, SSL и VPN. + +## Требования + +- Ubuntu / Debian +- root-доступ + +## Быстрый старт + +```bash +git clone && cd initializator +``` + +### 1. Базовая настройка + +```bash +sudo bash common.sh # UFW-файрвол (deny incoming, allow SSH) +sudo bash nginx.sh # Nginx + правила UFW +sudo bash certbot.sh # Certbot для SSL-сертификатов +``` + +### 2. VPN-сервер + +Два варианта — выбирай нужный: + +| | `vless.sh` | `vless_ip.sh` | +|---|---|---| +| Подключение | По домену | По IP-адресу | +| Транспорт | WebSocket | TCP | +| Шифрование | TLS (Let's Encrypt) | Reality (XTLS) | +| Nginx | Нужен (проксирует WS) | Не нужен | +| Маскировка | Обычный HTTPS-сайт | TLS-хендшейк с реальным сайтом | + +## Скрипты + +### `common.sh` + +Устанавливает и настраивает UFW: + +- deny incoming / allow outgoing +- Открывает порт 22 (SSH) + +### `nginx.sh` + +- Устанавливает Nginx (если не установлен) +- Включает автозапуск +- Открывает порты 80/443 в UFW + +### `certbot.sh` + +- Устанавливает Certbot + плагин для Nginx + +### `vless.sh` — VLESS + WebSocket + TLS (по домену) + +Поднимает Xray-core за Nginx с WebSocket-транспортом и настоящим TLS-сертификатом. + +**Переменные `.env`:** + +```env +DOMAIN=example.com +VLESS_WS_PATH=stream +PORT=10001 +``` + +**Что делает:** + +1. Скачивает Xray-core с GitHub в `~/services/vless` +2. Генерирует UUID, создаёт `config.json` +3. Создаёт systemd-сервис `xray-vless` +4. Получает SSL-сертификат через Certbot (webroot) +5. Настраивает Nginx: HTTP -> HTTPS редирект, WebSocket-прокси +6. Выводит строку подключения + +**Архитектура:** + +``` +Клиент -> :443 (Nginx, TLS) -> WS /$VLESS_WS_PATH -> :$PORT (Xray) -> интернет +``` + +**Строка подключения:** + +``` +vless://UUID@DOMAIN:443?encryption=none&security=tls&sni=DOMAIN&type=ws&path=%2FPATH#Fish-VLESS +``` + +**Запуск:** + +```bash +sudo bash vless.sh +``` + +--- + +### `vless_ip.sh` — VLESS + Reality (по IP) + +Поднимает Xray-core напрямую на порту 443 с протоколом Reality. Nginx не нужен — Xray сам обрабатывает TLS, маскируясь под реальный сайт. + +**Переменные `.env`:** + +```env +SERVER_IP=45.146.202.107 +``` + +**Что делает:** + +1. Скачивает Xray-core с GitHub в `~/services/vless_ip` +2. Генерирует UUID + x25519 keypair + short ID +3. Создаёт `config.json` с Reality +4. Создаёт systemd-сервис `xray-vless-ip` +5. Открывает порт 443 в UFW +6. Выводит строку подключения + +**Архитектура:** + +``` +Клиент -> :443 (Xray, Reality/XTLS) -> интернет + | + └─ TLS fingerprint = www.kuper.ru (маскировка) +``` + +**Строка подключения:** + +``` +vless://UUID@IP:443?encryption=none&security=reality&sni=www.kuper.ru&fp=chrome&pbk=PUBLIC_KEY&sid=SHORT_ID&type=tcp&flow=xtls-rprx-vision#VLESS-Reality +``` + +**Запуск:** + +```bash +sudo bash vless_ip.sh +``` + +--- + +## Файл `.env` + +Создай `initializator/.env` перед запуском VPN-скриптов: + +```env +# Для vless.sh (доменный вариант) +DOMAIN=example.com +VLESS_WS_PATH=stream +PORT=10001 + +# Для vless_ip.sh (IP вариант) +SERVER_IP=45.146.202.107 +``` + +## Управление сервисом + +```bash +# Статус +systemctl status xray-vless # доменный +systemctl status xray-vless-ip # IP + +# Перезапуск +systemctl restart xray-vless +systemctl restart xray-vless-ip + +# Логи +journalctl -u xray-vless -f +journalctl -u xray-vless-ip -f +``` + +## Структура файлов на сервере + +``` +~/services/ +├── vless/ # доменный вариант +│ ├── xray # бинарник Xray-core +│ ├── config.json # конфиг сервера +│ └── connection.txt # строка подключения +└── vless_ip/ # IP вариант + ├── xray + ├── config.json + └── connection.txt + +/etc/systemd/system/ +├── xray-vless.service +└── xray-vless-ip.service + +/etc/nginx/sites-available/ +└── vless-$DOMAIN # только для доменного варианта +``` + +## Клиенты + +Строку подключения можно импортировать в: + +- **Android:** v2rayNG, NekoBox +- **iOS:** Streisand, V2Box +- **Windows:** Nekoray, v2rayN +- **macOS:** V2RayXS, Nekoray +- **Linux:** Nekoray diff --git a/initializator/certbot.sh b/initializator/certbot.sh new file mode 100755 index 0000000..830428a --- /dev/null +++ b/initializator/certbot.sh @@ -0,0 +1,15 @@ +#!/bin/bash +set -euo pipefail + +source "$(dirname "$0")/utils.sh" + +require_root + +if command -v certbot >/dev/null 2>&1; then + echo "Certbot is already installed: $(certbot --version 2>&1)" +else + echo "Installing Certbot..." + apt-get update -y || { echo "Failed to update package list"; exit 1; } + apt-get install -y certbot python3-certbot-nginx || { echo "Failed to install Certbot"; exit 1; } + echo "Certbot installed successfully." +fi diff --git a/initializator/common.sh b/initializator/common.sh new file mode 100644 index 0000000..c2b9843 --- /dev/null +++ b/initializator/common.sh @@ -0,0 +1,22 @@ +#!/bin/bash + +source "$(dirname "$0")/utils.sh" + +require_root + +# Check if UFW (Uncomplicated Firewall) is installed and display its status +if command -v ufw >/dev/null 2>&1; then + echo "UFW is installed." + ufw status verbose +else + echo "UFW is not installed. Installing..." + apt update && apt install -y ufw + + ufw default deny incoming + ufw default allow outgoing + ufw allow 22/tcp comment 'SSH' + + yes | ufw enable + echo "UFW installed and activated." + ufw status verbose +fi \ No newline at end of file diff --git a/initializator/nginx.sh b/initializator/nginx.sh new file mode 100644 index 0000000..32e68a5 --- /dev/null +++ b/initializator/nginx.sh @@ -0,0 +1,35 @@ +#!/bin/bash +set -euo pipefail + +source "$(dirname "$0")/utils.sh" + +require_root + +if command -v nginx >/dev/null 2>&1; then + echo "Nginx is already installed: $(nginx -v 2>&1)" +else + echo "Installing Nginx..." + apt-get update -y || { echo "Failed to update package list"; exit 1; } + apt-get install -y nginx || { echo "Failed to install Nginx"; exit 1; } + echo "Nginx installed successfully." +fi + +if ! systemctl is-active --quiet nginx; then + echo "Starting Nginx..." + systemctl start nginx || { echo "Failed to start Nginx"; exit 1; } +fi + +if ! systemctl is-enabled --quiet nginx; then + echo "Enabling Nginx on boot..." + systemctl enable nginx || { echo "Failed to enable Nginx"; exit 1; } +fi + +echo "Nginx status:" +systemctl status nginx --no-pager + +if command -v ufw >/dev/null 2>&1; then + ufw allow 'Nginx Full' || { echo "Failed to add UFW rule for Nginx"; exit 1; } + echo "UFW rule for Nginx added." +else + echo "WARNING: UFW is not installed, skipping firewall rule. Run common.sh first." +fi diff --git a/initializator/utils.sh b/initializator/utils.sh new file mode 100644 index 0000000..60b68da --- /dev/null +++ b/initializator/utils.sh @@ -0,0 +1,8 @@ +#!/bin/bash + +require_root() { + if [ $EUID -ne 0 ]; then + echo "This script must be run as root" + exit 1 + fi +} \ No newline at end of file diff --git a/initializator/vless.sh b/initializator/vless.sh new file mode 100644 index 0000000..cc45eaf --- /dev/null +++ b/initializator/vless.sh @@ -0,0 +1,286 @@ +#!/bin/bash +set -euo pipefail + +source "$(dirname "$0")/utils.sh" + +require_root + +SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" +ENV_FILE="$SCRIPT_DIR/.env" + +if [ ! -f "$ENV_FILE" ]; then + echo "ERROR: .env file not found at $ENV_FILE" + echo "Create $ENV_FILE with the following variables:" + echo " DOMAIN=example.com" + echo " VLESS_WS_PATH=stream" + echo " PORT=10001" + exit 1 +fi + +source "$ENV_FILE" + +: "${DOMAIN:?DOMAIN is not set in .env}" +: "${VLESS_WS_PATH:?VLESS_WS_PATH is not set in .env}" +: "${PORT:?PORT is not set in .env}" + +REAL_USER="${SUDO_USER:-$(whoami)}" +REAL_HOME=$(eval echo "~$REAL_USER") +VLESS_DIR="$REAL_HOME/services/vless" + +echo "=== VLESS (Xray-core) Installation ===" +echo " Domain: $DOMAIN" +echo " WS Path: /$VLESS_WS_PATH" +echo " Port: $PORT" +echo " Directory: $VLESS_DIR" +echo "" + +# --- 1. Download Xray-core --- + +mkdir -p "$VLESS_DIR" + +ARCH=$(uname -m) +case "$ARCH" in + x86_64) XRAY_ARCH="64" ;; + aarch64) XRAY_ARCH="arm64-v8a" ;; + *) + echo "ERROR: unsupported architecture: $ARCH" + exit 1 + ;; +esac + +XRAY_ZIP="Xray-linux-${XRAY_ARCH}.zip" +DOWNLOAD_URL="https://github.com/XTLS/Xray-core/releases/latest/download/${XRAY_ZIP}" + +if [ -x "$VLESS_DIR/xray" ]; then + echo "[1] Xray already installed: $("$VLESS_DIR/xray" version | head -1)" +else + echo "[1] Downloading Xray-core..." + for cmd in wget unzip; do + if ! command -v "$cmd" >/dev/null 2>&1; then + echo " Installing $cmd..." + apt-get install -y -qq "$cmd" + fi + done + wget -q --show-progress -O "/tmp/$XRAY_ZIP" "$DOWNLOAD_URL" + unzip -o -q "/tmp/$XRAY_ZIP" -d "$VLESS_DIR" + chmod +x "$VLESS_DIR/xray" + rm -f "/tmp/$XRAY_ZIP" + echo " Installed: $("$VLESS_DIR/xray" version | head -1)" +fi +echo "" + +# --- 2. Generate UUID & create config --- + +UUID=$("$VLESS_DIR/xray" uuid) +echo "[2] Generated UUID: $UUID" + +cat > "$VLESS_DIR/config.json" < "/etc/systemd/system/${SERVICE_NAME}.service" </dev/null; then + echo " Setting server_names_hash_bucket_size..." + echo 'server_names_hash_bucket_size 128;' > /etc/nginx/conf.d/hash_bucket_size.conf +fi + +mkdir -p "/var/www/certbot" +mkdir -p "/var/www/${DOMAIN}" +if [ ! -f "/var/www/${DOMAIN}/index.html" ]; then + echo "

Welcome

" > "/var/www/${DOMAIN}/index.html" +fi + +if [ -f "/etc/letsencrypt/live/${DOMAIN}/fullchain.pem" ]; then + echo "[4] SSL certificate already exists" +else + echo "[4] Obtaining SSL certificate..." + + cat > "/etc/nginx/sites-available/$NGINX_SITE" <&1; then + + echo " Certbot failed, resetting ACME account and retrying..." + rm -rf /etc/letsencrypt/accounts/acme-v02.api.letsencrypt.org/ + + certbot certonly --webroot -w /var/www/certbot -d "$DOMAIN" \ + --non-interactive --agree-tos --email "admin@${DOMAIN}" || { + echo "ERROR: Failed to obtain SSL certificate" + exit 1 + } + fi + echo " Certificate obtained" +fi +echo "" + +# --- 5. Nginx full config (with SSL) --- + +echo "[5] Configuring nginx (HTTPS + WebSocket proxy)..." + +cat > "/etc/nginx/sites-available/$NGINX_SITE" < "$VLESS_DIR/connection.txt" +chown "$REAL_USER:$REAL_USER" "$VLESS_DIR/connection.txt" + +echo "=== VLESS READY ===" +echo "" +echo "$VLESS_LINK" +echo "" +echo "Saved to: $VLESS_DIR/connection.txt" diff --git a/initializator/vless_ip.sh b/initializator/vless_ip.sh new file mode 100644 index 0000000..2a4cc28 --- /dev/null +++ b/initializator/vless_ip.sh @@ -0,0 +1,207 @@ +#!/bin/bash +set -euo pipefail + +source "$(dirname "$0")/utils.sh" + +require_root + +SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" +ENV_FILE="$SCRIPT_DIR/.env" + +if [ ! -f "$ENV_FILE" ]; then + echo "ERROR: .env file not found at $ENV_FILE" + echo "Create $ENV_FILE with: SERVER_IP=45.146.202.107" + exit 1 +fi + +source "$ENV_FILE" + +: "${SERVER_IP:?SERVER_IP is not set in .env}" + +REAL_USER="${SUDO_USER:-$(whoami)}" +REAL_HOME=$(eval echo "~$REAL_USER") +VLESS_DIR="$REAL_HOME/services/vless_ip" +SERVICE_NAME="xray-vless-ip" +REALITY_DEST="www.kuper.ru:443" +REALITY_SERVER_NAME="www.kuper.ru" + +echo "=== VLESS + Reality Installation ===" +echo " Server IP: $SERVER_IP" +echo " Port: 443" +echo " Directory: $VLESS_DIR" +echo "" + +# --- 1. Download Xray-core --- + +mkdir -p "$VLESS_DIR" + +ARCH=$(uname -m) +case "$ARCH" in + x86_64) XRAY_ARCH="64" ;; + aarch64) XRAY_ARCH="arm64-v8a" ;; + *) + echo "ERROR: unsupported architecture: $ARCH" + exit 1 + ;; +esac + +XRAY_ZIP="Xray-linux-${XRAY_ARCH}.zip" +DOWNLOAD_URL="https://github.com/XTLS/Xray-core/releases/latest/download/${XRAY_ZIP}" + +if [ -x "$VLESS_DIR/xray" ]; then + echo "[1] Xray already installed: $("$VLESS_DIR/xray" version | head -1)" +else + echo "[1] Downloading Xray-core..." + for cmd in wget unzip; do + if ! command -v "$cmd" >/dev/null 2>&1; then + echo " Installing $cmd..." + apt-get install -y -qq "$cmd" + fi + done + wget -q --show-progress -O "/tmp/$XRAY_ZIP" "$DOWNLOAD_URL" + unzip -o -q "/tmp/$XRAY_ZIP" -d "$VLESS_DIR" + chmod +x "$VLESS_DIR/xray" + rm -f "/tmp/$XRAY_ZIP" + echo " Installed: $("$VLESS_DIR/xray" version | head -1)" +fi +echo "" + +# --- 2. Generate keys & config --- + +UUID=$("$VLESS_DIR/xray" uuid) +echo "[2] Generated UUID: $UUID" + +KEYS=$("$VLESS_DIR/xray" x25519 2>&1) || true + +PRIVATE_KEY=$(echo "$KEYS" | grep -i 'private' | awk '{print $NF}' || true) +PUBLIC_KEY=$(echo "$KEYS" | grep -i 'password' | awk '{print $NF}' || true) + +if [ -z "$PRIVATE_KEY" ] || [ -z "$PUBLIC_KEY" ]; then + echo "ERROR: Failed to parse x25519 keys. Raw output:" + echo "$KEYS" + exit 1 +fi + +echo " Reality private key: $PRIVATE_KEY" +echo " Reality public key: $PUBLIC_KEY" + +SHORT_ID=$(openssl rand -hex 4) +echo " Short ID: $SHORT_ID" + +cat > "$VLESS_DIR/config.json" < "/etc/systemd/system/${SERVICE_NAME}.service" </dev/null 2>&1; then + ufw allow 443/tcp comment 'VLESS Reality' >/dev/null 2>&1 || true + echo "[4] UFW: port 443 opened" +else + echo "[4] UFW not installed, skipping firewall rule" +fi +echo "" + +# --- 5. Fix ownership & output --- + +chown -R "$REAL_USER:$REAL_USER" "$VLESS_DIR" + +VLESS_LINK="vless://${UUID}@${SERVER_IP}:443?encryption=none&security=reality&sni=${REALITY_SERVER_NAME}&fp=chrome&pbk=${PUBLIC_KEY}&sid=${SHORT_ID}&type=tcp&flow=xtls-rprx-vision#VLESS-Reality" + +echo "$VLESS_LINK" > "$VLESS_DIR/connection.txt" +chown "$REAL_USER:$REAL_USER" "$VLESS_DIR/connection.txt" + +echo "=== VLESS READY ===" +echo "" +echo "$VLESS_LINK" +echo "" +echo "Saved to: $VLESS_DIR/connection.txt"