ос и с. ОСиС. 1. Классификация программного обеспечения
Скачать 2.7 Mb.
|
30. Реализация безопасности в UNIX на уровне файловой системы Как и принято в многопользовательской операционной системе, в UNIX поддерживается единообразный механизм контроля доступа к файлам и справочникам файловой системы. Любой процесс может получить доступ к некоторому файлу в том и только в том случае, если права доступа, описанные при файле, соответствуют возможностям данного процесса. Защита файлов от несанкционированного доступа в ОС UNIX основывается на трех фактах. Во-первых, с любым процессом, создающим файл (или справочник), ассоциирован некоторый уникальный в системе идентификатор пользователя (UID - User Identifier), который в дальнейшем можно трактовать как идентификатор владельца вновь созданного файла. Во-вторых, с каждый процессом, пытающимся получить некоторый доступ к файлу, связана пара идентификаторов - текущие идентификаторы пользователя и его группы. В-третьих, каждому файлу однозначно соответствует его описатель - i-узел. На последнем факте стоит остановиться более подробно. Важно понимать, что имена файлов и файлы как таковые - это не одно и то же. В частности, при наличии нескольких жестких связей с одним файлом несколько имен файла реально представляют один и тот же файл и ассоциированы с одним и тем же i-узлом. Любому используемому в файловой системе i-узлу всегда однозначно соответствует один и только один файл. I-узел содержит достаточно много разнообразной информации (большая ее часть доступна пользователям через системные вызовы stat и fstat), и среди этой информации находится часть, позволяющая файловой системе оценить правомощность доступа данного процесса к данному файлу в требуемом режиме. Общие принципы защиты одинаковы для всех существующих вариантов системы: Информация i-узла включает UID и GID текущего владельца файла (немедленно после создания файла идентификаторы его текущего владельца устанавливаются соответствующими действующим идентификатором процесса-создателя, но в дальнейшем могут быть изменены системными вызовами chown и chgrp). Кроме того, в i-узле файла хранится шкала, в которой отмечено, что может делать с файлом пользователь - его владелец, что могут делать с файлом пользователи, входящие в ту же группу пользователей, что и владелец, и что могут делать с файлом остальные пользователи. Мелкие детали реализации в разных вариантах системы различаются. Для определенности мы приведем точную картину того, как это происходит в UNIX (1). Таблица 1. Представление информации, ограничивающей доступ к файлу, в i-узле файла
31. Реализация безопасности в UNIX на уровне ОС С каждым выполняемым процессом в ОС UNIX связываются реальный идентификатор пользователя (real user ID), действующий идентификатор пользователя (effective user ID) и сохраненный идентификатор пользователя (saved user ID). Все эти идентификаторы устанавливаются с помощью системного вызова setuid, который можно выполнять только в режиме суперпользователя. Аналогично, с каждым процессом связываются три идентификатора группы пользователей - real group ID, effective group ID и saved group ID. Эти идентификаторы устанавливаются привилегированным системным вызовом setgid. При входе пользователя в систему программа login проверяет, что пользователь зарегистрирован в системе и знает правильный пароль (если он установлен), образует новый процесс и запускает в нем требуемый для данного пользователя shell. Но перед этим login устанавливает для вновь созданного процесса идентификаторы пользователя и группы, используя для этого информацию, хранящуюся в файлах /etc/passwd и /etc/group. После того, как с процессом связаны идентификаторы пользователя и группы, для этого процесса начинают действовать ограничения для доступа к файлам. Процесс может получить доступ к файлу или выполнить его (если файл содержит выполняемую программу) только в том случае, если хранящиеся при файле ограничения доступа позволяют это сделать. Связанные с процессом идентификаторы передаются создаваемым им процессам, распространяя на них те же ограничения. Однако в некоторых случаях процесс может изменить свои права с помощью системных вызовов setuid и setgid, а иногда система может изменить права доступа процесса автоматически. Рассмотрим, например, следующую ситуацию. В файл /etc/passwd запрещена запись всем, кроме суперпользователя (суперпользователь может писать в любой файл). Этот файл, помимо прочего, содержит пароли пользователей и каждому пользователю разрешается изменять свой пароль. Имеется специальная программа /bin/passwd, изменяющая пароли. Однако пользователь не может сделать это даже с помощью этой программы, поскольку запись в файл /etc/passwd запрещена. В системе UNIX эта проблема разрешается следующим образом. При выполняемом файле может быть указано, что при его запуске должны устанавливаться идентификаторы пользователя и/или группы. Если пользователь запрашивает выполнение такой программы (с помощью системного вызова exec), то для соответствующего процесса устанавливаются идентификатор пользователя, соответствующий идентификатору владельца выполняемого файла и/или идентификатор группы этого владельца. В частности, при запуске программы /bin/passwd процесс получит идентификатор суперпользователя, и программа сможет произвести запись в файл /etc/passwd. И для идентификатора пользователя, и для идентификатора группы реальный ID является истинным идентификатором, а действующий ID - идентификатором текущего выполнения. Если текущий идентификатор пользователя соответствует суперпользователю, то этот идентификатор и идентификатор группы могут быть переустановлены в любое значение системными вызовами setuid и setgid. Если же текущий идентификатор пользователя отличается от идентификатора суперпользователя, то выполнение системных вызовов setuid и setgid приводит к замене текущего идентификатора истинным идентификатором (пользователя или группы соответственно). 32. Понятие пользователь, группа в UNIX Каждый файл помимо названия, полного пути, времени создания и т.д. обладает набором атрибутов, определяющих права доступа для любого пользователя. Все пользователи сервера делятся относительно файла на три категории: владелец файла (как правило тот, кто его создал или скопировал) пользователи, входящие в группу, к которой принадлежит файл все остальные пользователи Все права относительно файла также делятся на три категории: право на чтение (read - сокращенно "r") файла - позволяет просматривать и копировать содержимое файла право на запись файла (write - сокращенно "w") - позволяет дописывать и перезаписывать содержимое файла право на исполнение файла (execute - сокращенно "x") - позволяет отдать операционной системе команду на исполнение файла как программы Для каждой категории пользователей (владельца, группы, остальных) определяются свои права (на чтение, на запись, на исполнение) - всего получается девять позиций, принимающих значение "есть"/"нет". Как правило, права на доступ к файлу обозначаются девятью символами - три повторяющиеся тройки символов rwx, каждый из символов обозначает присутствие соответствующего права доступа и может быть заменен на "-" если соответствующее право отсутствует. Первая тройка соответствует правам владельца файла, вторая - правам пользователей из той же группы, к которой принадлежит файл, третья - правам для всех остальных. Например, предположим, что для файла myfile имеются следующие права доступа: для владельца - чтение, запись, исполнение (rwx) для группы - чтение, исполнение (r-x) для всех остальных - только чтение (r--) Тогда права доступа к файлу будут описываться следующей последовательностью символов: rwxr-xr— Иногда для краткости используют "числовую" форму описания прав доступа - трехзначное число, каждая цифра которого соответствует тройке прав для соответствующей категории пользователей: первая - владельцу, вторая - группе, третья - остальным. Сама цифра образуется суммой чисел, приписываемых каждой категории прав доступа: 1 - исполнение, 2 - запись, 4 - чтение. Таким образом 'rwx' соответствуют 7, 'rw-' - 6, 'r-x' - 5, 'r--' - 4, '-w-' - 2, '--x' - 1, '---' - 0. Например, предположим, что для файла myfile имеются следующие права доступа: для владельца - чтение, запись (rw-) для группы - чтение (r--) для всех остальных - ничего (---) В символьной форме такие права доступа будут описываться как rw-r-----, а в числовой форме они выглядят так: 640. Иногда числовая форма описания прав доступа к файлу включает в себя четыре цифры - в этом случае первая цифра не относится к правам доступа, как таковым (а определяет поведение файла во время исполнения, так что здесь мы этого касаться не будем) и учитывать надо последние три цифры. Каталог для Unix - одна из разновидностей файла. Соответственно все, что было сказано выше о правах доступа к файлам, относиться и к каталогам. Правда понятия "прочитать", "записать" и "исполнить" в отношении каталога имеют свою специфику: "Чтение" подразумевает получение списка файлов, принадлежащих каталогу - важно помнить, что это не блокирует доступ к самим файлам, лежащим в этом каталоге. "Запись" подразумевает изменение списка файлов, принадлежащих каталогу - чтобы создать файл в каком-либо каталоге, надо быть пользователем, который имеет право записи в этот каталог, чтобы удалить файл, надо иметь не право записи в удаляемый файл (это позволяет только удалить или перезаписать информацию в самом файле), а право записи в каталог, которому файл принадлежит "Исполнение" - подразумевает принципиальную возможность доступа к любому файлу, принадлежащему данному каталогу или его подкаталогам. Даже если права доступа к файлу, находящемуся в каталоге и позволяют какие-либо операции с ним, отсутствие права на "исполнение" этого каталога не позволит ничего с этим файлом сделать. Для файлов, не являющихся cgi-программами - таких как .html, .shtml или .php, - права доступа могут быть установлены в 644 (-rw-r--r--) (запись-чтение для владельца и только чтение для всех остальных). Для файлов, являющихся cgi-программами (perl-скрипты, скомпилированные C-программы и прочее), права доступа должны быть установлены в 744 (rwxr--r--) (исполнение-запись-чтение для владельца и чтение для всех остальных). Нельзя разрешать запись в файл с cgi-программой кому-либо, кроме владельца - попытку запустить такую cgi-программу веб-сервер считает ошибкой. При разработке cgi-программ учитывайте, пожалуйста, что web-сервер запускает их от имени пользователя-владельца сайта. Если Ваша cgi-программа работает с файлами данных (записывает в них что-либо), то эти файлы должны иметь права доступа 600 (rw------). PHP-скрипты запускаются от имени пользователя, не являющегося пользователем-владельцем сайта поэтому для файлов данных, которые используют PHP-скрипты, необходимо установить права 666 (rw-rw-rw-), а если php-скрипт создает в каком-либо каталоге новые файлы, то этот каталог должен иметь права на запись "для всех" - например 777 (rwxrwxrwx). Права на каталоги мы рекомендуем устанавливать в 755 (rwxr-xr-x). Эти же права устанавливаются по умолчанию при создании нового каталога. Нельзя разрешать запись в каталог с cgi-программой кому-либо, кроме владельца - попытку запустить cgi-программу из такого каталога веб-сервер считает ошибкой. 33. Бесправный пользователь. Пользователь ресурса. Пользователь ОС Существует несколько моделей предоставления прав доступа к файлам и другим объектам. Наиболее простая модель используется в системах семейства Unix. В этих системах каждый файл или каталог имеют идентификаторы хозяина и группы. Определено три набора прав доступа: для хозяина, группы (т.е., для пользователей, входящих в группу, к которой принадлежит файл) и всех остальных. Пользователь может принадлежать к нескольким группам одновременно, файл всегда принадлежит только одной группе. Бывают три права: чтения, записи и исполнения. Для каталога право исполнения означает право на поиск файлов в этом каталоге. Каждое из прав обозначается битом в маске прав доступа, т.е. все три группы прав представляются девятью битами или тремя восьмеричными цифрами. Права на удаление или переименование файла не существует; вообще, в Unix не определено операции удаления файла как таковой, а существует лишь операция удаления имени unlink . Для удаления или изменения имени достаточно иметь право записи в каталог, в котором это имя содержится. В традиционных системах семейства Unix все глобальные объекты - внешние устройства и именованные программные каналы - являются файлами (точнее, имеют имена в файловой системе), и управление доступом к ним охватывается файловым механизмом. В современных версиях Unix адресные пространства исполняющихся процессов также доступны как файлы в специальной файловой (или псевдофайловой, если угодно) системе proc. Файлы в этой ФС могут быть использованы, например, отладчиками для доступа к коду и данным отлаживаемой программы. Управление таким доступом также осуществляется стандартным файловым механизмом. Кроме доступа к адресному пространству, над процессом в Unix определена, по существу, только операция посылки сигнала. Обычный пользователь может посылать сигналы только своим процессам; только суперпользователь (root) может посылать их чужим процессам. Все остальные операции осуществимы только между процессами, связанными отношением родитель/потомок, и распределение прав доступа в этой ситуации вообще не нужно. Таким образом, файловые права доступа используются для управления доступом к практически любым объектам ОС. В Unix появились объекты, не являющиеся файлами и идентифицируемые численными ключами доступа вместо имен. Все эти объекты являются средствами межпроцессного взаимодействия: это семафоры, очереди сообщений и сегменты разделяемой памяти. Каждый такой объект имеет маску прав доступа, аналогичную файловой, и доступ к ним контролируется точно так же, как и к файлам. Основное преимущество этого подхода состоит в его простоте. Фактически это наиболее простая из систем привилегий, пригодная для практического применения. Иными словами, более простые системы непригодны вообще. Кроме того, практика эксплуатации систем, использующих эту модель, показывает, что она вполне адекватна подавляющему большинству реальных ситуаций. Многие современные системы, не входящие в семейство Unix, а также и некоторые версии Unix, например, HP/UX или SCO UnixWare 2.x, используют более сложную и гибкую систему управления доступом, основанную на списках управления доступом (Access Control Lists - ACL). С каждым защищаемым объектом, кроме идентификатора его хозяина, связан список записей. Каждая запись состоит из идентификатора пользователя или группы и списка прав для этого пользователя или группы. Понятие группы в таких системах не играет такой большой роли, как в Unix, а служит лишь для сокращения ACL, позволяя задать права для многих пользователей одним элементом списка. Многие системы, использующие эту модель, например Novell Netware, даже не ассоциируют с файлом идентификатора группы. Обычно список возможных прав включает в себя право на изменение ACL. Таким образом, не только хозяин объекта может изменять права доступа к нему. Это право может быть дано и другим пользователям системы или даже группам пользователей, если это окажется для чего-то необходимо. Однако за дополнительную гибкость приходится платить снижением производительности. В системах семейства Unix проверка прав доступа осуществляется простой битовой операцией над маской прав. В системах же, использующих ACL, необходим просмотр списка, который может занять намного больше времени. Самое плохое состоит в том, что мы не можем гарантировать завершения этого поиска за какое-либо время, не устанавливая ограничений на длину списка. В современных системах накладные расходы, связанные с использованием ACL, считаются достаточно малыми, поэтому эта модель распределения прав приобретает все большую популярность. Кроме прав доступа к объектам, система должна управлять выдачей некоторых привилегий. Так, для выполнения резервного копирования и восстановления файлов необходим пользователь, способный осуществлять доступ к файлам и операции на ними, не обращая внимания на права доступа. Во всех системах необходимы пользователи, имеющие право изменять конфигурацию системы, заводить новых пользователей и группы и т.д. Если система обеспечивает запуск процессов реального времени, создание таких процессов тоже должно контролироваться, поскольку процесс РВ имеет более высокий приоритет, чем все процессы разделенного времени, и может, просто не отдавая процессор, заблокировать все остальные задачи. В большинстве современных многопользовательских ОС, не входящих в семейство Unix, с каждым пользователем ассоциирован список привилегий, которыми этот пользователь обладает. В системах семейства Unix все гораздо проще: обычные пользователи не обладают никакими привилегиями. Для выполнения привилегированных функций существует пользователь c численным идентификатором 0 - суперпользователь (superuser), который обладает, подобно христианскому Господу Богу, всеми мыслимыми правами, привилегиями и атрибутами. По традиции суперпользователь имеет символьное имя root - ``корень''. Система списков привилегий предоставляет большую гибкость, чем один сверхпривилегированный суперпользователь, потому что позволяет администратору системы передать часть своих функций, например выполнение резервного копирования, другим пользователям, не давая им при этом других привилегий. Однако, как и ACL, эта схема приводит к большим накладным расходам при контроле прав доступа: вместо сравнения идентификатора пользователя с нулем мы должны сканировать список привилегий, что несколько дольше. В некоторых ситуациях нужен более тонкий контроль за доступом, чем управление доступом на уровне файлов. Например, для изменения информации о пользователе необходим доступ на запись к соответствующей базе данных, но не ко всей, а только к определенной записи. Вполне естественно и даже необходимо дать пользователю возможность менять пароль, не обращаясь к администратору. С другой стороны, совершенно недопустима возможность менять пароли других пользователей. Одним из решений было бы хранение пароля для каждого из пользователей в отдельном файле, но это во многих отношениях неудобно. Другое решение может состоять в использовании модели клиент-сервер с процессом-сервером, исполняющимся с привилегиями администратора, который является единственным средством доступа к паролям. Например, в Windows NT весь доступ к пользовательской базе данных осуществляется через системные вызовы, то есть функции процесса-сервера исполняет само ядро системы. Этот подход позволяет решить проблему контроля доступа именно к пользовательской базе данных, но аналогичная проблема возникает и в других ситуациях. В системах семейства Unix для этой цели был предложен оригинальный механизм, известный как setuid (setting of user id - установка [эффективного] идентификатора пользователя). В Unix каждая задача имеет два пользовательских идентификатора: реальный и эффективный. Реальный идентификатор обычно совпадает с идентификатором пользователя, запустившего задание. Для проверки прав доступа к файлам и другим объектам, однако, используется эффективный идентификатор. При запуске обычных задач реальный и эффективный идентификаторы совпадают. Несовпадение может возникнуть при запуске программы с установленным признаком setuid. При этом эффективный идентификатор для задачи устанавливается равным идентификатору хозяина файла, содержавшего программу. *Признак setuid является атрибутом файла, содержащего загрузочный модуль программы. Только хозяин может установить этот признак, таким образом передавая другим пользователям право исполнять эту программу от своего имени. При модификации файла или при передаче его другому пользователю признак setuid автоматически сбрасывается. * Так, например, программа /bin/passwd принадлежит пользователю root, и у нее установлен признак setuid. Любой пользователь, запустивший эту программу, получает задачу, имеющую право модификации пользовательской базы данных - файлов /etc/passwd и /etc/shadow. Однако прежде чем произвести модификацию, программа passwd проверяет допустимость модификации. Например, при смене пароля она требует ввести старый пароль. Сменить пароль пользователю, который его забыл, может только root. Другим примером setuid-программы может служить программа /bin/ps (process status - состояние процессов). Системы семейства Unix не предоставляют системных вызовов для получения статистики об исполняющихся процессах. Программа /bin/ps анализирует виртуальную память ядра системы, доступную как файл устройства /dev/kmem, находит в ней список процессов и выводит содержащиеся в списке данные. Естественно, только привилегированная программа может осуществлять доступ к /dev/kmem. Механизм setuid был изобретен одним из отцов-основателей Unix Деннисом Ритчи и запатенован фирмой AT&T в 1975 г. Через несколько месяцев после получения патенту был дан статус public domain. Официально фирма AT&T объяснила это тем, что плату за использование данного патента нецелесообразно делать высокой, а сбор небольшой платы с большого числа пользователей неудобен и тоже нецелесообразен. Механизм setuid позволяет выдавать привилегии, доступные только суперпользователю, как отдельным пользователям (при этом setuid-программа должна явным образом проверять реальный идентификатор пользователя и сравнивать его с собственной базой данных), так и группам (при этом достаточно передать setuid-программу соответствующей группе и дать ей право исполнения на эту программу), таким образом отчасти компенсируя недостаточную гибкость стандартной системы прав доступа и привилегий в системе Unix. В надежной Unix-системе административные задачи разделены на несколько различных ролей; каждая из них может быть поручена одному лицу или разным. Каждой роли соответствуют отдельные полномочия; такое соответствие помогает отслеживать происходящее. В соответствии с распределение административных ролей устанавливаются следующие полномочия ядра: configaudit (право модификации параметров учета) writeaudit (право записи в журнал учета) execduid (право выполнять программы с битом переустановки) chmodsugid (право устанавливать бит переустановки) chown (право изменять владельца объекта) suspenaudit (приостановка учета процесса) Один из важных аспектов надежной системы - локализация потенциальных проблем, связанных с безопасностью. Ограничительный механизм распадается на три части: парольные ограничения ограничения на использование терминалов входные ограничения Администратор опознавания может позволять пользователям самостоятельно вводить пароли или использовать сгенерированные пароли. Пароль может подвергаться проверке на очевидность. Для паролей контролируется "время жизни"; выделяются следующие состояния: пароль корректен пароль просрочен (пользователь может войти в систему и изменить пароль - если у него есть на это полномочие) пароль мертв (пользователь заблокирован; необходима помощь администратора) Пользователи часто пытаются сопротивляться принудительной периодической смене паролей, немедленно восстанавливая предыдущее значение. Чтобы помешать этому, кроме максимального устанавливается еще и минимальное время жизни паролей. Терминал - это дверь в систему. терминалы могут быть защищены от попыток вторжения в систему. Можно установить максимальное число неудачных попыток входа в систему. После того, как это число исчерпано, терминал блокируется; разблокировать его может только администратор. Кроме того, можно специфицировать интервал между двумя попытками входа. С каждым зарегистрированным пользователем можно связать те же ограничения на попытки входа, что и с терминалом. Если пользователь в течение длительного времени не вводит никаких команд, он, скорее всего, закончил работу и просто забыл выйти из системы. надежная система позволяет специфицировать отрезок времени, по истечении которого бездействующие пользователи принудительно "выводятся" из системы. Поддерживается возможность генерировать отчеты о различных аспектах функционирования системы: пароли, терминалы, входы. |