От «админа-пожарного» к «архитектору-стратегу»
В мире системного администрирования существует два подхода к безопасности. Первый — «пожарный»: реагировать, когда сервер уже взломан, логи забиты ошибками, а сайт лежит. Второй — «архитекторский»: выстраивать проактивную, автоматизированную систему аудита, которая находит уязвимости до того, как ими воспользуются.
Проблема большинства гайдов в том, что они либо слишком поверхностны («просто запустите apt update»), либо уходят в дебри SELinux и AppArmor, что нереализуемо для ежедневной проверки.
Этот гайд — золотая середина. Мы пройдем по практическому чеклисту для быстрого, но эффективного аудита безопасности Linux-сервера. А в конце мы превратим этот чеклист в автоматизированный bash-скрипт, который сделает 80% рутинной работы за вас. Хватит тушить пожары, пора строить крепость.
Пошаговый чеклист аудита
Мы разделим наш аудит на три ключевых направления: Пользователи, Сеть и Система.
Шаг 1. Ревизия пользователей и доступов (Кто в доме хозяин?)
Каждый пользователь — потенциальная точка входа. Начнем с них.
Поиск «вторых» root-пользователей
Первое, что ищет злоумышленник, — это учетная запись с UID (User ID) 0, который дает полные права root. Кроме самого root, таких быть не должно.
Bash
# Ищем всех пользователей с UID 0
# Флаг -F: указывает двоеточие как разделитель полей
# '($3 == 0)' — это условие awk, которое проверяет, равно ли третье поле (UID) нулю
# Если да, печатаем первое поле (имя пользователя)
awk -F: '($3 == 0) {print $1}' /etc/passwd
Ожидаемый результат: Только root. Если вы видите здесь что-то еще (например, toor или admin), это красный флаг.
Анализ пользователей со слабыми или пустыми паролями
Это критическая уязвимость. Атака по словарю — первое, что попробует любой ботнет.
Bash
# Проверяем файл /etc/shadow на наличие пустых паролей
# Пустой пароль обозначается как '!!' или просто пустое второе поле
# Флаг -F: снова используем двоеточие как разделитель
# '($2 == "" || $2 == "!")' — условие: второе поле (хэш пароля) пустое ИЛИ равно "!"
awk -F: '($2 == "" || $2 == "!") {print $1}' /etc/shadow
Ожидаемый результат: Пустота. Любой пользователь в этом списке — это открытая дверь на ваш сервер.
Усиление конфигурации SSH
SSH — это главный вход. Он должен быть защищен лучше всего. Открываем /etc/ssh/sshd_config и проверяем ключевые параметры:
Ini, TOML
# /etc/ssh/sshd_config
# Запрещаем вход под root. Всегда.
# Сначала заходите под своим пользователем, потом используйте 'sudo'.
PermitRootLogin no
# Отключаем вход по паролю, разрешаем только по ключам (высший пилотаж).
# Если вы еще не готовы, хотя бы оставьте 'yes', но убедитесь, что у всех сложные пароли.
PasswordAuthentication no
# Явно разрешаем вход только по ключам.
PubkeyAuthentication yes
# Указываем группу пользователей, которым разрешен SSH-доступ.
# (Не забудьте создать эту группу и добавить в нее себя: groupadd sshusers && usermod -aG sshusers your_user)
# AllowGroups sshusers
Не забудьте перезапустить сервис после изменений: sudo systemctl restart sshd.
Аудит сетевых служб и файрвола (Что слушает мир?)
Каждый открытый порт — это сервис, который принимает входящие соединения. Каждый сервис — это потенциальная уязвимость.
Поиск открытых портов
Используем утилиту ss (Socket Statistics), она современнее и быстрее, чем netstat.
Bash
# Показываем все слушающие (l) TCP (t) и UDP (u) сокеты
# -n (numeric) — не пытаться резолвить имена (работает быстрее)
# -p (processes) — показать процесс, который держит этот порт
sudo ss -tulnp
Что здесь искать:
- Порты, открытые вовне (
0.0.0.0или*):mysql(3306),postgresql(5432),redis(6379),mongo(27017) не должны слушать во всем мире. Они должны быть доступны только с127.0.0.1(localhost) или из внутренней сети. - Неизвестные сервисы: Видите порт, который не знаете?
ss -tulnp | grep :<port_number>покажет процесс. Немедленно разберитесь, что это.
Проверка статуса файрвола
Нет файрвола — нет безопасности. Мы ожидаем увидеть четкий «белый список» разрешенных портов (как 22, 80, 443) и запрет на все остальное.
Для UFW (Ubuntu/Debian):
Bash
sudo ufw status verbose
Ожидаемый результат: Status: active и Default: deny (incoming).
Для firewalld (CentOS/RHEL):
Bash
sudo firewall-cmd --list-all
Ожидаемый результат: target: default и список ваших разрешенных сервисов.
Целостность системы и обновления (Латаем дыры)
Проверка на неустановленные обновления безопасности
Это основы. Уязвимости в пакетах openssl, bash или ядре используются в первую очередь.
Для Debian/Ubuntu:
Bash
# Обновляем списки пакетов
sudo apt update > /dev/null
# Выводим список пакетов, которые можно обновить
sudo apt list --upgradable
Для RHEL/CentOS:
Bash
# Проверяем обновления, но не устанавливаем их
sudo yum check-update
Поиск файлов с SUID/SGID битами
Это продвинутая техника. SUID (Set User ID) и SGID (Set Group ID) — это специальные разрешения, которые позволяют файлу выполняться с правами владельца (часто root), а не того, кто его запустил. Это мощный вектор для повышения привилегий.
Bash
# Ищем SUID (4000) и SGID (2000) файлы по всей системе
# -perm /6000 — ищет файлы, где установлен ИЛИ SUID, ИЛИ SGID
# -type f — ищем только файлы (исключаем директории)
# 2>/dev/null — подавляем ошибки (вроде "Permission denied" для /proc)
find / -perm /6000 -type f 2>/dev/null
Что здесь искать: Вы увидите много системных файлов (/usr/bin/passwd, /usr/bin/sudo). Это нормально. Ищите нестандартные файлы в /tmp, /var/tmp, /home или кастомные скрипты, которые вы или кто-то другой по ошибке сделали SUID-ными.
Автоматизация аудита: Скрипт «Basic Security Scan»
Руками проверять все это долго. Архитектор автоматизирует. Вот простой, но мощный bash-скрипт, который соберет всю базовую информацию в один отчет.
Скопируйте этот код в файл audit.sh, дайте ему права на выполнение (chmod +x audit.sh) и запустите (sudo ./audit.sh).
Bash
#!/bin/bash
# =================================================================
# Basic Security Audit Script
# Простой скрипт для базового аудита безопасности Linux
# Запускать от имени sudo
# =================================================================
# Устанавливаем цвета для вывода
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m' # No Color
echo -e "${YELLOW}=== (1) ПРОВЕРКА ПОЛЬЗОВАТЕЛЕЙ ===${NC}"
# 1.1 Поиск пользователей с UID 0 (кроме root)
echo "[+] Поиск пользователей с UID 0..."
USERS_UID_0=$(awk -F: '($3 == 0) {print $1}' /etc/passwd | grep -v 'root')
if [ -n "$USERS_UID_0" ]; then
echo -e "${RED}ВНИМАНИЕ: Обнаружены пользователи с UID 0 (кроме root):${NC}"
echo "$USERS_UID_0"
else
echo -e "${GREEN}OK: Только 'root' имеет UID 0.${NC}"
fi
# 1.2 Поиск пользователей с пустыми паролями
echo "[+] Поиск пользователей с пустыми паролями..."
EMPTY_PASS=$(awk -F: '($2 == "" || $2 == "!") {print $1}' /etc/shadow)
if [ -n "$EMPTY_PASS" ]; then
echo -e "${RED}ВНИМАНИЕ: Обнаружены пользователи с пустыми паролями:${NC}"
echo "$EMPTY_PASS"
else
echo -e "${GREEN}OK: Пользователи с пустыми паролями не найдены.${NC}"
fi
echo -e "\n${YELLOW}=== (2) ПРОВЕРКА СЕТИ ===${NC}"
# 2.1 Поиск открытых портов
echo "[+] Слушающие TCP/UDP порты:"
# Используем 'ss'. Если нет, пробуем 'netstat'.
if command -v ss &> /dev/null; then
ss -tulnp
elif command -v netstat &> /dev/null; then
netstat -tulnp
else
echo -e "${RED}Ошибка: Не найдены 'ss' или 'netstat'.${NC}"
fi
# 2.2 Проверка статуса UFW (для Debian-based)
if command -v ufw &> /dev/null; then
echo "[+] Статус файрвола UFW:"
ufw status | grep -q 'Status: active'
if [ $? -eq 0 ]; then
echo -e "${GREEN}OK: UFW активен.${NC}"
else
echo -e "${RED}ВНИМАНИЕ: UFW неактивен!${NC}"
fi
fi
echo -e "\n${YELLOW}=== (3) ПРОВЕРКА СИСТЕМЫ ===${NC}"
# 3.1 Поиск SUID/SGID файлов
echo "[+] Поиск SUID/SGID файлов (может занять время)..."
# Сохраняем результат во временный файл для анализа
find / -perm /6000 -type f -exec ls -ld {} \; 2>/dev/null > /tmp/suid_files.txt
echo "Найдено $(wc -l < /tmp/suid_files.txt) SUID/SGID файлов. (Подробности в /tmp/suid_files.txt)"
# Проверяем на "подозрительные" расположения
SUSPICIOUS_SUID=$(grep -E '/tmp|/var/tmp|/home' /tmp/suid_files.txt)
if [ -n "$SUSPICIOUS_SUID" ]; then
echo -e "${RED}ВНИМАНИЕ: Найдены SUID/SGID файлы в подозрительных директориях:${NC}"
echo "$SUSPICIOUS_SUID"
fi
# 3.2 Проверка наличия обновлений (для apt)
if command -v apt &> /dev/null; then
echo "[+] Проверка обновлений (apt)..."
# Обновляем репозитории тихо
apt update -qq
UPGRADABLE=$(apt list --upgradable 2>/dev/null | wc -l)
# wc -l посчитает и заголовок, поэтому вычитаем 1
UPGRADABLE_COUNT=$((UPGRADABLE - 1))
if [ $UPGRADABLE_COUNT -gt 0 ]; then
echo -e "${YELLOW}Доступно $UPGRADABLE_COUNT обновлений.${NC} (Запустите 'apt list --upgradable')"
else
echo -e "${GREEN}OK: Система обновлена.${NC}"
fi
fi
echo -e "\n${YELLOW}=== АУДИТ ЗАВЕРШЕН ===${NC}"
Что мы узнали и почему это важно?
Мы только что превратили хаотичный набор команд в систему. Мы прошли путь от «надеюсь, все в порядке» до «я проверил и вот отчет».
Этот чеклист и скрипт — не панацея, а фундамент. Это первый шаг к построению комплексной системы безопасности. Вы не просто «закрыли порты», вы внедрили повторяемый процесс аудита.
Настоящий «архитектор будущего» не делает это вручную. Он настраивает этот скрипт на запуск по расписанию (привет, systemd timers!), отправляет отчеты в Zabbix или Slack и тратит освободившееся время на изучение AI для анализа логов, а не на ручной поиск пустых паролей.
Теги: #linux #security #bash #automation #sysadmin #аудит #checklist
🚀 Хотите стать архитектором будущего, а не просто админом? Эта статья — лишь верхушка айсберга. В нашем Telegram-канале «Admin Future» мы каждый день публикуем системные гайды, готовые скрипты, AI-лайфхаки и чеклисты, которые не найти в Google. Мы не просто постим команды — мы строим библиотеку знаний для тех, кто хочет расти от админа до архитектора. Подписывайтесь и становитесь экспертом: Admin Future