1
0
Pārlūkot izejas kodu

Merge branch 'master' of u23-27burdyko/EASvZI into master

ypv 2 dienas atpakaļ
vecāks
revīzija
2ff9ff891d

BIN
Лекции/2.4.510_Hardening_Checklist_for_Linux/burdyko.jpg


+ 30 - 0
Лекции/2.4.510_Hardening_Checklist_for_Linux/burdyko.md

@@ -0,0 +1,30 @@
+# Hardening Checklist for Linux
+![](burdyko.jpg)
+
+
+Введение
+Hardening (ужесточение безопасности) — это процесс уменьшения поверхности атаки операционной системы. Чеклист представляет собой набор конкретных действий, которые должны быть выполнены после установки Linux. В отличие от общих руководств, данный чеклист ориентирован на серверные среды и рабочие станции с высокими требованиями к конфиденциальности.
+
+1. Обновление системы и управление пакетами
+Первым шагом всегда идёт синхронизация репозиториев и установка критических обновлений. Используйте apt update && apt upgrade (Debian/Ubuntu) или dnf update (RHEL). Необходимо настроить автоматические обновления безопасности через unattended-upgrades или dnf-automatic. Удалите неиспользуемые пакеты: apt autoremove, а также удалите компиляторы (gcc, make), если они не нужны для повседневной работы.
+
+2. Управление учётными записями и паролями
+Отключите вход для root через SSH: в файле /etc/ssh/sshd_config установите PermitRootLogin no. Создайте обычного пользователя с правами sudo. Настройте политику паролей через pam_pwquality.so (минимальная длина 12 символов, включая цифры и спецсимволы). Используйте fail2ban для блокировки IP после нескольких неудачных попыток входа. Обязательно проверьте отсутствие пользователей с пустым паролем: awk -F: '($2 == "") {print}' /etc/shadow.
+
+3. Настройка межсетевого экрана и защита сети
+Включите и настройте ufw (Uncomplicated Firewall) или nftables. Пример политики: запретить всё, разрешить SSH (порт 22) и HTTP/HTTPS (80,443). Запретите переадресацию IPv4, если сервер не является маршрутизатором: sysctl -w net.ipv4.ip_forward=0. Отключите неиспользуемые сетевые службы, например, rpcbind, cups. Также рекомендуется включить защиту от спуфинга: net.ipv4.conf.all.rp_filter=1.
+
+4. Контроль целостности файлов и аудит
+Установите AIDE (Advanced Intrusion Detection Environment) или Tripwire. Инициализируйте базу данных эталонных хеш-сумм для критичных файлов (/bin, /etc, /sbin). Настройте ежедневный запуск проверки через cron. Включите системный аудит через auditd для мониторинга изменений /etc/passwd, /etc/sudoers, а также неудачных попыток доступа. Регулярно анализируйте логи через journalctl и logwatch.
+
+5. Ограничение ресурсов и удаление привилегий
+Используйте ulimit для предотвращения fork-бомб и DoS-атак: ограничьте максимальное количество процессов для пользователей. Настройте AppArmor (Ubuntu/Debian) или SELinux (RHEL/Fedora) в режиме enforcing. Для служб, работающих от root, создавайте отдельные непривилегированные пользователей через systemd (опции User= и Group=). Запретите использование ядерных модулей, если они не нужны, добавив install <модуль> /bin/true в /etc/modprobe.d/.
+
+6. Проверка открытых портов и процессов
+Регулярно (ежедневно) выполняйте ss -tulpn и netstat -tulpn, чтобы выявить подозрительные службы, слушающие на неожиданных портах. Используйте lsof -i для идентификации процессов, открывших сетевые сокеты. Интегрируйте эти проверки в скрипты мониторинга (Nagios, Zabbix). Любой неизвестный процесс, потребляющий аномально много CPU или памяти, должен быть расследован с помощью chkrootkit или rkhunter.
+
+7. Резервное копирование и безопасное хранение
+Завершающий элемент чеклиста — настройка автоматического резервного копирования конфигурационных файлов (/etc, /var/log, домашние каталоги администраторов). Используйте rsync с ssh-ключами без пароля (но с ограничением команд в authorized_keys). Храните резервные копии на отдельном зашифрованном носителе или в S3 с серверным шифрованием. Проверяйте восстановление хотя бы раз в квартал.
+
+Заключение
+Применение данного чеклиста снижает риск компрометации системы примерно на 70-80% по статистике CIS. Важно помнить, что hardening — это не разовая акция, а непрерывный процесс: чеклист должен пересматриваться и дополняться после каждого обновления дистрибутива или изменения архитектуры приложения.

+ 599 - 0
Лекции/2.4.510_Hardening_Checklist_for_Linux/burdyko_igra.html

