package linuxmodules import ( "fmt" "rubric/utils" ) var SecurityModule = Module{ Key: "security", Aliases: []string{"sec", "selinux", "firewall", "безопасность"}, Title: "Безопасность: SELinux и Firewall", Description: "Темы 45–46, 48: SELinux, firewalld, восстановление доступа", Run: showSecurity, } func showSecurity() { utils.Header("Linux — Безопасность: SELinux и Firewall") // ─── 45. SELinux ────────────────────────────────────────────── utils.Section("45. Принудительный контроль доступа — SELinux") utils.Println("SELinux (Security-Enhanced Linux) — система принудительного контроля доступа.") utils.Println("Работает поверх обычных прав Unix: даже root ограничен политикой SELinux.") fmt.Println() utils.Println(utils.ColorBold + "Режимы SELinux:" + utils.ColorReset) utils.Code(`Enforcing — SELinux активен, запрещённые действия блокируются и логируются (производственный режим) Permissive — SELinux активен, нарушения только логируются (не блокируются). Для отладки. Disabled — SELinux полностью отключён (требует перезагрузки) # Текущий режим: getenforce sestatus # подробная информация # Временно изменить режим (до перезагрузки): setenforce 0 # Enforcing → Permissive setenforce 1 # Permissive → Enforcing setenforce Permissive # то же самое # Постоянно — /etc/selinux/config: SELINUX=enforcing # enforcing / permissive / disabled SELINUXTYPE=targeted # политика # После изменения с/на disabled — нужна перезагрузка. # При включении SELinux после disabled — нужна переметка файлов: touch /.autorelabel && reboot`) utils.Println(utils.ColorBold + "Контексты SELinux:" + utils.ColorReset) utils.Code(`Каждый файл, процесс и порт имеет SELinux-контекст: user:role:type:level ↓ ↓ ↓ ↓ system_u:object_r:httpd_sys_content_t:s0 Самое важное — type (тип): httpd_sys_content_t, etc_t... # Просмотр контекстов файлов: ls -Z /var/www/html/ ls -lZ /etc/nginx/ # Просмотр контекста процессов: ps auxZ | grep nginx # Просмотр контекста портов: semanage port -l | grep http`) utils.Println(utils.ColorBold + "Управление контекстами:" + utils.ColorReset) utils.Code(`# Изменить контекст файла: chcon -t httpd_sys_content_t /var/www/mysite/ chcon -R -t httpd_sys_content_t /var/www/mysite/ # рекурсивно # Проблема: chcon не постоянен, restorecon сбросит его. # Правильно: использовать semanage fcontext: # Добавить постоянное правило для контекста: semanage fcontext -a -t httpd_sys_content_t '/srv/web(/.*)?' # Применить правила к файлам: restorecon -Rv /srv/web/ # Восстановить контекст по умолчанию: restorecon -Rv /var/www/html/ # Проверить ожидаемый контекст: matchpathcon /var/www/html/index.html`) utils.Println(utils.ColorBold + "Булевые переменные SELinux (Booleans):" + utils.ColorReset) utils.Code(`# Booleans — включают/выключают определённые возможности: # Просмотр всех: getsebool -a getsebool -a | grep httpd # Включить/выключить (временно): setsebool httpd_can_network_connect on setsebool httpd_can_network_connect off # Постоянно (после перезагрузки): setsebool -P httpd_can_network_connect on setsebool -P httpd_enable_homedirs on # Полезные booleans: httpd_can_network_connect # nginx/apache → внешняя сеть httpd_can_network_connect_db # nginx/apache → БД httpd_enable_homedirs # доступ к /home samba_enable_home_dirs # Samba к /home ssh_sysadm_login # SSH-вход для sysadmin`) utils.Println(utils.ColorBold + "Порты и SELinux:" + utils.ColorReset) utils.Code(`# Посмотреть разрешённые порты: semanage port -l semanage port -l | grep http # Разрешить nginx слушать нестандартный порт 8888: semanage port -a -t http_port_t -p tcp 8888 # Удалить правило порта: semanage port -d -t http_port_t -p tcp 8888 # Изменить существующее правило: semanage port -m -t http_port_t -p tcp 8888`) utils.Println(utils.ColorBold + "Диагностика проблем SELinux:" + utils.ColorReset) utils.Code(`# Логи SELinux: /var/log/audit/audit.log # основной лог # Поиск запретов: ausearch -m avc -ts recent # последние запреты AVC grep 'denied' /var/log/audit/audit.log | tail -20 # audit2why — объяснить запрет: ausearch -m avc -ts recent | audit2why # audit2allow — создать модуль для разрешения: ausearch -m avc -ts recent | audit2allow -m mymodule > mymodule.te checkmodule -M -m -o mymodule.mod mymodule.te semodule_package -o mymodule.pp -m mymodule.mod semodule -i mymodule.pp # sealert — графическая диагностика (если установлен setroubleshoot): sealert -a /var/log/audit/audit.log`) // ─── 46. firewalld ──────────────────────────────────────────── utils.Section("46. Межсетевой экран — firewalld") utils.Println("firewalld — динамический менеджер firewall в RHEL/Fedora/CentOS.") utils.Println("Работает поверх nftables (или iptables).") fmt.Println() utils.Println(utils.ColorBold + "Зоны (Zones) — основное понятие firewalld:" + utils.ColorReset) utils.Code(`Зона определяет уровень доверия к трафику интерфейса. drop — всё входящее молча отбрасывается block — входящее отклоняется с сообщением об ошибке public — публичные сети, только явно разрешённое (по умолчанию) external — внешние сети с маскарадингом internal — внутренние сети, больше доверие home — домашние сети work — рабочие сети dmz — демилитаризованная зона trusted — весь трафик разрешён`) utils.Println(utils.ColorBold + "Основные команды firewall-cmd:" + utils.ColorReset) utils.Command("firewall-cmd --state", "работает ли firewalld") utils.Command("systemctl status firewalld", "статус сервиса") utils.Command("firewall-cmd --get-active-zones", "активные зоны и интерфейсы") utils.Command("firewall-cmd --get-default-zone", "зона по умолчанию") utils.Command("firewall-cmd --list-all", "все правила активной зоны") utils.Command("firewall-cmd --list-all --zone=public", "правила зоны public") fmt.Println() utils.Println(utils.ColorBold + "Управление сервисами и портами:" + utils.ColorReset) utils.Code(`# Разрешить сервис (временно, до перезагрузки): firewall-cmd --add-service=http firewall-cmd --add-service=https firewall-cmd --add-service=ssh # Постоянно (--permanent): firewall-cmd --permanent --add-service=http firewall-cmd --permanent --add-service=https firewall-cmd --reload # применить permanent-правила # Удалить сервис: firewall-cmd --permanent --remove-service=http # Список доступных сервисов: firewall-cmd --get-services # Разрешить порт напрямую: firewall-cmd --permanent --add-port=8080/tcp firewall-cmd --permanent --add-port=5000-5100/tcp firewall-cmd --permanent --remove-port=8080/tcp`) utils.Println(utils.ColorBold + "Rich rules — сложные правила:" + utils.ColorReset) utils.Code(`# Разрешить SSH только с конкретного IP: firewall-cmd --permanent --add-rich-rule=' rule family="ipv4" source address="192.168.1.0/24" service name="ssh" accept' # Заблокировать IP: firewall-cmd --permanent --add-rich-rule=' rule family="ipv4" source address="10.10.10.5" drop' # Ограничить количество соединений (rate limiting): firewall-cmd --permanent --add-rich-rule=' rule service name="ssh" limit value="5/m" accept'`) utils.Println(utils.ColorBold + "Маскарадинг (NAT):" + utils.ColorReset) utils.Code(`# Включить маскарадинг (нужно для роутера): firewall-cmd --permanent --zone=external --add-masquerade # Пробросить порт: firewall-cmd --permanent --add-forward-port=port=80:proto=tcp:toport=8080 # Внешний 80 → внутренний 8080`) // ─── 48. Восстановление доступа ─────────────────────────────── utils.Section("48. Восстановление доступа") utils.Println("Что делать если потеряли пароль root или доступ к системе.") fmt.Println() utils.Println(utils.ColorBold + "Сброс пароля root (RHEL/CentOS):" + utils.ColorReset) utils.Code(`1. Перезагрузить систему. 2. В меню GRUB нажать 'e' на нужной записи. 3. Найти строку начинающуюся с linux или linuxefi. 4. В конце строки добавить: rd.break 5. Нажать Ctrl+X для загрузки. # В initramfs shell: mount -o remount,rw /sysroot # перемонтировать с правами записи chroot /sysroot # перейти в систему passwd root # задать новый пароль root # Если SELinux включён: touch /.autorelabel # переметить файлы SELinux exit reboot`) utils.Println(utils.ColorBold + "Сброс пароля root (Ubuntu/Debian):" + utils.ColorReset) utils.Code(`1. В GRUB выбрать "Advanced options". 2. Выбрать строку "(recovery mode)". 3. В меню recovery выбрать "root". # Или: в GRUB нажать 'e', найти строку linux, # заменить ro на rw, добавить в конец: init=/bin/bash # В shell: passwd root # Если файловая система только для чтения: mount -o remount,rw / passwd root sync reboot -f`) utils.Println(utils.ColorBold + "Восстановление из LiveCD:" + utils.ColorReset) utils.Code(`# Загрузиться с LiveCD/LiveUSB # Найти системный раздел: lsblk # Смонтировать: mount /dev/sda2 /mnt mount /dev/sda1 /mnt/boot # boot раздел # Для UEFI: mount /dev/sda1 /mnt/boot/efi # Chroot: mount --bind /dev /mnt/dev mount --bind /proc /mnt/proc mount --bind /sys /mnt/sys chroot /mnt # Теперь можно: passwd root, grub-install, etc.`) utils.Footer() }