#!/bin/bash # ============================================================================= # 🌍 УНИВЕРСАЛЬНЫЙ СЕРВЕРНЫЙ КОМБАЙН v1.2.1 # Ubuntu/Debian/AlmaLinux/Rocky/CentOS/Fedora # ============================================================================= GREEN='\033[0;32m' RED='\033[0;31m' YELLOW='\033[1;33m' BLUE='\033[0;34m' PURPLE='\033[0;35m' NC='\033[0m' OS_ID="" OS_VERSION="" PKG_MGR="" SSH_SERVICE="" if [ "$EUID" -ne 0 ]; then echo "🚫 Запустите от root!" exit 1 fi detect_os() { if [ -f /etc/os-release ]; then . /etc/os-release OS_ID=$ID OS_VERSION=$VERSION_ID else OS_ID=$(uname -s | tr '[:upper:]' '[:lower:]') fi case $OS_ID in ubuntu|debian) PKG_MGR="apt" SSH_SERVICE="ssh" DOCKER_CMD="curl -fsSL https://get.docker.com | sh" ;; "almalinux"|"rocky"|"centos"|"fedora") PKG_MGR="dnf" SSH_SERVICE="sshd" DOCKER_CMD="dnf config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo && dnf install -y docker-ce docker-ce-cli containerd.io docker-compose-plugin" ;; *) echo "❌ Неподдерживаемая ОС: $OS_ID"; exit 1 ;; esac echo "🖥️ ОС: $OS_ID | Пакеты: $PKG_MGR | SSH: $SSH_SERVICE" } pause(){ read -p " Нажмите [Enter]..." fackEnterKey; } pkg_install() { echo "📦 Установка: $@"; $PKG_MGR update -y && $PKG_MGR install -y "$@"; } service_restart() { if command -v systemctl >/dev/null; then systemctl restart "$1" else service "$1" restart fi } service_enable() { if command -v systemctl >/dev/null; then systemctl enable --now "$1" else service "$1" start && chkconfig "$1" on 2>/dev/null || true fi } check_other_users() { awk -F: '$3 >= 1000 && $3 != 65534 {print $1}' /etc/passwd | wc -l } setup_timezone_interactive() { clear echo "${GREEN}🌍 ЧАСОВОЙ ПОЯС${NC}" echo "1) Europe/Moscow 2) Europe/Kiev 3) Asia/Almaty" echo "4) Asia/Yekaterinburg 5) Asia/Novosibirsk 6) Europe/Berlin" echo "7) America/New_York 8) Asia/Tokyo 0) Ручной ввод" echo "" read -p "► " TZ_CHOICE case $TZ_CHOICE in 1) TZ="Europe/Moscow";; 2) TZ="Europe/Kiev";; 3) TZ="Asia/Almaty";; 4) TZ="Asia/Yekaterinburg";; 5) TZ="Asia/Novosibirsk";; 6) TZ="Europe/Berlin";; 7) TZ="America/New_York";; 8) TZ="Asia/Tokyo";; 0) read -p "Зона (ex: Europe/Moscow): " TZ;; *) echo "Неверный выбор"; pause; return;; esac timedatectl set-timezone "$TZ" 2>/dev/null && timedatectl set-ntp true 2>/dev/null echo "${GREEN}✅ $TZ | $(date)${NC}" pause } install_base_pkgs() { echo "${GREEN}📦 БАЗОВЫЕ ПАКЕТЫ${NC}" case $PKG_MGR in apt) pkg_install mc htop zip wget curl git net-tools gnupg2 unzip ;; dnf) pkg_install mc htop zip wget curl git net-tools gnupg2 unzip ;; esac curl -L "https://github.com/dundee/gdu/releases/latest/download/gdu_linux_amd64.tgz" | tar xz chmod +x gdu_linux_amd64 && mv gdu_linux_amd64 /usr/local/bin/ echo "${GREEN}✅ gdu установлен${NC}" } create_user_full() { echo "${GREEN}👤 СОЗДАНИЕ ПОЛЬЗОВАТЕЛЯ${NC}" read -p "Имя: " UNAME echo "1) Только SSH ключ 🔑 2) Пароль + SSH 🔐" read -p "► " AUTH_METHOD useradd -m -s /bin/bash "$UNAME" usermod -aG wheel,sudo "$UNAME" 2>/dev/null || usermod -aG sudo "$UNAME" if [ "$AUTH_METHOD" == "1" ]; then echo "${GREEN}🔑 SSH ПУБЛИЧНЫЙ КЛЮЧ:${NC}" read -p "> " UKEY mkdir -p /home/$UNAME/.ssh echo "$UKEY" > /home/$UNAME/.ssh/authorized_keys passwd -l "$UNAME" echo "${GREEN}✅ Только SSH ключ${NC}" else read -s -p "🔐 Пароль: " PASS1; echo read -s -p "Повторить: " PASS2; echo [ "$PASS1" = "$PASS2" ] && echo "$UNAME:$PASS1" | chpasswd echo "${GREEN}✅ Пароль установлен${NC}" read -p "🔑 SSH ключ (опционально): " UKEY [ -n "$UKEY" ] && echo "$UKEY" > /home/$UNAME/.ssh/authorized_keys fi chown -R "$UNAME:$UNAME" /home/$UNAME/.ssh 2>/dev/null || true chmod 700 /home/$UNAME/.ssh 2>/dev/null || true chmod 600 /home/$UNAME/.ssh/authorized_keys 2>/dev/null || true echo "$UNAME ALL=(ALL) NOPASSWD: ALL" > "/etc/sudoers.d/${UNAME}" chmod 440 "/etc/sudoers.d/${UNAME}" echo "${GREEN}✅ $UNAME готов (sudo без пароля)${NC}" pause } setup_ssh_security() { clear echo "${RED}🔒 НАСТРОЙКА SSH БЕЗОПАСНОСТИ${NC}" USER_COUNT=$(check_other_users) if [ "$USER_COUNT" -eq 0 ]; then echo "${RED}🚫 ОШИБКА: Только root!${NC}" echo "${YELLOW}✅ Сначала пункт 3 → Создать пользователя${NC}" pause; return fi echo "${YELLOW}⚠️ Будет изменено:${NC}" echo " ✖ Вход root" echo " ✖ Пароли" echo " ✔ Только SSH ключи" echo "" read -p "ПРОДОЛЖИТЬ? (y/N): " CONFIRM [ "$CONFIRM" != "y" ] && { echo "Отменено."; pause; return; } SSHD_CONFIG="/etc/ssh/${SSH_SERVICE}_config" cp "$SSHD_CONFIG" "${SSHD_CONFIG}.bak.$(date +%Y%m%d_%H%M)" sed -i 's/^#*PasswordAuthentication.*/PasswordAuthentication no/' "$SSHD_CONFIG" sed -i 's/^#*PermitRootLogin.*/PermitRootLogin no/' "$SSHD_CONFIG" sed -i 's/^#*PubkeyAuthentication.*/PubkeyAuthentication yes/' "$SSHD_CONFIG" if command -v "${SSH_SERVICE}" >/dev/null && "${SSH_SERVICE}" -t 2>/dev/null; then service_restart "$SSH_SERVICE" echo "${GREEN}✅ SSH защищён!${NC}" else echo "${RED}❌ Ошибка конфига! Восстановление...${NC}" cp "${SSHD_CONFIG}.bak.$(date +%Y%m%d_%H%M)" "$SSHD_CONFIG" service_restart "$SSH_SERVICE" fi pause } install_unattended_upgrades() { echo "${GREEN}🔄 АВТООБНОВЛЕНИЯ БЕЗОПАСНОСТИ${NC}" if [[ "$OS_ID" != "ubuntu" && "$OS_ID" != "debian" ]]; then echo "${YELLOW}⚠️ Только Ubuntu/Debian${NC}" pause; return fi pkg_install unattended-upgrades needrestart cat > /etc/apt/apt.conf.d/20auto-upgrades << 'EOF' APT::Periodic::Update-Package-Lists "1"; APT::Periodic::Unattended-Upgrade "1"; EOF cat > /etc/apt/apt.conf.d/50unattended-upgrades << 'EOF' Unattended-Upgrade::Allowed-Origins { "${distro_id}:${distro_codename}-security"; "${distro_id}:${distro_codename}-updates"; }; Unattended-Upgrade::Mail "root"; Unattended-Upgrade::Remove-Unused-Dependencies "true"; Unattended-Upgrade::Automatic-Reboot "false"; EOF dpkg-reconfigure -plow unattended-upgrades service_enable unattended-upgrades echo "${GREEN}✅ НАСТРОЕНО:${NC}" echo " 📅 Обновления: ежедневно" echo " 🔒 Только: security + updates" echo " 📋 Логи: /var/log/unattended-upgrades/" echo " ⚠️ Авто-ребут: отключен" pause } install_audit_with_rotation() { echo "${GREEN}🔒 АУДИТ + РОТАЦИЯ ЛОГОВ${NC}" case $PKG_MGR in apt) pkg_install auditd audispd-plugins logrotate ;; dnf) pkg_install audit policycoreutils-python-utils logrotate ;; esac cat > /etc/audit/rules.d/server-setup.rules << 'EOF' -w /etc/sudoers -p wa -k sudoers -w /etc/passwd -p wa -k identity -w /etc/group -p wa -k identity -w /etc/ssh/sshd_config -p wa -k ssh_config -a always,exit -F arch=b64 -S execve -k process_exec EOF if grep -q "^max_log_file" /etc/audit/auditd.conf 2>/dev/null; then sed -i 's/^max_log_file.*/max_log_file = 50/' /etc/audit/auditd.conf else echo 'max_log_file = 50' >> /etc/audit/auditd.conf fi echo 'num_logs = 8' >> /etc/audit/auditd.conf service_restart auditd 2>/dev/null || true service_enable auditd 2>/dev/null || true echo "${GREEN}✅ Аудит: /var/log/audit/audit.log${NC}" pause } status_all() { clear echo "${GREEN}📊 СТАТУС СИСТЕМЫ${NC}" echo "==============================================" echo "🔄 Unattended: $(systemctl is-active unattended-upgrades 2>/dev/null || echo 'Неактивен')" echo "🔒 SSH: $(systemctl is-active $SSH_SERVICE 2>/dev/null || echo 'Неактивен')" echo "🛡️ Fail2Ban: $(systemctl is-active fail2ban 2>/dev/null || echo 'Неактивен')" echo "📊 Auditd: $(systemctl is-active auditd 2>/dev/null || echo 'Неактивен')" echo "🐳 Docker: $(systemctl is-active docker 2>/dev/null || echo 'Неактивен')" echo "==============================================" echo "👥 Пользователей: $(check_other_users)" echo "📅 Время: $(date)" pause } install_smb_interactive() { echo "${GREEN}🗄️ SAMBA/SMB СЕРВЕР${NC}" pkg_install samba smbclient cifs-utils # Создание папок для шар mkdir -p /srv/samba while true; do echo "" echo "${YELLOW}➕ НОВАЯ ШАРА${NC}" read -p "Путь к папке (ex: /srv/samba/docs): " SHARE_PATH [ -z "$SHARE_PATH" ] && break read -p "Имя шары (ex: docs): " SHARE_NAME read -p "Пользователи (ex: user1,user2 или guest): " SHARE_USERS # Создание папки mkdir -p "$SHARE_PATH" if [[ "$SHARE_USERS" == *"guest"* ]]; then chmod 777 "$SHARE_PATH" GUEST_OK="yes" VALID_USERS="" else chmod 770 "$SHARE_PATH" GUEST_OK="no" VALID_USERS="valid users = $SHARE_USERS" fi # Добавление в smb.conf cat >> /etc/samba/smb.conf << EOF [${SHARE_NAME}] path = $SHARE_PATH browsable = yes writable = yes guest ok = $GUEST_OK read only = no create mask = 0664 directory mask = 0775 $VALID_USERS EOF echo "${GREEN}✅ Шара '$SHARE_NAME' → '$SHARE_PATH'${NC}" done # Базовый smb.conf cat > /etc/samba/smb.conf << 'EOF' [global] workgroup = WORKGROUP server string = %h server (Samba, v5.2) security = user map to guest = bad user socket options = TCP_NODELAY IPTOS_LOWDELAY EOF service_restart smbd nmbd service_enable smbd nmbd echo "${GREEN}✅ SMB перезапущен!${NC}" echo "📡 IP: $(hostname -I | awk '{print $1}')" echo "📁 Подключение: //IP/share_name" pause } prepare_dist_upgrade() { echo -e "${YELLOW}🧹 ПОДГОТОВКА СИСТЕМЫ К ОБНОВЛЕНИЮ${NC}" # 1. Обновляем текущие пакеты до упора echo "📦 Шаг 1: Полное обновление текущих пакетов..." $PKG_MGR update -y && $PKG_MGR upgrade -y && $PKG_MGR dist-upgrade -y 2>/dev/null || $PKG_MGR full-upgrade -y # 2. Чистка старых ядер и конфигов echo "🧹 Шаг 2: Удаление неиспользуемых зависимостей..." $PKG_MGR autoremove --purge -y $PKG_MGR autoclean -y # 3. Проверка битых пакетов if [[ "$PKG_MGR" == "apt" ]]; then echo "🔍 Шаг 3: Проверка целостности пакетов..." dpkg --configure -a apt install -f -y fi echo -e "${GREEN}✅ Система готова к апгрейду!${NC}" echo -e "${YELLOW}⚠️ РЕКОМЕНДУЕТСЯ ПЕРЕЗАГРУЗКА ПЕРЕД СЛЕДУЮЩИМ ШАГОМ!${NC}" pause } do_major_upgrade() { clear echo -e "${RED}⚠️ ВНИМАНИЕ: ОПАСНАЯ ОПЕРАЦИЯ!${NC}" echo "Эта функция обновит вашу ОС до следующей мажорной версии." echo "Убедитесь, что у вас есть БЭКАП данных." read -p "Вы уверены, что хотите продолжить? (y/N): " CONFIRM [ "$CONFIRM" != "y" ] && return case $OS_ID in ubuntu) echo "🚀 Запуск Ubuntu Release Upgrade..." pkg_install update-manager-core # -d для разработки (если релиз новый), убираем для стабильных do-release-upgrade -f DistUpgradeViewNonInteractive ;; debian) CURRENT_CODENAME=$(lsb_release -sc 2>/dev/null || cat /etc/debian_version | cut -d. -f1) echo "📝 Текущий кодовое имя: $CURRENT_CODENAME" read -p "Введите кодовое имя СЛЕДУЮЩЕГО релиза (например, bookworm): " NEXT_CODENAME # Замена репозиториев sed -i "s/$CURRENT_CODENAME/$NEXT_CODENAME/g" /etc/apt/sources.list sed -i "s/$CURRENT_CODENAME/$NEXT_CODENAME/g" /etc/apt/sources.list.d/*.list 2>/dev/null apt update apt upgrade --without-new-pkgs -y apt full-upgrade -y ;; almalinux|rocky) echo "🚀 Использование инструмента ELevate (Leapp)..." pkg_install network-scripts # часто нужно для leapp curl -O https://repo.almalinux.org/elevate/elevate-release-latest-el$(echo $OS_VERSION | cut -d. -f1).noarch.rpm rpm -Uvh elevate-release-latest-el*.rpm pkg_install leapp-upgrade leapp-data-almalinux # или rocky echo "🔍 Запуск проверки совместимости..." leapp preupgrade echo -e "${YELLOW}Проверьте отчет: /var/log/leapp/leapp-report.txt${NC}" echo "Для финала запустите: leapp upgrade" ;; *) echo "❌ Автоматический апгрейд для $OS_ID пока не поддерживается." ;; esac pause } setup_disks_advanced() { clear echo "${GREEN}💾 НОВЫЕ ДИСКИ${NC}" # Список дисков с размерами echo "==============================================" echo "ДИСКИ (непримонтированные):" lsblk -dno NAME,SIZE,TYPE,ROTA | grep disk | while read name size type rota; do disk="/dev/$name" if ! mount | grep -q "$disk"; then echo " 📦 $disk [$size] ($(blockdev --getsize64 "$disk" | numfmt --to=iec))" fi done echo "==============================================" read -p "Диск для настройки (/dev/sdb): " SELECTED_DISK if [ -z "$SELECTED_DISK" ] || [ ! -b "$SELECTED_DISK" ]; then echo "${RED}❌ Диск не найден${NC}" pause return fi echo "" echo "${YELLOW}⚙️ НАСТРОЙКА $SELECTED_DISK${NC}" echo "1) ext4 (Linux)" echo "2) xfs (RHEL/CentOS)" echo "3) btrfs (современный)" echo "4) ntfs (Windows совместимость)" read -p "Файловая система: " FS_CHOICE case $FS_CHOICE in 1) FS="ext4";; 2) FS="xfs";; 3) FS="btrfs";; 4) FS="ntfs";; *) echo "Отмена"; return;; esac # Форматирование echo "${YELLOW}⚠️ ВНИМАНИЕ: Данные будут УДАЛЕНЫ!${NC}" read -p "ПРОДОЛЖИТЬ? (y/N): " CONFIRM [ "$CONFIRM" != "y" ] && return parted "$SELECTED_DISK" --script mklabel gpt parted "$SELECTED_DISK" --script mkpart primary "$FS" 1MiB 100% partprobe "$SELECTED_DISK" sleep 3 PARTITION="${SELECTED_DISK}1" case $FS in ext4) mkfs.ext4 -F "$PARTITION" ;; xfs) mkfs.xfs -f "$PARTITION" ;; btrfs) mkfs.btrfs -f "$PARTITION" ;; ntfs) mkfs.ntfs -Q "$PARTITION" ;; esac # Монтирование echo "" read -p "Точка монтирования (ex: /srv/data): " MOUNT_POINT MOUNT_POINT=${MOUNT_POINT:-/srv/data} mkdir -p "$MOUNT_POINT" mount "$PARTITION" "$MOUNT_POINT" # FSTAB UUID=$(blkid -s UUID -o value "$PARTITION") case $FS in ntfs) FSTAB_OPTS="defaults,uid=1000,gid=1000" ;; *) FSTAB_OPTS="defaults" ;; esac echo "UUID=$UUID $MOUNT_POINT $FS $FSTAB_OPTS 0 2" >> /etc/fstab # Проверка mount -a df -h "$MOUNT_POINT" echo "${GREEN}✅ $PARTITION → $MOUNT_POINT ($FS)${NC}" echo "📝 Добавлено в /etc/fstab" pause } install_fail2ban_interactive() { echo "${GREEN}🛡️ FAIL2BAN — ИНТЕРАКТИВНАЯ НАСТРОЙКА${NC}" pkg_install fail2ban # Остановка если запущен systemctl stop fail2ban 2>/dev/null || true # Бэкап cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.conf.bak 2>/dev/null || true clear echo "${YELLOW}⚙️ ОСНОВНЫЕ НАСТРОЙКИ${NC}" read -p "Время бана (по умолчанию 1h): " BANTIME BANTIME=${BANTIME:-3600} read -p "Макс. попыток (по умолчанию 5): " MAXRETRY MAXRETRY=${MAXRETRY:-5} read -p "Время проверки попыток (по умолчанию 10m): " FINDTIME FINDTIME=${FINDTIME:-600} echo "" echo "${YELLOW}🤝 IP КОТОРЫЕ НЕ БАНИТЬ (через запятую):${NC}" echo "Примеры: 192.168.1.0/24, 10.0.0.0/8" read -p "Белый список: " IGNOREIP IGNOREIP=${IGNOREIP:-"127.0.0.1/8 ::1"} # SSH Jail настройки echo "" echo "${GREEN}🔒 SSH ЗАЩИТА${NC}" echo "1) Только стандартный порт 22" echo "2) Несколько портов (22,2222)" echo "3) Ручной ввод портов" read -p "► " SSH_PORT_CHOICE case $SSH_PORT_CHOICE in 1) SSH_PORT="ssh" ;; 2) SSH_PORT="22,2222" ;; 3) read -p "Порты (через запятую): " SSH_PORT ;; *) SSH_PORT="ssh" ;; esac # Дополнительные сервисы echo "" echo "${YELLOW}➕ ДОПОЛНИТЕЛЬНЫЕ СЕРВИСЫ${NC}" echo "1) Только SSH" echo "2) SSH + Nginx/Apache" echo "3) SSH + все популярные" read -p "► " SERVICES_CHOICE case $SERVICES_CHOICE in 2) SERVICES="sshd nginx-http-auth nginx-botsearch" ;; 3) SERVICES="sshd nginx-http-auth nginx-botsearch apache-auth dropbear" ;; *) SERVICES="sshd" ;; esac # Создание jail.local cat > /etc/fail2ban/jail.local << EOF [DEFAULT] bantime = $BANTIME findtime = $FINDTIME maxretry = $MAXRETRY backend = systemd ignoreip = $IGNOREIP EOF # Добавление SSH cat >> /etc/fail2ban/jail.local << EOF [sshd] enabled = true port = $SSH_PORT logpath = /var/log/auth.log backend = systemd EOF # Дополнительные сервисы for service in $SERVICES; do cat >> /etc/fail2ban/jail.local << EOF [$service] enabled = true EOF done # Фикс auth.log [ ! -f /var/log/auth.log ] && ln -sf /var/log/syslog /var/log/auth.log # Тест и запуск if fail2ban-client -t 2>/dev/null; then systemctl daemon-reload service_enable fail2ban echo "${GREEN}✅ Fail2Ban настроен и запущен!${NC}" echo "" echo "📊 АКТИВНЫЕ JAIL:" fail2ban-client status | grep -E '^[a-z]' | sed 's/^/ /' echo "" echo "🔍 Подробный статус:" echo " fail2ban-client status sshd" echo " fail2ban-client status" else echo "${RED}❌ Ошибка конфигурации!${NC}" echo "📋 Проверьте:" echo " fail2ban-client -t" echo " journalctl -u fail2ban -xe" fi pause } # --- ГЛАВНОЕ МЕНЮ --- detect_os while true; do clear printf "==============================================\n" printf " 🚀 SERVER ULTIMATE v1.2.1 (%s %s) 🚀\n" "$OS_ID" "$OS_VERSION" printf "==============================================\n" printf "1) 📛 Hostname \n" printf "2) 🌍 Часовой пояс + база \n" printf "3) 👤 Пользователь \n" printf "4) 🔒 SSH безопасность \n" printf "5) 📊 Аудит \n" printf "6) 🐳 Docker \n" printf "7) 🌐 WireGuard \n" printf "8) 🔐 OpenVPN \n" printf "9) 📈 Мониторинг \n" printf "10) 🛡️ Fail2Ban \n" printf "11) 🧹 Очистка \n" printf "12) 🔄 Автообновления \n" printf "13) 🗄️ SAMBA (шары+пользователи) \n" printf "14) 💾 Диски (выбор+форматирование)\n" printf "15) 📈 Расширение дисков \n" printf "16) 🛠️ Подготовка к Update \n" printf "17 🆙 Upgrade релиза. \n" printf "S) 📊 Статус \n" printf "0) ❌ Выход \n" printf "==============================================\n" read -p "► " opt case $opt in 1) read -p "Имя хоста: " HN; hostnamectl set-hostname "$HN" 2>/dev/null || hostname "$HN"; systemctl restart systemd-hostnamed 2>/dev/null || true; pause ;; 2) setup_timezone_interactive; install_base_pkgs ;; 3) create_user_full ;; 4) setup_ssh_security ;; 5) install_audit_with_rotation ;; 6) $DOCKER_CMD; service_enable docker; pause ;; 7) curl -fsSL https://git.io/wireguard -o wg.sh && bash wg.sh; pause ;; 8) curl -O https://raw.githubusercontent.com/angristan/openvpn-install/master/openvpn-install.sh && chmod +x openvpn-install.sh && ./openvpn-install.sh; pause ;; 9) pkg_install glances htop; pause ;; 10) install_fail2ban_interactive ;; 11) $PKG_MGR autoremove -y && $PKG_MGR autoclean -y; pause ;; 12) install_unattended_upgrades ;; 13) install_smb_interactive ;; 14) setup_disks_advanced ;; 15) extend_disk_space ;; 16) prepare_dist_upgrade ;; 17) do_major_upgrade ;; [Ss]) status_all ;; 0) break ;; *) echo "❌ Неверный пункт!"; sleep 1 ;; esac done echo "🎉 Настройка завершена! Сервер готов к работе!"