Политика безопасности Linux-сервера - это набор правил и процедур, которые определяют, кто получает доступ к системе, какие действия разрешены и как службы взаимодействуют с сетью. Без такой политики сервер остается уязвимым для подбора паролей, эксплуатации уязвимостей в службах и ошибок администраторов. Основные векторы атак: SSH с парольной аутентификацией, открытые порты неиспользуемых сервисов, процессы с избыточными правами и отсутствие контроля над действиями пользователей.
Комплексная защита строится на четырех уровнях: управление учетными записями и привилегиями, файрвол для фильтрации трафика, мандатный контроль доступа (SELinux или AppArmor) и усиление SSH. Каждый уровень закрывает свой класс угроз. Принцип наименьших привилегий означает, что пользователь или процесс получает только те права, которые необходимы для выполнения задачи, и ничего сверх этого.
Безопасность - это процесс, а не разовая настройка. Конфигурации устаревают, появляются новые уязвимости, меняются требования к доступу. Поэтому политику нужно регулярно пересматривать, а изменения тестировать в изолированной среде перед применением на боевом сервере.
Управление пользователями и привилегиями
Каждый администратор должен работать под собственной учетной записью. Общий root-доступ не позволяет отследить, кто выполнил конкретную команду, и увеличивает риск случайного повреждения системы. Отдельные учетные записи с делегированием прав через sudo решают обе проблемы.
Создание и удаление пользователей
Для создания пользователя с домашней директорией и bash в качестве оболочки используется команда:
useradd -m -s /bin/bash username
Параметр -m создает домашнюю директорию /home/username, а -s /bin/bash назначает оболочку. После создания нужно задать пароль:
passwd username
Система запросит пароль дважды. Для удаления пользователя вместе с его домашней директорией:
userdel -r username
Без параметра -r домашняя директория останется на диске. Это может быть полезно, если нужно сохранить данные, но обычно при удалении учетной записи директорию тоже удаляют.
Настройка sudo: предоставление привилегий
Файл /etc/sudoers определяет, какие команды пользователь может выполнять от имени root. Редактировать его нужно только через visudo, который проверяет синтаксис перед сохранением и предотвращает блокировку sudo из-за ошибки.
Чтобы разрешить пользователю выполнять все команды:
username ALL=(ALL:ALL) ALL
Для ограничения конкретными командами, например, перезапуском веб-сервера:
username ALL=(ALL) /usr/bin/systemctl restart nginx, /usr/bin/systemctl status nginx
Для выполнения команд без запроса пароля используется тег NOPASSWD:
username ALL=(ALL) NOPASSWD: /usr/bin/systemctl restart nginx
Алиасы упрощают управление при большом количестве пользователей. Можно сгруппировать команды в Cmnd_Alias и назначить его группе пользователей:
Cmnd_Alias WEB_SERVICES = /usr/bin/systemctl restart nginx, /usr/bin/systemctl reload nginx
%webadmins ALL=(ALL) WEB_SERVICES
Риск при настройке sudoers: разрешение на выполнение редакторов или команд с возможностью выхода в shell (например, vim, less, find) фактически дает пользователю полный root-доступ. Проверяйте, какие команды делегируете.
Управление группами и правами доступа к файлам
Группы упрощают управление доступом к общим ресурсам. Создание группы:
groupadd webadmins
Добавление пользователя в группу:
usermod -aG webadmins username
Параметр -a (append) добавляет группу к уже существующим, без него пользователь будет удален из всех других групп.
Права на файлы задаются через chmod. Основные комбинации: rwx - чтение, запись, выполнение; rw- - чтение и запись; r-- - только чтение. Для веб-сервера типичная настройка:
chown -R www-data:www-data /var/www/site
chmod 750 /var/www/site
chmod 640 /var/www/site/*.php
Владелец www-data получает полный доступ к директории, группа - чтение и выполнение, остальные - ничего. Файлы PHP доступны только владельцу и группе на чтение и запись.
Политика паролей настраивается через PAM (Pluggable Authentication Modules). В файле /etc/security/pwquality.conf задаются минимальная длина, требования к сложности и срок действия пароля. Для серверов с SSH-доступом рекомендуется минимальная длина 12 символов и запрет на повторное использование последних 5 паролей.
Настройка файрвола: iptables и nftables
Файрвол фильтрует сетевой трафик на уровне ядра. Он не заменяет другие меры защиты, но ограничивает поверхность атаки: если служба не слушает порт, к ней невозможно подключиться. Базовая стратегия - запретить все входящие соединения, кроме явно разрешенных.
Основы iptables: цепочки и правила
iptables использует три основные цепочки: INPUT для входящего трафика, OUTPUT для исходящего и FORWARD для транзитного. Правила обрабатываются сверху вниз, первое совпадение определяет действие.
Установка политики по умолчанию - запретить все входящие:
iptables -P INPUT DROP
iptables -P FORWARD DROP
iptables -P OUTPUT ACCEPT
Разрешить SSH на порту 22:
iptables -A INPUT -p tcp --dport 22 -j ACCEPT
Разрешить HTTP и HTTPS:
iptables -A INPUT -p tcp --dport 80 -j ACCEPT
iptables -A INPUT -p tcp --dport 443 -j ACCEPT
Разрешить уже установленные соединения:
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
Просмотр текущих правил:
iptables -L -v -n
Флаг -v показывает счетчики пакетов, -n отключает обратное разрешение DNS для ускорения вывода.
Переход на nftables: современный синтаксис
nftables заменяет iptables, ip6tables, arptables и ebtables единым фреймворком. Синтаксис компактнее, обработка правил быстрее, конфигурация хранится в одном файле. В современных дистрибутивах (Debian 10+, Ubuntu 20.04+, RHEL 8+) nftables доступен по умолчанию.
Создание таблицы для IPv4 и IPv6:
nft add table inet filter
Создание цепочки input с политикой drop:
nft add chain inet filter input { type filter hook input priority 0; policy drop; }
Разрешение SSH, HTTP и HTTPS:
nft add rule inet filter input tcp dport 22 accept
nft add rule inet filter input tcp dport 80 accept
nft add rule inet filter input tcp dport 443 accept
nft add rule inet filter input ct state established,related accept
Сохранение конфигурации:
nft list ruleset > /etc/nftables.conf
Загрузка при старте системы настраивается через systemd-юнит nftables.service, который читает этот файл.
Практические примеры правил для веб-сервера
Типовой веб-сервер принимает SSH, HTTP и HTTPS. Все остальные порты закрыты. Для административных портов (например, панель управления на порту 9090) доступ ограничивается конкретными IP:
nft add rule inet filter input ip saddr 203.0.113.10 tcp dport 9090 accept
nft add rule inet filter input ip saddr 203.0.113.20 tcp dport 9090 accept
nft add rule inet filter input tcp dport 9090 drop
Первые два правила разрешают доступ с двух адресов, третье блокирует всех остальных. Порядок правил критичен: сначала разрешения, затем запрет.
Разрешение ICMP ping полезно для диагностики:
nft add rule inet filter input icmp type echo-request accept
Перед применением правил на боевом сервере проверьте их в тестовой среде. Ошибка в порядке правил может заблокировать ваш собственный SSH-доступ.
Мандатный контроль доступа: SELinux и AppArmor
Мандатный контроль доступа (MAC) ограничивает действия процессов даже если они запущены от root. Это дополнительный уровень защиты на случай эксплуатации уязвимости: взломанный веб-сервер не сможет читать файлы за пределами своей директории или запускать произвольные процессы.
SELinux: включение и базовая настройка
SELinux использует метки (контексты) на файлах и процессах. Политика определяет, какие процессы к каким файлам могут обращаться. Проверка текущего статуса:
getenforce
Возможные значения: Enforcing (политика применяется), Permissive (нарушения логируются, но не блокируются), Disabled (выключен). Временное переключение в permissive:
setenforce 0
Возврат в enforcing:
setenforce 1
Для постоянного включения нужно изменить параметр SELINUX=enforcing в файле /etc/selinux/config.
Настройка нестандартного порта для SSH - типичная задача. SELinux разрешает SSH только на порту 22. Чтобы добавить порт 2222:
semanage port -a -t ssh_port_t -p tcp 2222
Команда semanage входит в пакет policycoreutils-python-utils (RHEL/CentOS) или policycoreutils-python (Fedora).
AppArmor: профили и режимы
AppArmor работает на основе профилей, привязанных к путям исполняемых файлов. Профиль определяет, какие файлы и ресурсы доступны процессу. Проверка статуса:
aa-status
Профили работают в двух режимах: enforce (блокировка нарушений) и complain (только логирование). Переключение режима:
aa-enforce /etc/apparmor.d/usr.sbin.nginx
aa-complain /etc/apparmor.d/usr.sbin.nginx
Для обновления профиля на основе записанных нарушений используется aa-logprof. Он анализирует логи и предлагает добавить разрешения в профиль. Это основной инструмент при настройке AppArmor для нестандартных конфигураций.
Решение типичных проблем с MAC
Симптом: служба не запускается или не может обратиться к файлам после включения SELinux/AppArmor. Первый шаг - проверить логи.
Для SELinux логи находятся в /var/log/audit/audit.log. Сообщения AVC (Access Vector Cache) показывают, какие действия были заблокированы. Утилита sealert анализирует эти сообщения и предлагает решение:
sealert -a /var/log/audit/audit.log
Для AppArmor логи в /var/log/syslog или journalctl -u apparmor. Утилита aa-logprof предложит обновить профиль на основе нарушений.
Распространенная ошибка - отключение SELinux или AppArmor вместо настройки. Это снимает защиту со всей системы ради решения одной проблемы. Если служба блокируется, настройте контекст или профиль, а не выключайте MAC.
Усиление безопасности SSH
SSH - основная точка входа для удаленного администрирования. Брутфорс-атаки на порт 22 идут непрерывно с момента подключения сервера к интернету. Усиление SSH снижает риск подбора пароля и ограничивает последствия компрометации учетной записи.
Отключение входа root и аутентификация по ключам
Вход root по SSH должен быть запрещен. Администратор заходит под своей учетной записью и повышает права через sudo. В файле /etc/ssh/sshd_config:
PermitRootLogin no
PasswordAuthentication no
PubkeyAuthentication yes
После изменения конфигурации перезапустите sshd:
systemctl restart sshd
Генерация ключевой пары на клиенте:
ssh-keygen -t ed25519 -a 100
Алгоритм ed25519 быстрее и компактнее RSA при сопоставимой криптостойкости. Параметр -a 100 задает количество итераций KDF для защиты приватного ключа.
Копирование публичного ключа на сервер:
ssh-copy-id username@server_ip
После этого вход выполняется без пароля. Проверьте, что ключевая аутентификация работает, прежде чем отключать парольную. Иначе вы потеряете доступ к серверу.
Дополнительные меры: смена порта, ограничение доступа, fail2ban
Смена стандартного порта снижает количество автоматических сканирований, но не заменяет другие меры. В sshd_config:
Port 2222
Ограничение доступа по пользователям и группам:
AllowUsers admin1 admin2
AllowGroups sshadmins
Остальные пользователи не смогут подключиться по SSH, даже если у них есть валидные ключи.
Fail2ban отслеживает логи аутентификации и блокирует IP-адреса после нескольких неудачных попыток. Установка на Debian/Ubuntu:
apt install fail2ban
Базовая конфигурация в /etc/fail2ban/jail.local:
[sshd]
enabled = true
port = 2222
maxretry = 3
bantime = 3600
После трех неудачных попыток IP блокируется на час. Это останавливает большинство автоматических брутфорс-атак.
Более детально тема усиления SSH и аудита разобрана в руководстве по hardening и аудиту Linux-сервера. Там же есть чек-лист для проверки конфигурации.
Типичные ошибки и как их избежать
Блокировка собственного IP в файрволе - самая частая причина потери доступа к серверу. Правило DROP для всех входящих, примененное до разрешения SSH, отключит вашу текущую сессию. Решение: всегда добавляйте разрешающие правила до установки политики DROP и тестируйте конфигурацию в изолированной среде.
Неправильная настройка sudoers может заблокировать sudo полностью. Ошибка в синтаксисе файла /etc/sudoers делает команду sudo недоступной для всех пользователей. Решение: всегда используйте visudo, который проверяет синтаксис перед сохранением. Держите вторую root-сессию открытой при изменении sudoers.
Отключение SELinux вместо настройки - типичная реакция на проблемы с доступом. Это устраняет симптом, но снимает защиту. Решение: используйте sealert и audit2allow для создания точечных разрешений, а не отключайте MAC.
Слабые пароли остаются проблемой даже при отключенной парольной аутентификации SSH. Пароли используются для sudo, для доступа к базам данных, для других служб. Решение: настройте PAM-политику с минимальной длиной 12 символов и требованием к сложности.
Отсутствие резервных копий конфигураций усложняет восстановление после неудачных изменений. Перед редактированием sshd_config, sudoers, файрвола или политик SELinux создавайте копию:
cp /etc/ssh/sshd_config /etc/ssh/sshd_config.bak.$(date +%Y%m%d)
Для тестирования изменений используйте виртуальную машину или контейнер. Настройка безопасности в изолированной среде позволяет выявить ошибки без риска для рабочего сервера.
Заключение: комплексный подход к безопасности
Политика безопасности Linux-сервера объединяет управление доступом, файрвол, мандатный контроль доступа и усиление SSH. Каждый уровень решает свою задачу: учетные записи ограничивают действия пользователей, файрвол фильтрует сетевой трафик, SELinux/AppArmor сдерживают процессы, SSH защищает удаленный доступ.
После первичной настройки безопасность требует регулярного обслуживания. Устанавливайте обновления безопасности в течение 24-48 часов после их выхода. Просматривайте логи на предмет подозрительной активности. Пересматривайте правила доступа при изменении состава команды или архитектуры сервера.
Для автоматизации аудита используйте инструменты вроде Lynis и OpenSCAP. Они проверяют конфигурацию на соответствие лучшим практикам и выявляют слабые места. Подробный чек-лист аудита безопасности с готовыми командами приведен в руководстве по аудиту и защите серверов.
Если вы разворачиваете сервер для веб-проекта, обратите внимание на облачную инфраструктуру Timeweb Cloud. VDS/VPS с предустановленными шаблонами Linux позволяют быстро поднять окружение и применить описанные в этой статье практики на изолированном инстансе.
Тестируйте изменения, документируйте конфигурации, обучайте команду. Безопасность - это непрерывный процесс, а не конечное состояние.