276 lines
12 KiB
Go
276 lines
12 KiB
Go
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()
|
||
}
|