add server scripts
This commit is contained in:
parent
4a62a574b0
commit
d3a12fc48a
196
initializator/README.md
Normal file
196
initializator/README.md
Normal file
@ -0,0 +1,196 @@
|
|||||||
|
# Initializator
|
||||||
|
|
||||||
|
Набор скриптов для быстрой настройки нового VPS-сервера с нуля: файрвол, веб-сервер, SSL и VPN.
|
||||||
|
|
||||||
|
## Требования
|
||||||
|
|
||||||
|
- Ubuntu / Debian
|
||||||
|
- root-доступ
|
||||||
|
|
||||||
|
## Быстрый старт
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git clone <repo> && 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
|
||||||
15
initializator/certbot.sh
Executable file
15
initializator/certbot.sh
Executable file
@ -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
|
||||||
22
initializator/common.sh
Normal file
22
initializator/common.sh
Normal file
@ -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
|
||||||
35
initializator/nginx.sh
Normal file
35
initializator/nginx.sh
Normal file
@ -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
|
||||||
8
initializator/utils.sh
Normal file
8
initializator/utils.sh
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
require_root() {
|
||||||
|
if [ $EUID -ne 0 ]; then
|
||||||
|
echo "This script must be run as root"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
286
initializator/vless.sh
Normal file
286
initializator/vless.sh
Normal file
@ -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" <<EOF
|
||||||
|
{
|
||||||
|
"log": {
|
||||||
|
"loglevel": "warning"
|
||||||
|
},
|
||||||
|
"inbounds": [
|
||||||
|
{
|
||||||
|
"listen": "127.0.0.1",
|
||||||
|
"port": ${PORT},
|
||||||
|
"protocol": "vless",
|
||||||
|
"settings": {
|
||||||
|
"clients": [
|
||||||
|
{
|
||||||
|
"id": "${UUID}"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"decryption": "none"
|
||||||
|
},
|
||||||
|
"streamSettings": {
|
||||||
|
"network": "ws",
|
||||||
|
"wsSettings": {
|
||||||
|
"path": "/${VLESS_WS_PATH}"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"sniffing": {
|
||||||
|
"enabled": true,
|
||||||
|
"destOverride": ["http", "tls", "quic"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"outbounds": [
|
||||||
|
{
|
||||||
|
"protocol": "freedom",
|
||||||
|
"tag": "direct"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"protocol": "blackhole",
|
||||||
|
"tag": "block"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"routing": {
|
||||||
|
"rules": [
|
||||||
|
{
|
||||||
|
"type": "field",
|
||||||
|
"outboundTag": "block",
|
||||||
|
"protocol": ["bittorrent"]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
EOF
|
||||||
|
|
||||||
|
echo " Config: $VLESS_DIR/config.json"
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
# --- 3. Systemd service ---
|
||||||
|
|
||||||
|
SERVICE_NAME="xray-vless"
|
||||||
|
|
||||||
|
echo "[3] Creating systemd service..."
|
||||||
|
cat > "/etc/systemd/system/${SERVICE_NAME}.service" <<EOF
|
||||||
|
[Unit]
|
||||||
|
Description=Xray VLESS Server
|
||||||
|
After=network.target
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Type=simple
|
||||||
|
ExecStart=${VLESS_DIR}/xray run -config ${VLESS_DIR}/config.json
|
||||||
|
Restart=on-failure
|
||||||
|
RestartSec=5
|
||||||
|
LimitNOFILE=65535
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
||||||
|
EOF
|
||||||
|
|
||||||
|
systemctl daemon-reload
|
||||||
|
systemctl enable "$SERVICE_NAME" --quiet
|
||||||
|
systemctl restart "$SERVICE_NAME"
|
||||||
|
echo " Service $SERVICE_NAME started"
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
# --- 4. SSL certificate ---
|
||||||
|
|
||||||
|
NGINX_SITE="vless-${DOMAIN}"
|
||||||
|
|
||||||
|
if grep -q '^\s*#.*server_names_hash_bucket_size' /etc/nginx/nginx.conf; then
|
||||||
|
echo " Enabling server_names_hash_bucket_size in nginx.conf..."
|
||||||
|
sed -i 's/.*#\s*server_names_hash_bucket_size.*/ server_names_hash_bucket_size 128;/' /etc/nginx/nginx.conf
|
||||||
|
elif ! grep -rq 'server_names_hash_bucket_size' /etc/nginx/nginx.conf /etc/nginx/conf.d/ 2>/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 "<html><body><h1>Welcome</h1></body></html>" > "/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" <<NGINX
|
||||||
|
server {
|
||||||
|
listen 80;
|
||||||
|
server_name ${DOMAIN};
|
||||||
|
|
||||||
|
location /.well-known/acme-challenge/ {
|
||||||
|
root /var/www/certbot;
|
||||||
|
}
|
||||||
|
|
||||||
|
location / {
|
||||||
|
root /var/www/${DOMAIN};
|
||||||
|
index index.html;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
NGINX
|
||||||
|
|
||||||
|
ln -sf "/etc/nginx/sites-available/$NGINX_SITE" "/etc/nginx/sites-enabled/$NGINX_SITE"
|
||||||
|
nginx -t || { echo "ERROR: nginx config test failed"; exit 1; }
|
||||||
|
systemctl reload nginx
|
||||||
|
|
||||||
|
if ! certbot certonly --webroot -w /var/www/certbot -d "$DOMAIN" \
|
||||||
|
--non-interactive --agree-tos --email "admin@${DOMAIN}" 2>&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" <<NGINX
|
||||||
|
server {
|
||||||
|
listen 80;
|
||||||
|
server_name ${DOMAIN};
|
||||||
|
|
||||||
|
location /.well-known/acme-challenge/ {
|
||||||
|
root /var/www/certbot;
|
||||||
|
}
|
||||||
|
|
||||||
|
location / {
|
||||||
|
return 301 https://\$host\$request_uri;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
server {
|
||||||
|
listen 443 ssl;
|
||||||
|
http2 on;
|
||||||
|
server_name ${DOMAIN};
|
||||||
|
|
||||||
|
ssl_certificate /etc/letsencrypt/live/${DOMAIN}/fullchain.pem;
|
||||||
|
ssl_certificate_key /etc/letsencrypt/live/${DOMAIN}/privkey.pem;
|
||||||
|
ssl_protocols TLSv1.2 TLSv1.3;
|
||||||
|
ssl_ciphers HIGH:!aNULL:!MD5;
|
||||||
|
|
||||||
|
location /${VLESS_WS_PATH} {
|
||||||
|
proxy_redirect off;
|
||||||
|
proxy_pass http://127.0.0.1:${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_read_timeout 300s;
|
||||||
|
proxy_send_timeout 300s;
|
||||||
|
}
|
||||||
|
|
||||||
|
location / {
|
||||||
|
root /var/www/${DOMAIN};
|
||||||
|
index index.html;
|
||||||
|
try_files \$uri \$uri/ =404;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
NGINX
|
||||||
|
|
||||||
|
ln -sf "/etc/nginx/sites-available/$NGINX_SITE" "/etc/nginx/sites-enabled/$NGINX_SITE"
|
||||||
|
nginx -t || { echo "ERROR: nginx config test failed"; exit 1; }
|
||||||
|
systemctl reload nginx
|
||||||
|
echo " Nginx configured and reloaded"
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
# --- 6. Fix ownership & output ---
|
||||||
|
|
||||||
|
chown -R "$REAL_USER:$REAL_USER" "$VLESS_DIR"
|
||||||
|
|
||||||
|
VLESS_LINK="vless://${UUID}@${DOMAIN}:443?encryption=none&security=tls&sni=${DOMAIN}&type=ws&path=%2F${VLESS_WS_PATH}#Fish-VLESS"
|
||||||
|
|
||||||
|
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"
|
||||||
207
initializator/vless_ip.sh
Normal file
207
initializator/vless_ip.sh
Normal file
@ -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" <<EOF
|
||||||
|
{
|
||||||
|
"log": {
|
||||||
|
"loglevel": "warning"
|
||||||
|
},
|
||||||
|
"inbounds": [
|
||||||
|
{
|
||||||
|
"listen": "0.0.0.0",
|
||||||
|
"port": 443,
|
||||||
|
"protocol": "vless",
|
||||||
|
"settings": {
|
||||||
|
"clients": [
|
||||||
|
{
|
||||||
|
"id": "${UUID}",
|
||||||
|
"flow": "xtls-rprx-vision"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"decryption": "none"
|
||||||
|
},
|
||||||
|
"streamSettings": {
|
||||||
|
"network": "tcp",
|
||||||
|
"security": "reality",
|
||||||
|
"realitySettings": {
|
||||||
|
"dest": "${REALITY_DEST}",
|
||||||
|
"serverNames": ["${REALITY_SERVER_NAME}"],
|
||||||
|
"privateKey": "${PRIVATE_KEY}",
|
||||||
|
"shortIds": ["${SHORT_ID}"]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"sniffing": {
|
||||||
|
"enabled": true,
|
||||||
|
"destOverride": ["http", "tls", "quic"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"outbounds": [
|
||||||
|
{
|
||||||
|
"protocol": "freedom",
|
||||||
|
"tag": "direct"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"protocol": "blackhole",
|
||||||
|
"tag": "block"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"routing": {
|
||||||
|
"rules": [
|
||||||
|
{
|
||||||
|
"type": "field",
|
||||||
|
"outboundTag": "block",
|
||||||
|
"protocol": ["bittorrent"]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
EOF
|
||||||
|
|
||||||
|
echo " Config: $VLESS_DIR/config.json"
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
# --- 3. Systemd service ---
|
||||||
|
|
||||||
|
echo "[3] Creating systemd service..."
|
||||||
|
cat > "/etc/systemd/system/${SERVICE_NAME}.service" <<EOF
|
||||||
|
[Unit]
|
||||||
|
Description=Xray VLESS Reality Server
|
||||||
|
After=network.target
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Type=simple
|
||||||
|
ExecStart=${VLESS_DIR}/xray run -config ${VLESS_DIR}/config.json
|
||||||
|
Restart=on-failure
|
||||||
|
RestartSec=5
|
||||||
|
LimitNOFILE=65535
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
||||||
|
EOF
|
||||||
|
|
||||||
|
systemctl daemon-reload
|
||||||
|
systemctl enable "$SERVICE_NAME" --quiet
|
||||||
|
systemctl restart "$SERVICE_NAME"
|
||||||
|
|
||||||
|
sleep 1
|
||||||
|
if systemctl is-active --quiet "$SERVICE_NAME"; then
|
||||||
|
echo " Service $SERVICE_NAME started"
|
||||||
|
else
|
||||||
|
echo "ERROR: Service failed to start"
|
||||||
|
journalctl -u "$SERVICE_NAME" --no-pager -n 10
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
# --- 4. Firewall ---
|
||||||
|
|
||||||
|
if command -v ufw >/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"
|
||||||
Loading…
x
Reference in New Issue
Block a user