Безопасность системы Linux: как предотвратить «плохие действия» других пользователей на общем сервере
Это перевод оригинальной статьи Linux System Security: How To Prevent Others From Doing “Bad Things” on a Shared Server.
Подписывайтесь на телеграм-канал usr_bin, где я публикую много полезного по Linux, в том числе ссылки на статьи в этом блоге.
В процессе разработки приложения необходимо учитывать ряд аспектов, включая код, операционную систему, сеть и базу данных. Поэтому простого понимания безопасности кода недостаточно; необходимо также понимать общие механизмы безопасности в базовых средах и инструментах. Правильно настроив эти механизмы безопасности, можно повысить общую безопасность.
Когда речь заходит о Linux, многие из вас, вероятно, ежедневно используют его для различных задач разработки и эксплуатации. Однако в большинстве случаев компании не выделяют каждому сотруднику отдельный сервер Linux. Вместо этого несколько разработчиков и сотрудников службы эксплуатации используют один сервер Linux. Возникает вопрос: повлияют ли действия других сотрудников, использующих сервер Linux, на наши собственные данные и процессы? Кроме того, учитывая, что хакеры могут использовать различные уязвимости для управления сервером Linux, как можно предотвратить и минимизировать ущерб, наносимый такими вторжениями?
Понимание модели безопасности в Linux
Для эффективного решения проблем безопасности необходимо сначала понять модель безопасности Linux. Давайте разделим компоненты Linux на два уровня: уровень ядра и уровень пользователя. Уровень пользователя выполняет различные задачи, используя интерфейсы, предоставляемые уровнем ядра.
Уровень ядра обеспечивает важнейшие функции безопасности, такие как сегментация прав доступа, изоляция процессов и защита памяти, формируя основу безопасности пользовательского уровня. Если безопасность ядра нарушена (например, хакер может изменить логику ядра), он может произвольно изменять права доступа, манипулировать процессами и получать доступ к памяти. В таких случаях любые меры безопасности, реализованные на пользовательском уровне, теряют смысл.
Учитывая критическую важность безопасности ядра в Linux, стоит ли нам вкладывать значительные усилия в её защиту? На самом деле, подобно тому, как мы не слишком беспокоимся о деталях операционной системы при разработке приложений (особенно при использовании языков высокого уровня, таких как Java), нам не нужно уделять слишком много внимания безопасности ядра при рассмотрении безопасности Linux. Вместо этого следует сосредоточиться в первую очередь на безопасности пользовательского уровня. Для безопасности уровня ядра достаточно следовать рекомендациям по защите от известных уязвимостей, например, использовать официальные образы и регулярно их обновлять.
Поскольку большинство взаимодействий происходит на пользовательском уровне, давайте рассмотрим операции на этом уровне. В Linux все операции пользовательского уровня можно абстрагировать в следующий процесс: «Субъект -> Запрос -> Объект». Например, в операции «open /etc/passwd» субъект — это сам пользователь, запрос — операция чтения, а объект — файл /etc/passwd.
В этом процессе система безопасности ядра Linux обеспечивает контроль доступа на основе разрешений, предотвращая несанкционированный доступ к данным. Уровень пользователя Linux должен обеспечивать правильную настройку разрешений. Это ключ к безопасному совместному использованию сервера несколькими пользователями, что также является основной темой данной статьи.
Как золотое правило применяется в системах Linux?
Теперь, когда мы знаем, что основой безопасности систем Linux является правильная настройка прав доступа на уровне пользователя, давайте рассмотрим, как принципы Золотого правила аутентификации, авторизации и аудита применяются в системах Linux. Мы также выделим ключевые параметры безопасности, на которые следует обратить внимание в этих областях.
1. Механизмы аутентификации в Linux
Linux — многопользовательская операционная система, которая управляет и хранит пользовательскую информацию с помощью простых текстовых файлов. В этом контексте два важнейших файла: /etc/passwd и /etc/shadow.
В Linux файл /etc/passwd доступен для чтения всем пользователям и не хранит пароли напрямую из соображений безопасности. Вместо этого в поле пароля используется символ 'x' как заглушка. Информация о пароле пользователя хранится в файле /etc/shadow, доступном для чтения только пользователю ROOT.
Файл /etc/shadow содержит не только зашифрованные пароли, но и другие политики управления паролями, такие как количество дней, в течение которых пароль действителен, или количество дней до истечения срока действия пароля, по истечении которых должно быть выдано предупреждение. Мы можем изменить эти политики управления паролями с помощью команды chage. Например, следующая команда chage заставляет тестового пользователя менять пароль каждые 60 дней, тем самым снижая вероятность утечки пароля:
chage -M 60 test
Поскольку аутентификация — это функция, предоставляемая ядром Linux, проблема безопасности, на которой необходимо сосредоточиться на уровне пользователя, — это утечка идентификационной информации из-за слабых паролей. Для решения этой проблемы можно настроить соответствующие политики паролей в файле /etc/shadow. Кроме того, можно использовать такие инструменты, как John the Ripper, для обнаружения слабых паролей в Linux, используя известные базы данных слабых паролей. Следующая команда демонстрирует, как использовать John the Ripper для обнаружения слабых паролей:
unshadow /etc/passwd /etc/shadow > mypasswd john mypasswd john --show mypassw
2. Механизм авторизации в Linux
Согласно «золотому правилу», аутентификация — это лишь первый шаг, предоставляющий доверенную идентификацию. После получения этой идентификации необходимо обеспечить авторизацию, чтобы ограничить действия, которые может выполнять пользователь.
В Linux объектами (также известными как субъекты) являются только файлы и каталоги. Для этих двух типов объектов Linux определяет три типа прав доступа: чтение, запись и выполнение. Различия между этими правами доступа для файлов и каталогов можно увидеть в представленной сравнительной таблице:
Помимо этих стандартных разрешений, Linux предоставляет дополнительные теги разрешений для более детального управления. Например, Linux предлагает атрибуты файлов для дополнительной защиты. Установив бит неизменяемости с помощью chattr +i /etc/passwd, вы можете запретить любому пользователю изменять файл. Подробнее об атрибутах файлов можно найти в Википедии.
Ещё одна функция Linux — это «sticky bit», который в первую очередь используется для предотвращения манипуляций пользователей с файлами других пользователей. Например, команда chmod +t /tmp может запретить пользователям удалять файлы в директории /tmp, принадлежащем другим пользователям.
Это механизмы самозащиты при авторизации Linux, но как мы можем активно обеспечить безопасность этого процесса?
Ранее мы подчеркивали, что основная угроза безопасности в системах Linux связана с правами доступа. Это означает, что либо конфиденциальные файлы имеют неправильно настроенные права доступа, что позволяет другим пользователям получать к ним доступ или выполнять их, либо приложения содержат уязвимости или утечку паролей, что позволяет пользователям с низким уровнем привилегий получать более высокие привилегии.
Чтобы решить проблемы с разрешениями, нам следует придерживаться принципа наименьших привилегий.
Давайте рассмотрим одну из самых распространённых проблем безопасности в системах Linux: неправильное использование прав ROOT. Многие пользователи, входя в систему Linux, первым делом запускают команду su чтобы получить полноценную оболочку ROOT-пользователя. Таким образом, им не придётся каждый раз временно повышать привилегии до уровня ROOT с помощью команды sudo для выполнения каждой операции.
Однако следует отметить важный момент: в среде ROOT-оболочки все запущенные процессы также имеют привилегии ROOT. Если вы запустите быстровозвращающийся процесс, например, cat, это не создаст особых проблем. Но если это длительный процесс, это может легко привести к злоупотреблению привилегиями.
Например, если вы запустите Redis или MySQL от имени пользователя ROOT, любой другой пользователь, подключающийся к этим службам, может косвенно получить привилегии ROOT. В большинстве случаев взлома сервера хакеры используют уязвимости в этих процессах с привилегиями ROOT для повышения своих привилегий.
Поэтому при запуске любых долговременных процессов необходимо придерживаться принципа наименьших привилегий. Это означает настройку минимально необходимых прав для запуска резидентных процессов в зависимости от требуемого уровня операций. Например, операции чтения/записи файлов в таких базах данных, как Redis и MySQL, не требуют наивысших привилегий ROOT.
Принцип наименьших привилегий критически важен в системах Linux. Вы можете спросить: при таком количестве операций в Linux, для каждой из них нужна индивидуальная настройка прав доступа? К счастью, это не так. Мы часто используем известные инструменты для реализации принципа наименьших привилегий при запуске резидентных процессов, и ваша задача — правильно запустить или настроить эти инструменты.
Например, вы можете запустить службу MySQL, используя mysqld, которая выделяет процессы MySQL пользователю "mysql" и запускает демон под ROOT-аккаунтом. Вот как это выглядит на практике:
root 297353 0.0 0.0 115432 1360 ? S Aug12 0:00 /bin/sh /usr/local/mysql/bin/mysqld_safe --datadir=/var/lib/mysql --pid-file=/var/lib/mysql/mysql.pid mysql 297553 31.3 4.3 11282756 5729572 ? Sl Aug12 22593:40 /usr/local/mysql/bin/m
Аналогично, при запуске Nginx, Nginx будет запускать рабочие процессы от имени пользователя «nobody». Конкретный эффект будет следующим:
root 7083 0.0 0.0 61032 5324 ? Ss Aug12 0:01 nginx: master process nginx nobody 331122 0.0 0.0 90768 31776 ? S 11:44 0:00 nginx: worker process nobody 331123 0.0 0.0 90768 32720 ? S 11:44 0:00 nginx: worker process nobody 331124 0.0 0.0 90768 31776 ? S 11:44 0:00 nginx: worker process
Конечно, некоторые инструменты не предоставляют возможности переключения на пользователя с минимальными привилегиями. Например, при запуске Redis напрямую с помощью redis-server, нам необходимо самостоятельно управлять переключением удостоверений пользователей. Итак, как же переключить удостоверения пользователей?
Давайте сначала рассмотрим пример Nginx. При запуске Nginx Linux предоставляет идентификатор «nobody». Фактически, когда кто-либо входит в систему Linux, первым полученным идентификатором пользователя является «nobody», а затем он переключается на другие обычные идентификаторы пользователя с «nobody».
Таким образом, у пользователя «nobody» обычно есть минимальные права в операционной системе. Поэтому для инструментов, не предоставляющих минимальной функциональности переключения привилегий, мы можем использовать идентификатор пользователя «nobody» для ручного переключения.
При запуске Redis с помощью redis-server мы можем использовать следующую команду для запуска redis-serverот имени пользователя «nobody» (при условии, что мы соответствующим образом настроили каталоги для журналов и PID, чтобы гарантировать возможность записи от имени пользователя «nobody»):
su -s /bin/redis-server nobody
Применяя принцип «наименьших привилегий», мы можем повысить безопасность авторизации системы Linux.
3. Механизм аудита в Linux
Как мы уже обсуждали ранее, аудит в контексте «золотых правил» в основном включает в себя ведение журнала и анализ. Итак, какие типы журналов существуют в системе Linux? В Linux информация системного журнала обычно хранится в каталоге /var/log, и некоторые приложения также регистрируют соответствующую информацию в этом каталоге. Системные журналы в основном делятся на три категории: журналы входа пользователей, журналы специальных событий и журналы процессов.
Журналы входа пользователей — это,в основном, файлы /var/log/wtmp и /var/run/utmp, в которых хранится информация, связанная с входами пользователей. Журналы входа пользователей представляют собой двоичные файлы и не могут быть просмотрены напрямую в текстовом формате, но к ним можно получить доступ с помощью таких команд, как who, users, ac, last и lastlog.
Журналы специальных событий включают в себя /var/log/secure и /var/log/message. В /var/log/secure в основном регистрируются записи, связанные с аутентификацией и авторизацией. Например, если кто-то попытается взломать SSH методом подбора пароля, этот журнал предоставит информацию о таких попытках. Файл /var/log/message поддерживается демоном syslogd, который предоставляет стандартный механизм записи специальных событий и сообщений. Другие приложения могут использовать этот демон для сообщения о специальных событиях.
Журналы процессов: Когда управление системными процессами выполняется с помощью accton, создается файл, называемый pacct, в котором записываются команды пользователя.
По умолчанию Linux использует logrotate для управления стратегиями хранения журналов (такими как ротация журналов и удаление старых журналов). Политики хранения для различных журналов можно изменить, настроив /etc/logrotate.conf.
Итак, как же нам отслеживать журналы? Я рекомендую два распространённых инструмента для анализа журналов: ELK и Zabbix. Эти инструменты можно использовать для мониторинга журналов безопасности Linux. Настроив соответствующие правила на этих аналитических платформах (например, обнаружение более трёх неудачных попыток входа по SSH), мы можем оперативно выявлять попытки вторжения со стороны хакеров и оперативно генерировать оповещения. Затем мы можем вручную проверять журналы для решения конкретных проблем.
Заключение
Безопасность систем Linux можно считать платформой с наилучшими практиками для принципа «минимальных привилегий», особенно когда несколько пользователей совместно используют и обслуживают один сервер. Правильная настройка прав доступа в таких ситуациях может быть довольно сложной. Для решения этой проблемы необходимо строго ограничить использование привилегий ROOT. Кроме того, реализация контроля доступа с помощью iptables также может обеспечить существенную защиту от уязвимостей процессов.
Помимо механизмов самозащиты системы Linux, существуют различные инструменты безопасности, обеспечивающие дополнительные уровни защиты (например, антивирусное ПО и системы обнаружения вторжений на уровне хоста).
На этом все! Спасибо за внимание! Если статья была интересна, подпишитесь на телеграм-канал usr_bin, где будет еще больше полезной информации.