@@ -0,0 +1,599 @@
+<!DOCTYPE html>
+<html lang="ru">
+<head>
+    <meta charset="UTF-8">
+    <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
+    <title>Linux Hardening Challenge — Аудит безопасности</title>
+    <style>
+        * {
+            box-sizing: border-box;
+            user-select: none; /* better terminal feel, but text can be selected */
+        }
+
+        body {
+            background: linear-gradient(145deg, #0a0f1a 0%, #0c111c 100%);
+            font-family: 'Courier New', 'Fira Code', 'JetBrains Mono', monospace;
+            display: flex;
+            justify-content: center;
+            align-items: center;
+            min-height: 100vh;
+            margin: 0;
+            padding: 20px;
+        }
+
+        /* game container */
+        .game-container {
+            max-width: 1300px;
+            width: 100%;
+            background: #0b0e14;
+            border-radius: 28px;
+            box-shadow: 0 20px 40px rgba(0, 0, 0, 0.6), inset 0 1px 0 rgba(255,255,255,0.05);
+            overflow: hidden;
+            border: 1px solid #2a2f3f;
+        }
+
+        /* header: scene & progress */
+        .game-header {
+            background: #070a10;
+            padding: 16px 24px;
+            border-bottom: 1px solid #252a36;
+            display: flex;
+            justify-content: space-between;
+            flex-wrap: wrap;
+            gap: 12px;
+        }
+
+        .scene-badge {
+            background: #1e2433;
+            padding: 6px 14px;
+            border-radius: 60px;
+            font-weight: bold;
+            font-size: 0.85rem;
+            color: #8fbcbb;
+            letter-spacing: 0.5px;
+            border-left: 3px solid #88c0d0;
+        }
+
+        .progress {
+            background: #11161f;
+            padding: 6px 14px;
+            border-radius: 40px;
+            font-size: 0.85rem;
+            color: #d8dee9;
+        }
+
+        .progress span {
+            color: #a3be8c;
+            font-weight: bold;
+        }
+
+        /* main content area: terminal + description */
+        .terminal-panel {
+            display: flex;
+            flex-direction: row;
+            flex-wrap: wrap;
+            padding: 24px;
+            gap: 24px;
+        }
+
+        .terminal {
+            flex: 2;
+            min-width: 280px;
+            background: #01040c;
+            border-radius: 20px;
+            border: 1px solid #2b3245;
+            box-shadow: inset 0 0 15px rgba(0,0,0,0.5), 0 5px 10px rgba(0,0,0,0.3);
+            overflow: hidden;
+        }
+
+        .terminal-header {
+            background: #191e2a;
+            padding: 12px 18px;
+            font-size: 0.85rem;
+            color: #bbc2cf;
+            border-bottom: 1px solid #2e3548;
+            display: flex;
+            gap: 8px;
+            align-items: center;
+        }
+
+        .terminal-dot {
+            width: 12px;
+            height: 12px;
+            border-radius: 50%;
+            background: #ec5f67;
+            display: inline-block;
+        }
+        .terminal-dot.yellow { background: #f9ae58; }
+        .terminal-dot.green { background: #8cc570; }
+
+        .terminal-body {
+            padding: 20px;
+            font-family: 'Courier New', monospace;
+            background: #01040c;
+            min-height: 380px;
+            color: #d8dee9;
+            font-size: 0.9rem;
+            line-height: 1.45;
+            white-space: pre-wrap;
+            word-break: break-word;
+        }
+
+        .command-line {
+            margin-top: 16px;
+            background: #0a0f17;
+            border-radius: 14px;
+            padding: 12px;
+            display: flex;
+            align-items: center;
+            gap: 8px;
+            flex-wrap: wrap;
+            border: 1px solid #2a3143;
+        }
+
+        .prompt {
+            color: #8fbcbb;
+            font-weight: bold;
+            background: #121724;
+            padding: 6px 10px;
+            border-radius: 12px;
+            font-size: 0.85rem;
+        }
+
+        .command-input {
+            flex: 1;
+            background: #03060c;
+            border: 1px solid #2e3a4e;
+            color: #e5e9f0;
+            padding: 8px 12px;
+            border-radius: 20px;
+            font-family: monospace;
+            font-size: 0.9rem;
+            outline: none;
+        }
+
+        .command-input:focus {
+            border-color: #88c0d0;
+            box-shadow: 0 0 5px #5e81ac;
+        }
+
+        button {
+            background: #2e3a48;
+            border: none;
+            padding: 8px 18px;
+            border-radius: 26px;
+            font-family: monospace;
+            font-weight: bold;
+            color: #e5e9f0;
+            cursor: pointer;
+            transition: 0.1s linear;
+            font-size: 0.8rem;
+        }
+
+        button:hover {
+            background: #434f62;
+            transform: scale(0.97);
+        }
+
+        .action-buttons {
+            flex: 1;
+            min-width: 260px;
+            background: #0e121c;
+            border-radius: 24px;
+            border: 1px solid #262e3f;
+            padding: 18px;
+        }
+
+        .action-title {
+            font-size: 1rem;
+            font-weight: bold;
+            color: #81a1c1;
+            margin-bottom: 14px;
+            border-left: 3px solid #88c0d0;
+            padding-left: 12px;
+        }
+
+        .action-list {
+            display: flex;
+            flex-direction: column;
+            gap: 12px;
+            margin-bottom: 24px;
+        }
+
+        .action-btn {
+            background: #191f2b;
+            text-align: left;
+            padding: 12px 14px;
+            border-radius: 18px;
+            font-size: 0.8rem;
+            width: 100%;
+            box-shadow: 0 1px 2px black;
+        }
+
+        .message-area {
+            background: #05080f;
+            border-radius: 18px;
+            padding: 12px;
+            font-size: 0.8rem;
+            color: #cbd5e6;
+            border-top: 1px solid #2c3347;
+            margin-top: 12px;
+        }
+
+        .warning {
+            color: #f0a86e;
+        }
+        .success {
+            color: #a3be8c;
+        }
+        .error {
+            color: #ec5f67;
+        }
+        hr {
+            border-color: #252c3b;
+            margin: 10px 0;
+        }
+
+        @media (max-width: 780px) {
+            .terminal-panel { flex-direction: column; }
+            .command-line { flex-direction: column; align-items: stretch; }
+        }
+    </style>
+</head>
+<body>
+<div class="game-container" id="gameRoot">
+    <div class="game-header">
+        <div class="scene-badge" id="sceneName">Сцена 1: Первое подключение</div>
+        <div class="progress">Статус: <span id="progressStatus">🔐 0/6</span></div>
+    </div>
+    <div class="terminal-panel">
+        <div class="terminal">
+            <div class="terminal-header">
+                <span class="terminal-dot"></span><span class="terminal-dot yellow"></span><span class="terminal-dot green"></span>
+                <span style="margin-left: 8px;">admin@hardening:~</span>
+            </div>
+            <div class="terminal-body" id="terminalOutput">
+                > Добро пожаловать в Hardening Challenge.<br>
+                > Выполняйте команды и используйте действия.<br>
+                > Введите <span class="success">help</span> для списка команд.<br>
+                > root@secured-server:~# 
+            </div>
+            <div class="command-line">
+                <span class="prompt" id="promptUser">admin@lab:~$</span>
+                <input type="text" id="cmdInput" class="command-input" placeholder="введите команду..." autofocus>
+                <button id="runCmdBtn">⏎ Выполнить</button>
+            </div>
+        </div>
+        <div class="action-buttons">
+            <div class="action-title">📋 ДОСТУПНЫЕ ДЕЙСТВИЯ (сцена)</div>
+            <div id="dynamicActions" class="action-list">
+                <!-- динамические кнопки сценария -->
+            </div>
+            <div class="message-area" id="gameMessage">
+                💡 Используй команды или кнопки. Пройди все 6 сцен!
+            </div>
+        </div>
+    </div>
+</div>
+
+<script>
+    // ------------------- ИГРОВОЕ СОСТОЯНИЕ -------------------
+    let currentScene = 1;           // 1..6
+    let sceneCompleted = [false, false, false, false, false, false]; // index 0 = сцена1
+    let globalState = {
+        // сцена 1
+        updated: false,
+        adminCreated: false,
+        sudoGranted: false,
+        switchedToAdmin: false,
+        // сцена 2
+        minlenSet: false,
+        fail2banInstalled: false,
+        fail2banActive: false,
+        // сцена 3
+        ufwDefaultDeny: false,
+        ufwSshAllowed: false,
+        ufwHttpHttps: false,
+        ufwMysqlDenied: false,
+        ufwEnabled: false,
+        // сцена 4
+        aideInitialized: false,
+        aideDbMoved: false,
+        auditRuleAdded: false,
+        auditRulePersistent: false,
+        aideCheckOk: false,
+        // сцена 5
+        apparmorEnforced: false,
+        limitsSet: false,
+        rebootSimulated: false,
+        // финальная проверка
+    };
+
+    // вспомогательный рендер терминала (логи)
+    let terminalLog = ["> Система готова. Hardening Checklist v1.0"];
+    function addTerminalLine(text, type = "info") {
+        let prefix = "";
+        if (type === "cmd") prefix = "$ ";
+        else if (type === "out") prefix = "› ";
+        else if (type === "error") prefix = "⚠️ ";
+        else if (type === "success") prefix = "✓ ";
+        terminalLog.push(prefix + text);
+        if (terminalLog.length > 28) terminalLog.shift();
+        const terminalDiv = document.getElementById("terminalOutput");
+        if (terminalDiv) terminalDiv.innerHTML = terminalLog.map(l => l + "<br>").join("");
+        terminalDiv.scrollTop = terminalDiv.scrollHeight;
+    }
+
+    function setGameMessage(msg, isError = false) {
+        const msgDiv = document.getElementById("gameMessage");
+        if (msgDiv) {
+            msgDiv.innerHTML = isError ? `❌ ${msg}` : `ℹ️ ${msg}`;
+            if (!isError) msgDiv.style.color = "#cbd5e6";
+            else msgDiv.style.color = "#ec5f67";
+        }
+    }
+
+    function updateProgressUI() {
+        let completedCount = sceneCompleted.filter(v => v === true).length;
+        document.getElementById("progressStatus").innerHTML = `🏆 ${completedCount}/6 сцен пройдено`;
+        const sceneNames = [
+            "Сцена 1: Обновление и пользователь",
+            "Сцена 2: Пароли + fail2ban",
+            "Сцена 3: UFW файрвол",
+            "Сцена 4: AIDE + аудит",
+            "Сцена 5: AppArmor + лимиты",
+            "Сцена 6: Финальная проверка"
+        ];
+        document.getElementById("sceneName").innerHTML = `${sceneNames[currentScene-1]}`;
+    }
+
+    // проверка завершения текущей сцены
+    function checkSceneCompletion() {
+        let completed = false;
+        if (currentScene === 1) {
+            if (globalState.updated && globalState.adminCreated && globalState.sudoGranted && globalState.switchedToAdmin) {
+                completed = true;
+            }
+        } else if (currentScene === 2) {
+            if (globalState.minlenSet && globalState.fail2banInstalled && globalState.fail2banActive) completed = true;
+        } else if (currentScene === 3) {
+            if (globalState.ufwDefaultDeny && globalState.ufwSshAllowed && globalState.ufwHttpHttps && globalState.ufwMysqlDenied && globalState.ufwEnabled) completed = true;
+        } else if (currentScene === 4) {
+            if (globalState.aideInitialized && globalState.aideDbMoved && globalState.auditRuleAdded && globalState.auditRulePersistent && globalState.aideCheckOk) completed = true;
+        } else if (currentScene === 5) {
+            if (globalState.apparmorEnforced && globalState.limitsSet && globalState.rebootSimulated) completed = true;
+        } else if (currentScene === 6) {
+            // финальная проверка - все сцены 1-5 должны быть пройдены
+            let allPrev = sceneCompleted[0] && sceneCompleted[1] && sceneCompleted[2] && sceneCompleted[3] && sceneCompleted[4];
+            if (allPrev) completed = true;
+        }
+
+        if (completed && !sceneCompleted[currentScene-1]) {
+            sceneCompleted[currentScene-1] = true;
+            addTerminalLine(`✨ СЦЕНА ${currentScene} ВЫПОЛНЕНА! Переход к следующей...`, "success");
+            setGameMessage(`Сцена ${currentScene} пройдена! Переход к сцене ${currentScene+1 <=6 ? currentScene+1 : 6}`);
+            if (currentScene < 6) {
+                currentScene++;
+                updateProgressUI();
+                renderDynamicActions();
+                // сброс сообщения в сцене 6 финал
+                if (currentScene === 6) addTerminalLine("=== ФИНАЛЬНАЯ СЦЕНА: ЗАПУСТИТЕ ПРОВЕРКУ ===", "success");
+            } else if (currentScene === 6 && completed) {
+                addTerminalLine("🏆 ПОЗДРАВЛЯЮ! Сервер соответствует Hardening Checklist! Звание Security Auditor!", "success");
+                setGameMessage("Игра пройдена! Вы — гуру безопасности Linux. Обновите страницу для новой игры.");
+                document.getElementById("cmdInput").disabled = true;
+                document.getElementById("runCmdBtn").disabled = true;
+            }
+            updateProgressUI();
+            renderDynamicActions();
+        } else if (!completed && sceneCompleted[currentScene-1] === false) {
+            // ничего, просто ждем
+        } else if (sceneCompleted[currentScene-1] && currentScene<6){
+            // уже пройдена, возможно переход кнопкой
+        }
+    }
+
+    // обработчик команд
+    function processCommand(cmd) {
+        let trimmed = cmd.trim().toLowerCase();
+        addTerminalLine(cmd, "cmd");
+        // HELP
+        if (trimmed === "help") {
+            addTerminalLine("Доступные команды: status, check, apt update, adduser, usermod, exit, sudo, ufw, aide, auditctl, aa-status, ulimit, fail2ban-client, и др.");
+            return;
+        }
+        if (trimmed === "status") {
+            addTerminalLine(`--- текущая сцена ${currentScene} ---`);
+            if(currentScene===1) addTerminalLine(`updated:${globalState.updated} admin:${globalState.adminCreated} sudo:${globalState.sudoGranted} switched:${globalState.switchedToAdmin}`);
+            return;
+        }
+
+        // ----- СЦЕНАРНЫЕ КОМАНДЫ (эмуляция) -----
+        // СЦЕНА 1
+        if (currentScene === 1) {
+            if (trimmed === "apt update && apt upgrade" || trimmed === "apt update" || trimmed === "apt upgrade") {
+                globalState.updated = true;
+                addTerminalLine("Обновление выполнено. Система актуальна.", "success");
+                checkSceneCompletion();
+                return;
+            }
+            if (trimmed.startsWith("adduser ")) {
+                let parts = trimmed.split(" ");
+                if (parts[1] === "admin") { globalState.adminCreated = true; addTerminalLine("Пользователь admin создан.", "success"); checkSceneCompletion(); return; }
+            }
+            if (trimmed === "usermod -aG sudo admin") { globalState.sudoGranted = true; addTerminalLine("admin добавлен в группу sudo.", "success"); checkSceneCompletion(); return; }
+            if (trimmed === "exit") { 
+                if(globalState.adminCreated && globalState.sudoGranted){
+                    globalState.switchedToAdmin = true;
+                    addTerminalLine("Вы вышли из root и теперь работаете под admin (безопасно).", "success");
+                    document.getElementById("promptUser").innerText = "admin@secured:~$";
+                    checkSceneCompletion();
+                } else { addTerminalLine("Сначала создайте admin и дайте sudo.", "error"); }
+                return;
+            }
+        }
+        // СЦЕНА 2
+        if (currentScene === 2) {
+            if (trimmed.includes("minlen") && (trimmed.includes("pwquality") || trimmed === "set minlen=12")) {
+                globalState.minlenSet = true; addTerminalLine("Политика паролей: minlen=12 установлена.", "success"); checkSceneCompletion(); return;
+            }
+            if (trimmed === "apt install fail2ban") { globalState.fail2banInstalled = true; addTerminalLine("fail2ban установлен.", "success"); checkSceneCompletion(); return; }
+            if (trimmed === "systemctl enable fail2ban" || trimmed === "systemctl start fail2ban" || trimmed === "fail2ban-client start") {
+                if(globalState.fail2banInstalled){
+                    globalState.fail2banActive = true;
+                    addTerminalLine("fail2ban активирован, защита SSH включена.", "success");
+                    checkSceneCompletion();
+                } else addTerminalLine("Сначала установите fail2ban.", "error");
+                return;
+            }
+        }
+        // СЦЕНА 3 UFW
+        if (currentScene === 3) {
+            if (trimmed === "ufw default deny incoming") { globalState.ufwDefaultDeny = true; addTerminalLine("UFW default deny incoming установлен.", "success"); checkSceneCompletion(); return; }
+            if (trimmed === "ufw allow 22/tcp") { globalState.ufwSshAllowed = true; addTerminalLine("SSH порт 22 разрешён.", "success"); checkSceneCompletion(); return; }
+            if (trimmed === "ufw allow 80/tcp" || trimmed === "ufw allow 443/tcp") { 
+                globalState.ufwHttpHttps = true;
+                addTerminalLine("HTTP/HTTPS разрешены.", "success");
+                checkSceneCompletion(); 
+                return;
+            }
+            if (trimmed === "ufw deny 3306") { globalState.ufwMysqlDenied = true; addTerminalLine("Порт MySQL 3306 закрыт.", "success"); checkSceneCompletion(); return; }
+            if (trimmed === "ufw enable") { 
+                if(globalState.ufwDefaultDeny && globalState.ufwSshAllowed){
+                    globalState.ufwEnabled = true;
+                    addTerminalLine("UFW включён. Правила активны.", "success");
+                    checkSceneCompletion();
+                } else addTerminalLine("Сначала установите default deny и разрешите SSH.", "error");
+                return;
+            }
+        }
+        // СЦЕНА 4 AIDE + аудит
+        if (currentScene === 4) {
+            if (trimmed === "aideinit" || trimmed === "aide -i") { globalState.aideInitialized = true; addTerminalLine("База AIDE инициализирована.", "success"); checkSceneCompletion(); return; }
+            if (trimmed === "mv /var/lib/aide/aide.db.new.gz /var/lib/aide/aide.db.gz") { globalState.aideDbMoved = true; addTerminalLine("База AIDE перемещена.", "success"); checkSceneCompletion(); return; }
+            if (trimmed.includes("auditctl -w /etc/passwd")) { globalState.auditRuleAdded = true; addTerminalLine("Правило аудита для /etc/passwd добавлено.", "success"); checkSceneCompletion(); return; }
+            if (trimmed === "echo '-w /etc/passwd -p wa -k passwd_changes' >> /etc/audit/rules.d/hardening.rules") { globalState.auditRulePersistent = true; addTerminalLine("Правило аудита сохранено постоянно.", "success"); checkSceneCompletion(); return; }
+            if (trimmed === "aide --check") { 
+                if(globalState.aideInitialized && globalState.aideDbMoved){
+                    globalState.aideCheckOk = true;
+                    addTerminalLine("Проверка AIDE завершена: целостность ОК.", "success");
+                    checkSceneCompletion();
+                } else addTerminalLine("Сначала инициализируйте AIDE.", "error");
+                return;
+            }
+        }
+        // СЦЕНА 5 AppArmor + лимиты
+        if (currentScene === 5) {
+            if (trimmed === "aa-enforce /etc/apparmor.d/*") { globalState.apparmorEnforced = true; addTerminalLine("AppArmor переведён в режим enforcing.", "success"); checkSceneCompletion(); return; }
+            if (trimmed === "echo 'admin soft nproc 100' >> /etc/security/limits.conf" || trimmed.includes("limits.conf")) {
+                globalState.limitsSet = true;
+                addTerminalLine("Лимиты процессов для admin установлены (soft 100 / hard 150).", "success");
+                checkSceneCompletion();
+                return;
+            }
+            if (trimmed === "reboot" || trimmed === "systemctl reboot") {
+                if(globalState.apparmorEnforced && globalState.limitsSet){
+                    globalState.rebootSimulated = true;
+                    addTerminalLine("Перезагрузка симулирована. Лимиты и AppArmor применены.", "success");
+                    checkSceneCompletion();
+                } else addTerminalLine("Необходимо сначала настроить AppArmor и limits.conf.", "error");
+                return;
+            }
+        }
+        // СЦЕНА 6 финальная кнопка проверки
+        if (currentScene === 6) {
+            if (trimmed === "final-check" || trimmed === "проверка") {
+                let allPass = sceneCompleted[0] && sceneCompleted[1] && sceneCompleted[2] && sceneCompleted[3] && sceneCompleted[4];
+                if (allPass) {
+                    addTerminalLine("✅ ВСЕ ПРОВЕРКИ ПРОЙДЕНЫ! Сервер соответствует Hardening Checklist.", "success");
+                    sceneCompleted[5] = true;
+                    updateProgressUI();
+                    addTerminalLine("🏆 ПОЗДРАВЛЯЮ! Звание Security Auditor!", "success");
+                    setGameMessage("Игра пройдена. Вы мастер Linux Hardening!");
+                } else {
+                    addTerminalLine("❌ Не все сцены пройдены. Вернитесь и выполните предыдущие сцены.", "error");
+                }
+                checkSceneCompletion();
+                return;
+            }
+        }
+        addTerminalLine(`Неизвестная команда или не подходит для текущей сцены: ${cmd}`, "error");
+    }
+
+    // кнопки быстрых действий (согласно сценарию)
+    function renderDynamicActions() {
+        const container = document.getElementById("dynamicActions");
+        if (!container) return;
+        container.innerHTML = "";
+        if (currentScene === 1) {
+            addActionBtn("apt update && apt upgrade", () => processCommand("apt update && apt upgrade"));
+            addActionBtn("adduser admin", () => processCommand("adduser admin"));
+            addActionBtn("usermod -aG sudo admin", () => processCommand("usermod -aG sudo admin"));
+            addActionBtn("exit (переключиться на admin)", () => processCommand("exit"));
+        } 
+        else if (currentScene === 2) {
+            addActionBtn("Установить minlen=12 в pwquality", () => processCommand("set minlen=12"));
+            addActionBtn("apt install fail2ban", () => processCommand("apt install fail2ban"));
+            addActionBtn("systemctl enable --now fail2ban", () => processCommand("systemctl enable fail2ban"));
+        }
+        else if (currentScene === 3) {
+            addActionBtn("ufw default deny incoming", () => processCommand("ufw default deny incoming"));
+            addActionBtn("ufw allow 22/tcp", () => processCommand("ufw allow 22/tcp"));
+            addActionBtn("ufw allow 80/tcp && 443/tcp", () => { processCommand("ufw allow 80/tcp"); processCommand("ufw allow 443/tcp"); });
+            addActionBtn("ufw deny 3306", () => processCommand("ufw deny 3306"));
+            addActionBtn("ufw enable", () => processCommand("ufw enable"));
+        }
+        else if (currentScene === 4) {
+            addActionBtn("aideinit", () => processCommand("aideinit"));
+            addActionBtn("Переместить базу AIDE", () => processCommand("mv /var/lib/aide/aide.db.new.gz /var/lib/aide/aide.db.gz"));
+            addActionBtn("auditctl -w /etc/passwd -p wa -k passwd_changes", () => processCommand("auditctl -w /etc/passwd -p wa -k passwd_changes"));
+            addActionBtn("Сохранить правило аудита", () => processCommand("echo '-w /etc/passwd -p wa -k passwd_changes' >> /etc/audit/rules.d/hardening.rules"));
+            addActionBtn("aide --check", () => processCommand("aide --check"));
+        }
+        else if (currentScene === 5) {
+            addActionBtn("aa-enforce /etc/apparmor.d/*", () => processCommand("aa-enforce /etc/apparmor.d/*"));
+            addActionBtn("Установить лимиты (limits.conf)", () => processCommand("echo 'admin soft nproc 100' >> /etc/security/limits.conf"));
+            addActionBtn("reboot (симуляция)", () => processCommand("reboot"));
+        }
+        else if (currentScene === 6) {
+            addActionBtn("🔍 Запустить финальную проверку (final-check)", () => processCommand("final-check"));
+            addActionBtn("📋 Показать статус сцен", () => {
+                let msg = `Сцены: 1:${sceneCompleted[0]} 2:${sceneCompleted[1]} 3:${sceneCompleted[2]} 4:${sceneCompleted[3]} 5:${sceneCompleted[4]}`;
+                addTerminalLine(msg);
+            });
+        }
+        function addActionBtn(text, callback) {
+            const btn = document.createElement("button");
+            btn.className = "action-btn";
+            btn.innerText = text;
+            btn.onclick = () => { callback(); renderDynamicActions(); };
+            container.appendChild(btn);
+        }
+    }
+
+    // инициализация событий
+    function initGame() {
+        updateProgressUI();
+        renderDynamicActions();
+        const inputEl = document.getElementById("cmdInput");
+        const runBtn = document.getElementById("runCmdBtn");
+        runBtn.addEventListener("click", () => {
+            let val = inputEl.value;
+            if (val.trim() !== "") processCommand(val);
+            inputEl.value = "";
+            inputEl.focus();
+        });
+        inputEl.addEventListener("keypress", (e) => {
+            if (e.key === "Enter") {
+                let val = inputEl.value;
+                if (val.trim() !== "") processCommand(val);
+                inputEl.value = "";
+            }
+        });
+        addTerminalLine("Добро пожаловать! Следуйте чеклисту. Используйте кнопки или команды.", "success");
+        addTerminalLine("Сцена 1: обновите систему, создайте admin, дайте sudo и выполните exit.");
+    }
+    initGame();
+</script>
+</body>
+</html>

+ 171 - 0
Лекции/2.4.510_Hardening_Checklist_for_Linux/tsenarii_burdyko.md

@@ -0,0 +1,171 @@
+Интерактивный сценарий: «Аудит безопасности Linux — Hardening Challenge»
+
+Сцена 1. «Первое подключение после установки»
+Элементы:
+
+Терминал с приглашением root@secured-server:~#
+
+Панель подсказок (список действий)
+
+Действия:
+
+Ввести apt update && apt upgrade
+
+Ввести adduser admin
+
+Ввести usermod -aG sudo admin
+
+Проверить версию ядра uname -a
+
+Условия для продолжения:
+
+Система обновлена (команда выполнена успешно).
+
+Создан пользователь admin с правами sudo.
+
+Игрок должен не забыть выйти из root (exit) и зайти под admin.
+
+Если игрок пытается продолжить под root — появляется предупреждение «Небезопасно! Вход root запрещён по чеклисту».
+
+Сцена 2. «Настройка паролей и защиты от брутфорса»
+Элементы:
+
+Файл /etc/pam.d/common-password (Debian/Ubuntu) или /etc/security/pwquality.conf
+
+Конфиг fail2ban (/etc/fail2ban/jail.local)
+
+Текстовое поле для ввода команд
+
+Действия:
+
+Добавить в pwquality.conf строку minlen = 12 и difok = 3.
+
+Установить fail2ban командой apt install fail2ban.
+
+Включить защиту SSH: создать jail.local с секцией [sshd] enabled = true.
+
+Перезапустить fail2ban.
+
+Условия:
+
+Параметр minlen изменён и сохранён.
+
+fail2ban активен (systemctl is-active fail2ban возвращает active).
+
+Количество неудачных попыток входа установлено не более 5 за 10 минут (проверяется через fail2ban-client status sshd).
+
+Сцена 3. «Файрвол и закрытие портов»
+Элементы:
+
+Статус UFW (отключён)
+
+Список открытых портов (порт 22, 80, 443, 8080, 3306)
+
+Действия:
+
+Запретить все входящие соединения по умолчанию: ufw default deny incoming.
+
+Разрешить SSH: ufw allow 22/tcp.
+
+Разрешить HTTP/HTTPS: ufw allow 80/tcp и ufw allow 443/tcp.
+
+Закрыть ненужный порт 3306 (MySQL): ufw deny 3306.
+
+Включить UFW: ufw enable.
+
+Условия:
+
+ufw status verbose показывает Default: deny (incoming).
+
+Порт 3306 — закрыт.
+
+SSH доступен.
+
+Игрок не должен случайно заблокировать SSH (если попытается ufw deny 22 — игра выдаёт ошибку и просит разрешить сначала).
+
+Сцена 4. «Контроль целостности и аудит»
+Элементы:
+
+Установленный AIDE (но не инициализирован).
+
+Файл /etc/audit/rules.d/hardening.rules
+
+Действия:
+
+Инициализировать базу AIDE: aideinit (или aide -i).
+
+Переместить базу в рабочую директорию: mv /var/lib/aide/aide.db.new.gz /var/lib/aide/aide.db.gz.
+
+Добавить правило аудита: auditctl -w /etc/passwd -p wa -k passwd_changes.
+
+Сделать правило постоянным, добавив строку в hardening.rules.
+
+Запустить проверку AIDE: aide --check.
+
+Условия:
+
+База AIDE создана и не повреждена.
+
+Аудит работает (auditctl -l показывает правило).
+
+При проверке AIDE нет критических изменений (игрок может смоделировать ошибку, если изменил что-то без регистрации, и должен откатить).
+
+Сцена 5. «Ограничение ресурсов и SELinux/AppArmor»
+Элементы:
+
+Статус AppArmor (aa-status)
+
+Файл /etc/security/limits.conf
+
+Действия:
+
+Включить AppArmor для всех профилей: aa-enforce /etc/apparmor.d/*.
+
+Установить лимит процессов для пользователя admin: в limits.conf добавить admin soft nproc 100 и admin hard nproc 150.
+
+Перезагрузить систему (симулировать кнопкой).
+
+Проверить, что лимиты применились: ulimit -u под admin.
+
+Условия:
+
+AppArmor находится в режиме enforce (команда aa-status показывает профили в режиме enforce).
+
+Лимит процессов для admin не превышает 150.
+
+Если игрок забыл перезагрузиться или не применил лимиты — игра не пропускает дальше.
+
+Сцена 6 (финальная). «Проверка чеклиста и отчёт»
+Элементы:
+
+Кнопка «Запустить финальную проверку»
+
+Лог-файл /var/log/hardening_report.log
+
+Действия:
+
+Нажать кнопку проверки.
+
+Игра анализирует:
+
+обновлена ли система,
+
+есть ли пользователь sudo,
+
+включён ли UFW,
+
+активен ли fail2ban,
+
+настроен ли AIDE и аудит,
+
+работают ли AppArmor и лимиты.
+
+Игрок может исправить пропущенные пункты.
+
+Условия завершения игры:
+
+Все 6 сценариев пройдены без ошибок.
+
+Итоговый отчёт содержит зелёную надпись «Сервер соответствует Hardening Checklist».
+
+Игрок получает звание «Security Auditor».

+ 11 - 0
Лекции/2.4.510_Hardening_Checklist_for_Linux/voprosi_burdyko.md

@@ -0,0 +1,11 @@
+Какая первоочередная команда должна быть выполнена после установки Linux для синхронизации репозиториев и установки критических обновлений безопасности?
+apt update && apt upgrade (для Debian/Ubuntu) или dnf update (для RHEL), а также настройка автоматических обновлений через unattended-upgrades или dnf-automatic.
+
+Какой параметр в файле /etc/ssh/sshd_config необходимо установить в значение no, чтобы запретить прямые логины под пользователем root?
+PermitRootLogin no.
+
+Каким образом в Linux можно ограничить максимальное количество процессов для пользователя, чтобы предотвратить fork-бомбы и DoS-атаки?
+с помощью команды ulimit или через файл /etc/security/limits.conf, например, задав soft nproc 100 и hard nproc 150 для конкретного пользователя.
+
+Какие две основные системы мандатного контроля доступа используются в современных дистрибутивах Linux для ограничения привилегий процессов?
+AppArmor (Ubuntu/Debian) и SELinux (RHEL/Fedora), которые должны работать в режиме enforcing.