Konstantin GARSHENIN
учел твои замечания. посмотри.
#!/bin/bash
# Автоматизированное развёртывание инфраструктуры: веб-сайт + MTProto-прокси (TeleMT) + 3x-ui панель
# Исправленная версия с учётом всех замечаний и современных best practices
set -euo pipefail
# Цвета для вывода
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m' # No Color
log_info() { echo -e "${GREEN}[INFO]${NC} $1"; }
log_warn() { echo -e "${YELLOW}[WARN]${NC} $1"; }
log_error() { echo -e "${RED}[ERROR]${NC} $1"; }
# Функция для подтверждения продолжения
confirm_continue() {
echo ""
read -p "Нажмите Enter для продолжения или Ctrl+C для отмены..."
echo ""
}
# Основная функция
main() {
echo "=== АВТОМАТИЗИРОВАННОЕ РАЗВЁРТЫВАНИЕ ИНФРАСТРУКТУРЫ ==="
echo "Веб-сайт + MTProto-прокси (TeleMT) + 3x-ui панель"
echo ""
# Проверка прав root
if [[ $EUID -ne 0 ]]; then
log_error "Запустите скрипт с правами root (sudo)."
exit 1
fi
# Запрос данных у пользователя
log_info "Введите параметры развёртывания:"
read -p "Введите основной домен (например, example.com): " MAIN_DOMAIN
read -p "Введите поддомен для веб-сайта [по умолчанию: www.$MAIN_DOMAIN]: " WEB_SUBDOMAIN
WEB_SUBDOMAIN=${WEB_SUBDOMAIN:-"www.$MAIN_DOMAIN"}
read -p "Введите поддомен для Telegram MTProto прокси [по умолчанию: tg.$MAIN_DOMAIN]: " TG_SUBDOMAIN
TG_SUBDOMAIN=${TG_SUBDOMAIN:-"tg.$MAIN_DOMAIN"}
read -p "Введите поддомен для 3x-ui панели [по умолчанию: proxy.$MAIN_DOMAIN]: " PROXY_SUBDOMAIN
PROXY_SUBDOMAIN=${PROXY_SUBDOMAIN:-"proxy.$MAIN_DOMAIN"}
read -p "Введите email для уведомлений Let's Encrypt: " USER_EMAIL
# Порты по умолчанию
WEB_PORT=8443
TG_PORT=10443
PROXY_PORT=4443
NGINX_STREAM_PORT=443
echo ""
log_info "Параметры развёртывания:"
echo " Основной домен: $MAIN_DOMAIN"
echo " Веб-сайт: $WEB_SUBDOMAIN:$WEB_PORT"
echo " Telegram прокси: $TG_SUBDOMAIN:$TG_PORT"
echo " 3x-ui панель: $PROXY_SUBDOMAIN:$PROXY_PORT"
echo " Email: $USER_EMAIL"
echo ""
confirm_continue
# Шаг 1: Обновление системы и установка базовых пакетов
log_info "Шаг 1: Обновление системы и установка базовых пакетов..."
apt update
apt install -y curl wget git ufw certbot nginx
log_info "Базовые пакеты успешно установлены"
confirm_continue
# Шаг 2: Настройка фаервола UFW
log_info "Шаг 2: Настройка фаервола UFW..."
ufw allow 22/tcp
ufw allow 80/tcp
ufw allow $NGINX_STREAM_PORT/tcp # Внешний порт 443 = $NGINX_STREAM_PORT
ufw --force enable
log_info "Фаервол настроен, открыты порты: 22, 80, $NGINX_STREAM_PORT"
confirm_continue
# Шаг 3: Получение SSL-сертификатов Let's Encrypt
log_info "Шаг 3: Получение SSL-сертификатов Let's Encrypt..."
# Проверяем существование сертификата
if [ -d "/etc/letsencrypt/live/$MAIN_DOMAIN" ]; then
log_warn "Сертификат для $MAIN_DOMAIN уже существует."
read -p "Перевыпустить сертификат? (y/N): " -n 1 -r
echo ""
if [[ $REPLY =~ ^[Yy]$ ]]; then
certbot delete --cert-name "$MAIN_DOMAIN" true
fi
fi
# Создаём директорию для веб-рута Certbot
mkdir -p /var/www/html
systemctl start nginx 2>/dev/null true
# Получаем SAN-сертификат для всех поддоменов
log_info "Запрашиваем SAN-сертификат для: $WEB_SUBDOMAIN, $TG_SUBDOMAIN, $PROXY_SUBDOMAIN"
certbot certonly --webroot -w /var/www/html \
-d "$WEB_SUBDOMAIN" -d "$TG_SUBDOMAIN" -d "$PROXY_SUBDOMAIN" \
--agree-tos --email "$USER_EMAIL" --non-interactive \
--cert-name "$MAIN_DOMAIN"
if [ $? -eq 0 ]; then
log_info "SSL-сертификаты успешно получены!"
echo "Сертификаты расположены в: /etc/letsencrypt/live/$MAIN_DOMAIN/"
else
log_error "Ошибка получения сертификатов. Проверьте DNS-записи."
exit 1
fi
confirm_continue
# Шаг 4: Настройка Nginx Stream для SNI-роутинга
log_info "Шаг 4: Настройка Nginx Stream для SNI-роутинга..."
# Создаём структуру директорий для stream-конфигураций
mkdir -p /etc/nginx/stream-available /etc/nginx/stream-enabled
# Проверяем существование stream-блока в nginx.conf
if grep -q "^stream\s*{" /etc/nginx/nginx.conf; then
log_warn "Stream блок уже существует в nginx.conf"
# Проверяем наличие нашего include
if ! grep -q "include /etc/nginx/stream-enabled/\\*.conf;" /etc/nginx/nginx.conf; then
# Добавляем include внутрь существующего stream-блока
sed -i '/^stream\s*{/a \ include /etc/nginx/stream-enabled/*.conf;' /etc/nginx/nginx.conf
log_info "Добавлена директива include внутрь существующего stream-блока"
fi
else
# Добавляем include на верхний уровень nginx.conf
if ! grep -q "include /etc/nginx/stream-enabled/\\*.conf" /etc/nginx/nginx.conf; then
echo "include /etc/nginx/stream-enabled/*.conf;" >> /etc/nginx/nginx.conf
log_info "Добавлена директива include для stream-конфигураций в nginx.conf"
fi
fi
# Создаём stream-конфигурацию для SNI-роутинга
cat > /etc/nginx/stream-available/sni_router.conf << EOF
stream {
map \$ssl_preread_server_name \$backend {
hostnames;
$WEB_SUBDOMAIN web_backend;
$TG_SUBDOMAIN telegram_backend;
$PROXY_SUBDOMAIN xray_backend;
default web_backend;
}
upstream web_backend {
server 127.0.0.1:$WEB_PORT;
}
upstream telegram_backend {
server 127.0.0.1:$TG_PORT;
}
upstream xray_backend {
server 127.0.0.1:$PROXY_PORT;
}
server {
listen $NGINX_STREAM_PORT reuseport;
listen [::]:$NGINX_STREAM_PORT reuseport;
proxy_pass \$backend;
ssl_preread on;
# proxy_protocol удалён, так как бэкенды его не поддерживают
}
}
EOF
# Активируем конфигурацию
ln -sf /etc/nginx/stream-available/sni_router.conf /etc/nginx/stream-enabled/
log_info "Stream-конфигурация Nginx создана и активирована"
confirm_continue
# Шаг 5: Настройка веб-сервера
log_info "Шаг 5: Настройка веб-сервера..."
mkdir -p /var/www/"$MAIN_DOMAIN"
cat > /var/www/"$MAIN_DOMAIN"/index.html << EOF
<!DOCTYPE html>
<html lang="ru">
<head>
<meta charset="UTF-8">
<title>Добро пожаловать на $MAIN_DOMAIN</title>
</head>
<body>
<h1>Добро пожаловать на $MAIN_DOMAIN</h1>
<p>Сервер успешно настроен и работает.</p>
</body>
</html>
EOF
# Создаём конфигурацию виртуального хоста для веб-сайта
cat > /etc/nginx/sites-available/"$MAIN_DOMAIN" << EOF
server {
listen 127.0.0.1:$WEB_PORT ssl http2;
server_name $WEB_SUBDOMAIN;
# Используем путь основного домена для SAN-сертификата
ssl_certificate /etc/letsencrypt/live/$MAIN_DOMAIN/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/$MAIN_DOMAIN/privkey.pem;
root /var/www/$MAIN_DOMAIN;
index index.html;
location / {
try_files \$uri \$uri/ =404;
}
}
EOF
# Активируем сайт
ln -sf /etc/nginx/sites-available/"$MAIN_DOMAIN" /etc/nginx/sites-enabled/
log_info "Веб-сервер настроен: https://$WEB_SUBDOMAIN"
confirm_continue
# Шаг 6: Установка и настройка TeleMT
log_info "Шаг 6: Установка и настройка TeleMT для MTProto прокси..."
# Проверяем, не установлен ли уже TeleMT
if command -v telemt &> /dev/null; then
log_warn "TeleMT уже установлен, пропускаем установку."
else
log_info "Скачиваем TeleMT..."
wget -q https://github.com/telemt/telemt/releases/latest/download/telemt-linux-x86_64.tar.gz -O /tmp/telemt.tar.gz
tar -xzf /tmp/telemt.tar.gz -C /tmp/
mv /tmp/telemt /usr/local/bin/
chmod +x /usr/local/bin/telemt
rm -f /tmp/telemt.tar.gz
fi
# Создаём структуру директорий для TeleMT
mkdir -p /etc/telemt /etc/telemt/certs
# Копируем сертификаты (используем путь основного домена для SAN-сертификата)
cp /etc/letsencrypt/live/"$MAIN_DOMAIN"/fullchain.pem /etc/telemt/certs/
cp /etc/letsencrypt/live/"$MAIN_DOMAIN"/privkey.pem /etc/telemt/certs/
# Генерируем секретный ключ для MTProto
MT_SECRET=$(openssl rand -hex 16)
log_info "Сгенерирован секретный ключ MTProto: $MT_SECRET"
echo "СОХРАНИТЕ ЭТОТ КЛЮЧ ДЛЯ НАСТРОЙКИ КЛИЕНТОВ TELEGRAM!"
# Создаём конфигурационный файл TeleMT
cat > /etc/telemt/config.toml << EOF
[general]
use_middle_proxy = false
[server]
port = $TG_PORT
[[server.listeners]]
ip = "127.0.0.1"
[general.modes]
tls = true
mtproto = true
[censorship]
tls_domain = "$TG_SUBDOMAIN"
mask = false
[access.users]
mtproto_user = "$MT_SECRET"
[server.tls]
cert_file = "/etc/telemt/certs/fullchain.pem"
key_file = "/etc/telemt/certs/privkey.pem"
EOF
# Создаём systemd службу для TeleMT
cat > /etc/systemd/system/telemt.service << EOF
[Unit]
Description=TeleMT MTProto Telegram Proxy
After=network.target
Requires=network.target
[Service]
Type=simple
User=nobody
Group=nogroup
ExecStart=/usr/local/bin/telemt -c /etc/telemt/config.toml
Restart=always
RestartSec=3
LimitNOFILE=65536
Environment="RUST_LOG=info"
# Защита службы
NoNewPrivileges=true
PrivateTmp=true
ProtectSystem=strict
ProtectHome=true
ReadWritePaths=/etc/telemt
[Install]
WantedBy=multi-user.target
EOF
# Запускаем службу TeleMT
systemctl daemon-reload
systemctl enable telemt
systemctl start telemt
sleep 2
if systemctl is-active --quiet telemt; then
log_info "TeleMT успешно запущен и слушает на 127.0.0.1:$TG_PORT"
else
log_error "Ошибка запуска TeleMT. Проверьте логи: journalctl -u telemt -f"
exit 1
fi
echo ""
echo "ДАННЫЕ ДЛЯ ПОДКЛЮЧЕНИЯ TELEGRAM:"
echo " Сервер: $TG_SUBDOMAIN"
echo " Порт: 443"
echo " Секрет: $MT_SECRET"
echo " Ссылка: tg://proxy?server=$TG_SUBDOMAIN&port=443&secret=$MT_SECRET"
echo ""
confirm_continue
# Шаг 7: Установка и настройка 3x-ui
log_info "Шаг 7: Установка и настройка 3x-ui панели..."
# Используем официальный скрипт установки 3x-ui [github.com](https://github.com/MHSanaei/3x-ui/wiki/Installation)
bash <(curl -Ls https://raw.githubusercontent.com/MHSanaei/3x-ui/master/install.sh)
if [ $? -eq 0 ]; then
log_info "3x-ui успешно установлен"
else
log_error "Ошибка установки 3x-ui. Продолжаем без панели..."
fi
# Даём время для инициализации 3x-ui
sleep 5
# Конфигурационные инструкции для 3x-ui
log_info "Настраиваем 3x-ui для работы через Nginx SNI-роутинг..."
echo ""
echo "РУЧНАЯ НАСТРОЙКА 3X-UI ТРЕБУЕТСЯ:"
echo "1. Откройте панель 3x-ui: http://ваш_сервер:2053"
echo "2. Логин: admin, Пароль: admin"
echo "3. Смените пароль администратора"
echo "4. Создайте инбаунд с настройками:"
echo " - Тип протокола: VLESS"
echo " - Порт: $PROXY_PORT"
echo " - Слушать: 127.0.0.1"
echo " - Сертификат: Использовать существующий"
echo " - Путь к сертификату: /etc/letsencrypt/live/$MAIN_DOMAIN/fullchain.pem"
echo " - Путь к ключу: /etc/letsencrypt/live/$MAIN_DOMAIN/privkey.pem"
echo "5. Сохраните настройки и создайте пользователя"
echo ""
confirm_continue
# Шаг 8: Проверка конфигурации и запуск сервисов
log_info "Шаг 8: Проверка конфигурации и запуск сервисов..."
# Проверяем синтаксис конфигурации Nginx
if nginx -t; then
log_info "Конфигурация Nginx проверена успешно"
# Перезагружаем Nginx
systemctl reload nginx
sleep 2
if systemctl is-active --quiet nginx; then
log_info "Nginx успешно перезагружен"
else
log_error "Ошибка перезагрузки Nginx"
systemctl status nginx --no-pager
fi
else
log_error "Ошибка в конфигурации Nginx. Проверьте конфигурационные файлы."
exit 1
fi
# Финальный отчёт
echo ""
echo "================================================"
log_info "РАЗВЁРТЫВАНИЕ УСПЕШНО ЗАВЕРШЕНО!"
echo "================================================"
echo ""
echo "СЕРВИСЫ ДОСТУПНЫ ПО СЛЕДУЮЩИМ АДРЕСАМ:"
echo ""
echo "1. Веб-сайт:"
echo " URL: https://$WEB_SUBDOMAIN"
echo " Внутренний порт: $WEB_PORT"
echo ""
echo "2. Telegram MTProto прокси:"
echo " Сервер: $TG_SUBDOMAIN"
echo " Порт: 443"
echo " Секретный ключ: $MT_SECRET"
echo " Ссылка для подключения: tg://proxy?server=$TG_SUBDOMAIN&port=443&secret=$MT_SECRET"
echo ""
echo "3. 3x-ui панель управления:"
echo " Панель: http://ваш_сервер:2053"
echo " Прокси через Nginx: https://$PROXY_SUBDOMAIN"
echo " (Требуется ручная настройка инбаундов в панели)"
echo ""
echo "ТЕХНИЧЕСКАЯ ИНФОРМАЦИЯ:"
echo " - Все сервисы работают через SNI-роутинг на порту 443"
echo " - SSL-сертификаты автоматически обновляются (Certbot)"
echo " - Конфигурация Nginx: /etc/nginx/nginx.conf"
echo " - Сертификаты: /etc/letsencrypt/live/$MAIN_DOMAIN/"
echo " - Логи TeleMT: journalctl -u telemt -f"
echo ""
echo "ДЛЯ ПРОВЕРКИ РАБОТОСПОСОБНОСТИ ВЫПОЛНИТЕ:"
echo " curl -I https://$WEB_SUBDOMAIN"
echo " nginx -t"
echo " systemctl status telemt nginx"
echo ""
echo "================================================"
}
# Запуск основной функции
main