From 97031d15f2051c6e4fbf64ee59e5456fdcb51c78 Mon Sep 17 00:00:00 2001 From: smolkik-code Date: Sat, 17 Jan 2026 13:12:11 +0700 Subject: [PATCH] alpha 0.1 --- bit/server-rollback | 7 + config/main.conf | 2 + ib.sh | 642 -------------------------------------------- install.sh | 12 + lib/backup.sh | 23 ++ lib/colors.sh | 4 + lib/fail2ban.sh | 21 ++ lib/os-detect.sh | 21 ++ lib/samba.sh | 52 ++++ lib/ssh.sh | 48 ++++ lib/sysctl.sh | 13 + lib/users.sh | 44 +++ lib/utils.sh | 20 ++ menu.sh | 18 ++ server.sh | 11 + 15 files changed, 296 insertions(+), 642 deletions(-) create mode 100644 bit/server-rollback create mode 100644 config/main.conf delete mode 100644 ib.sh create mode 100644 install.sh create mode 100644 lib/backup.sh create mode 100644 lib/colors.sh create mode 100644 lib/fail2ban.sh create mode 100644 lib/os-detect.sh create mode 100644 lib/samba.sh create mode 100644 lib/ssh.sh create mode 100644 lib/sysctl.sh create mode 100644 lib/users.sh create mode 100644 lib/utils.sh create mode 100644 menu.sh create mode 100644 server.sh diff --git a/bit/server-rollback b/bit/server-rollback new file mode 100644 index 0000000..6f7214a --- /dev/null +++ b/bit/server-rollback @@ -0,0 +1,7 @@ +#!/bin/bash +BASE="/var/backups/server-ultimate" +select D in "$BASE"/*; do + cp -av "$D"/* / + systemctl restart sshd smbd fail2ban + break +done diff --git a/config/main.conf b/config/main.conf new file mode 100644 index 0000000..2dfc20b --- /dev/null +++ b/config/main.conf @@ -0,0 +1,2 @@ +BACKUP_DIR="/var/backups/server-ultimate" +LOG_FILE="/opt/server-ultimate/logs/server.log" diff --git a/ib.sh b/ib.sh deleted file mode 100644 index a707e52..0000000 --- a/ib.sh +++ /dev/null @@ -1,642 +0,0 @@ -#!/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 "🎉 Настройка завершена! Сервер готов к работе!" diff --git a/install.sh b/install.sh new file mode 100644 index 0000000..bdcf71b --- /dev/null +++ b/install.sh @@ -0,0 +1,12 @@ +#!/bin/bash +set -e + +echo "🔧 Установка server-ultimate" + +mkdir -p /opt/server-ultimate/{lib,config,logs} +cp -r ./* /opt/server-ultimate/ + +chmod +x /opt/server-ultimate/server.sh +ln -sf /opt/server-ultimate/server.sh /usr/local/bin/server + +echo "✅ Установлено. Запуск: server" diff --git a/lib/backup.sh b/lib/backup.sh new file mode 100644 index 0000000..8e62235 --- /dev/null +++ b/lib/backup.sh @@ -0,0 +1,23 @@ +source /opt/server-ultimate/config/main.conf + +backup_create() { + local COMP="$1"; shift + local FILES="$@" + + TS="$(date +%F_%H-%M-%S)" + DEST="$BACKUP_DIR/$COMP/$TS" + + mkdir -p "$DEST" + for f in $FILES; do + [ -f "$f" ] && cp -a "$f" "$DEST/" + done + + echo "$DEST" +} + +backup_restore() { + local COMP="$1" + ls "$BACKUP_DIR/$COMP" + read -p "Snapshot: " TS + cp -av "$BACKUP_DIR/$COMP/$TS"/* / +} diff --git a/lib/colors.sh b/lib/colors.sh new file mode 100644 index 0000000..6e9d8c9 --- /dev/null +++ b/lib/colors.sh @@ -0,0 +1,4 @@ +GREEN='\033[0;32m' +RED='\033[0;31m' +YELLOW='\033[1;33m' +NC='\033[0m' diff --git a/lib/fail2ban.sh b/lib/fail2ban.sh new file mode 100644 index 0000000..de46230 --- /dev/null +++ b/lib/fail2ban.sh @@ -0,0 +1,21 @@ +setup_fail2ban() { + $PKG install -y fail2ban + CONF="/etc/fail2ban/jail.local" + SNAP=$(backup_create fail2ban "$CONF") + + cat > "$CONF" < "$CONF" <> "$CONF" <> "$CONF" + + # Пароль — по выбору + if [[ "$DISABLE_PASS" != "y" ]]; then + sed -i 's/^PasswordAuthentication no/PasswordAuthentication yes/' "$CONF" + fi + + if sshd -t; then + systemctl restart sshd + log "SSH security профиль применён" + else + err "Ошибка SSH → rollback" + cp "$SNAP/sshd_config" "$CONF" + systemctl restart sshd + fi + + pause +} diff --git a/lib/sysctl.sh b/lib/sysctl.sh new file mode 100644 index 0000000..c38a7d9 --- /dev/null +++ b/lib/sysctl.sh @@ -0,0 +1,13 @@ +harden_sysctl() { + CONF="/etc/sysctl.d/99-hardening.conf" + SNAP=$(backup_create sysctl "$CONF") + + cat > "$CONF" </dev/null && { err "Уже существует"; pause; return; } + + echo "Способ входа:" + echo "1) 🔑 Только ключ" + echo "2) 🔐 Пароль + ключ" + echo "3) 🔐 Только пароль" + read -p "> " MODE + + useradd -m -s /bin/bash "$USER" + mkdir -p /home/$USER/.ssh + chmod 700 /home/$USER/.ssh + + case "$MODE" in + 1) + read -p "Вставь публичный ключ: " KEY + echo "$KEY" > /home/$USER/.ssh/authorized_keys + chmod 600 /home/$USER/.ssh/authorized_keys + passwd -l "$USER" + ;; + 2) + passwd "$USER" + read -p "Публичный ключ (Enter чтобы пропустить): " KEY + [[ -n "$KEY" ]] && echo "$KEY" > /home/$USER/.ssh/authorized_keys + ;; + 3) + passwd "$USER" + ;; + *) + userdel -r "$USER" + err "Отмена" + pause + return + ;; + esac + + chown -R $USER:$USER /home/$USER/.ssh + usermod -aG sudo "$USER" + + log "Создан пользователь $USER" + pause +} diff --git a/lib/utils.sh b/lib/utils.sh new file mode 100644 index 0000000..d6c2f2b --- /dev/null +++ b/lib/utils.sh @@ -0,0 +1,20 @@ +require_root() { + [[ $EUID -ne 0 ]] && { echo "❌ Запусти от root"; exit 1; } +} + +log() { + echo "[+] $1" + echo "$(date) | $1" >> "$LOG_FILE" +} + +warn() { + echo "[!] $1" +} + +err() { + echo "[x] $1" +} + +pause() { + read -p "Нажмите Enter..." +} diff --git a/menu.sh b/menu.sh new file mode 100644 index 0000000..fd5f0e7 --- /dev/null +++ b/menu.sh @@ -0,0 +1,18 @@ +main_menu() { + while true; do + clear + echo "🛡 SERVER-ULTIMATE v2.1" + echo "1) 👤 Создать пользователя" + echo "2) 🔒 Настроить SSH" + echo "3) ♻ Rollback конфигов" + echo "0) Выход" + read -p "> " C + + case "$C" in + 1) create_user ;; + 2) secure_ssh ;; + 3) backup_restore ssh ;; + 0) exit ;; + esac + done +} diff --git a/server.sh b/server.sh new file mode 100644 index 0000000..4cbf5f2 --- /dev/null +++ b/server.sh @@ -0,0 +1,11 @@ +#!/bin/bash + +BASE="/opt/server-ultimate" +source "$BASE/lib/utils.sh" +source "$BASE/lib/backup.sh" +source "$BASE/lib/users.sh" +source "$BASE/lib/ssh.sh" +source "$BASE/lib/menu.sh" + +require_root +main_menu