Как обойтись без прав root во FreeBSD. Часть 1


Майкл Лукас
перевод Станислава Лапшанского
Впервые опубликован: http://www.computerra.ru.

Суперпользовательский пароль может стать причиной конфликтов в любой организации. Большинство системных администраторов категорически против передачи пароля, даже если он требуется людям, отвечающим за обслуживание некоторых частей системы. Если такой системный администратор не знает как разрешить это противоречие, он может помешать людям выполнять их работу. Немало администраторов: раздают суперпользовательский пароль всем желающим, а затем плачутся окружающим на нестабильную работу системы. Система UNIX имеет широкие возможности для устранения необходимости отдавать административный пароль в чужие руки. В этом цикле статей мы всесторонне рассмотрим вопрос минимизации использования суперпользовательского аккаунта для выполнения целого ряда задач администрирования. В данной статье мы остановимся на методике объединения пользователей в административные группы.

Наиболее типичная ситуация выглядит так: младший администратор отвечает за администрирование определенной части системы. Под моим руководством состоит несколько администраторов DNS. Им не приходится устанавливать программное обеспечение, перекомпилировать ядро и вообще решать низкоуровневые административные задачи. Их задача - отвечать на запросы электронной почты, вносить изменения в файлы описания зон и после этого перезапускать named. Обычно, младшему администратору, недавно принятому на работу, кажется что для этого ему необходимы полномочия суперпользователя. Однако правильное использование механизма групп вкупе с несложным планированием позволят вам вообще отказаться от выдачи кому-либо суперпользовательского пароля. В этой статье мы воспользуемся групповой системой безопасности для администрирования файлов DNS зон. Подобная техника может применяться для управления многими другими составными частями системы.

UNIX подразделяет пользователей на группы, каждая группа состоит из людей, которые выполняют определенные административные функции. У вас может быть создана группа web, членами которой будут пользователи, имеющие право редактировать содержимое веб-страничек, или группа dns, в которую включены люди, администрирующие ваш DNS-сервер. В зависимости от используемой вами системы, она может как иметь, так и не иметь по умолчанию группы с подобными именами. Например, операционные системы NetBSD и OpenBSD создают при установке пользователя и группу с именем named, а FreeBSD называет их bind, во всех случаях они предназначены для использования сервером имен. Предопределенные группы и пользователи широко используются разнообразными системными программами. Например, веб-сервер обычно выполняется с правами пользователя www.

Для пользователей, которым нужен доступ к используемым этими программами файлам, нам необходимо создать отдельную группу. Однако у нас нет необходимости создавать пользователя с именем, совпадающим с названием этой группы. Информация о группах содержится в файле /etc/group. Каждая строка в этом файле состоит из четырех колонок, разделенных двоеточием.

В первой колонке содержится название группы. Название может быть любым, если вам хочется, назовите группу администраторов DNS-сервера "losers" (неудачники). Однако в целом разумно давать группе имя, соответствующее ее предполагаемому использованию, так если сегодня вы решите объединить администраторов почтового сервера в группу "xyzzy", то вспомните ли вы, для чего нужна эта группа, скажем, через шесть месяцев?

Поэтому всегда выбирайте название группы имеющее какой-то смысл.

Второе поле содержит зашифрованный пароль группы. Групповые пароли плохо защищены и их использование является небезопасным, поэтому большинство современных UNIX систем их вообще не поддерживают. Однако существует немало UNIX'ов, в которых они до сих пор применяются, поэтому мы о них и упоминаем. Вместо того, что бы оставлять это поле пустым, для его заполнения, мы воспользуемся символом "звездочка".

В третьем столбце хранится уникальный идентификатор группы (GID). Масса системных программ во FreeBSD пользуется именно идентификаторами, а не именами групп. Файл /etc/group сортируется в порядке возрастания GID.

В последнем поле содержится список имен пользователей, которые входят в группу. Для того что бы добавить пользователя в группу, просто добавьте его имя в этот список. Имена в списке отделяются друг от друга запятыми.

Для того что бы создать группу, вы должны выбрать число, которое будет ее уникальным идентификатором. Это число не должно использоваться другими пользователями и программами. Для таких групп, как создаваемая нами группа "dns", я обычно выбираю GID на единицу отличающийся от идентификатора родственной системной группы. Например во FreeBSD группа "bind" имеет идентификатор равный 53 (53-й порт используется для работы с сервером имен). Поэтому пусть создаваемая нами группа имеет GID, равный 54. В эту группу я добавлю пользователей "chris", "phil" и "michael", так что наша новая запись в файле /etc/group будет выглядеть следующим образом:
dns:*:54:chris,phil,michael

После того как мы отредактировали файл /etc/group, неплохо было бы проверить, не сделали ли мы ошибки. Для этого во FreeBSD включена утилита chkgrp, которая проверяет корректность файла /etc/group. Если ее запуск произошел без вывода на экран каких-либо сообщений, то все в порядке.

(Для того что бы не мучиться выбором уникального GID и вообще решить все проблемы разом, во FreeBSD существует утилита pw, которую удобно использовать для создания, удаления и модификации групп. Для создания аналогичной группы напечатайте:
$ pw groupadd dns -g 54 -M chris,phil,michael

Если вас не интересует номер GID группы (как меня например), то можно отказаться от использования ключа -g:
$ pw groupadd dns -M chris,phil,michael

Уверяю, что если вы даже мельком взглянете на man pw вы не останетесь внакладе. В операционной системе Linux так же имеется набор программ для управления пользователями и группами. Это утилиты useradd, usermod, userdel, groupadd, groupmod, groupdel. Их использование убережет вас от массы неприятностей. - прим. переводчика.)

Теперь, когда группа создана, ее можно использовать в качестве "владельца". Каждый файл в системе имеет владельцев - пользователя и группу. Вы можете узнать владельцев файла при помощи команды ls -l. Большинство неопытных администраторов обращают внимание только на владельца файла, забывая о "групповых" правах доступа.
$ ls -l
total 29
-rw------- 1 root wheel 27136 Sep 14 09:36 file1
-rwxrwx--- 1 root wheel 1188 Sep 14 09:35 file2

Из этого листинга видно, что к файлу file1 может обратиться только суперпользователь. file2 может читать суперпользователь и все члены группы wheel. Более того, если вы присутствуете в группе wheel, то вам не обязательно становиться суперпользователем, для того что бы отредактировать (т.е. писать) этот файл. Просто откройте его в редакторе, и вперед!

Для изменения группы владельцев файла применяется команда chgrp (а так же более общая команда chown, в таком виде: chown :groupname filename - прим. переводчика):
$ chgrp groupname filename

В BSD-системах wheel используется в качестве системной группы. Ее члены имеют право на использование пароля суперпользователя (имеется в виду, что при наличии этого пароля, пользователи группы wheel могут, воспользовавшись командой su, повысить свои права до суперпользовательских - прим. переводчика). В большинстве случаев нет никакой необходимости давать доступ на запись для группы wheel, поскольку это резко противоречит принципу "минимальных привилегий". Аналогично, группа bind используется для выполнения программ DNS-сервера. Ему совершенно необязательно иметь возможность записи в файлы зон (разумеется, если у вас не используется динамический DNS - прим. переводчика), поскольку иначе, если злоумышленник проникнет в ваш DNS-сервер, он сможет записать что-нибудь на диск. Этого нельзя допускать. Давайте рассмотрим следующую схему прав доступа, используемую для файлов зон на сайте blackhelicopters.org:
-rw-rw-r-- 1 mwlucas dns 486 Jun 7 10:14 blackhelicopters.org.db

Поскольку я главный администратор, я являюсь владельцем этого файла, кроме меня, все члены группы "dns" имеют возможность записи в этот файл. (На вашей системе в качестве владельца вы можете установить другого пользователя.) Таким образом члены группы "dns" имеют права для чтения и записи этого файла без использования пароля суперпользователя. И, наконец, этот файл может быть прочитан DNS-сервером (поскольку для всех пользователей системы установлен атрибут доступа на чтение - прим. переводчика).

Однако есть одна вещь, для которой все-таки необходимо знание пароля суперпользователя, он нужен для перезапуска DNS-сервера (так как без перезапуска сервер не узнает о произошедших изменениях в файле зоны - прим. переводчика). Простейшим решением проблемы будет перезапуск сервера по расписанию при помощи демона cron. Однако несмотря на это у администраторов DNS может остаться желание в определенных случаях перезапускать сервер вручную. В следующей статье цикла мы рассмотрим, как это реализовать.



Как обойтись без прав root. Часть 2

Майкл Лукас
перевод Станислава Лапшанского
Впервые опубликован: http://www.computerra.ru.

9 августа 2005 г

Оригинал статьи находится по адресу: http://www.onlamp.com/pub/a/bsd/2002/08/29/Big_Scary_Daemons.html

Правильная реализация системы безопасности на основе групп помогает резко уменьшить необходимость в применении пароля суперпользователя, однако, несмотря на это, время от времени пользователям все же необходимо выполнять команды с правами какого-нибудь другого пользователя (обычно это суперпользователь). Так как вы являетесь системным администратором, вам часто приходится стоять перед нелегким выбором, или постоянно выполнять просьбы ваших пользователей, или раздать всем желающим суперпользовательский пароль. Утилита sudo позволит разрубить вам этот гордиев узел, предоставляя третий, более рациональный путь. Впрочем, не следует забывать, что это довольно тонкая программа, требующая аккуратности при ее конфигурировании. sudo непосредственно интегрирована в OpenBSD, но с таким же успехом может быть установлена почти в любой версии UNIX в качестве стороннего приложения.

Утилита sudo является программой-посредником с установленным битом setuid, выполняющейся с привилегиями суперпользователя. Она позволяет установить гибкие правила доступа к программам, для запуска которых требуются административные полномочия. sudo получает от пользователя команду, затем сравнивает ее с внутренним списков разрешенных команд. Если пользователь имеет право на исполнение поданной команды, sudo немедленно ее выполняет. Поскольку суперпользователь может запускать программы от имени любого пользователя, sudo так же может выполнять команды от имени какого угодно наперед заданного пользователя.

При соответствующей настройке, системный администратор может позволить любому пользователю выполнять любые программы от имени любого другого пользователя. sudo очень мощная утилита, с ее помощью можно разрешить или запретить практически любой набор команд. Как результат такой гибкости, документация sudo, отпугивает новичков своей сложностью. Мы займемся конфигурированием sudo, на уровне, которого вполне должно хватить для большинства пользователей, однако вам следует помнить, что существует большое количество различных дополнительных параметров конфигурирования, которые описаны в руководстве sudo (8) и sudoers (5).

Преимущества от использования sudo не ограничиваются предоставлением четкой системы разграничения доступа. Одним из важнейших преимуществ является журналирование выполняемых пользователями команд. Каждая команда выполняемая sudo, записывается в журнал, что чрезвычайно упрощает выяснение того, кто, что и когда изменял. Кроме того, когда вы корректно настроите sudo, вы наконец сможете поменять суперпользовательский пароль и никогда больше никому его не давать. Более того, если вы все правильно настроите, то суперпользовательский пароль вообще никому не потребуется. Сокращение количества людей, знающих пароль суперпользователя ведет к увеличению защищенности вашей системы. И наконец, один и тот же конфигурационный файл программы sudo может применяться на всех ваших серверах, тем самым значительно сокращая временные затраты на администрирование системы.

Наиболее серьезным недостатком sudo является, чрезвычайно негативное отношение к ней пользователей и младших администраторов. Так как люди традиционно пользовались суперпользовательским паролем для выполнения своих действий, они подозревают, что при установке в систему sudo они потеряют некоторые прежде доступные им возможности. Для преодоления такого отношения к sudo, вы, в первую очередь должны будете удостовериться, что пользователи с ее помощью смогут выполнять свою работу в полном объеме. Если пользователи уверяют вас, что им требуется суперпользовательский пароль для выполнения других задач, то вы должны просто разобраться кто и за что отвечает. Вероятно такие пользователи брали на себя решение несвойственных им задач, вместо того, что бы озаботить ими вас.

Неправильная настройка sudo может привести к появлению дыр в безопасности системы. Бездумное конфигурирование может привести к тому, что сообразительный пользователь сможет незаконно получить права суперпользователя. Эта проблема разрешается при помощи внимательного конфигурирования и соблюдения административной политики.

Система sudo состоит из трех частей. Во-первых, это сама программа sudo (8) - программа-посредник с установленным setuid-битом, с которой непосредственно взаимодействуют пользователи. Во-вторых это конфигурационный файл sudo /etc/sudoers. Этот файл содержит таблицу прав доступа, в которой указывается кому и какие команды позволено запускать от имени какого пользователя. Его структура полностью описана в руководстве man 5 sudoers. И наконец команда visudo, которая позволяет администраторам редактировать файл sudoers без риска заблокировать себе вход в систему. Мы рассмотрим каждый компонент по очереди: visudo, sudoers и sudo.

Если файл sudoers имеет неправильный синтаксис, sudo просто не запустится. Если вы понадеетесь на sudo (имеется в виду случай, когда вы полностью отказались от использования суперпользовательского аккаунта забыв его пароль - прим. переводчика), предоставите через него доступ к файлу sudoers и при этом это файл испортите, то вы тем самым заблокируете доступ к любым действиям требующим прав суперпользователя и, к тому же, не сможете ничего исправить. Это плохо. Программа visudo (8) призвана обеспечить определенную защиту от подобных ситуаций.

Подобно утилите vipw (8), visudo (8) блокирует редактируемый файл для того чтобы в один момент времени его мог редактировать только одни человек. visudo открывает конфигурационный файл sudoers в редакторе (по умолчанию это редактор vi (1), однако такое поведение системы можно изменить, поменяв содержимое переменной $EDITOR). Когда вы покидаете редактор, visudo проверяет отредактированный файл на наличие синтаксических ошибок, о которых сообщает пользователю. Разумеется такая проверка не дает гарантии того, что конфигурационный файл будет таким как вы хотите, она просто подтверждает его синтаксическую корректность. Например утилита visudo (8) не моргнув глазом примет конфигурационный файл, в котором никто при помощи sudo сможет сделать ничего, если этот файл имеет правильный синтаксис.

Если программа visudo найдет в отредактированном файле ошибку, она выдаст на терминал номер строки в которой встретилась ошибка и спросит вас, что теперь делать:
# visudo
>>> sudoers file: syntax error, line 44 <<<
What now?

В данном случае в 44 строке мы допустили ошибку. Есть три варианта действий: вернуться к редактированию, выйти не сохраняя сделанных изменений или заставить visudo сохранить файл sudoers, несмотря на найденные ошибки.

При нажатии клавиши e, visudo вернет вас в режим редактирования, где вы сможете попытаться исправить обнаруженную ошибку.

Если нажать на x, visudo завершится и возвратит конфигурационный файл в состояние, в котором он был до начала редактирования. Сделанные вами изменения будут потеряны, но возможно это именно то, что нужно в такой ситуации, поскольку лучше иметь старую, но работающую конфигурацию, чем новую, но неработоспособную.

Клавиша Q заставит visudo принять сделанные изменения, несмотря на найденную ошибку. Не забывайте, что если конфигурационный файл содержит ошибку, sudo не запустится. Делая это, вы, в сущности, на некоторое время выключаете sudo, до тех пор, пока вы не отредактируете конфигурацию под аккаунтом суперпользователя. В подавляющем большинстве случаев это не то что вам нужно.

Файл sudoers сообщает sudo, кто может выполнять какие команды и от какого пользователя. OpenBSD хранит файл sudoers в каталоге /etc, а FreeBSD в каталоге /usr/local/etc. Никогда не редактируйте этот файл напрямую, даже если вы уверены, что точно знаете, что именно вы хотите изменить. Всегда используйте visudo.

При первом конфигурировании sudo вам может быть вам непонятен синтаксис таблицы прав доступа. Возможно, что сразу сделать все правильно вам не удастся. Однако как только вы поймете каким образом sudo устанавливает эти правила, все станет легко и просто.

Разнообразные примеры файлов sudoers, которые вы можете легко найти в Интернете, часто бывают слишком сложны и запутаны для понимания, но в них можно увидеть все интересные штучки которые предоставляет пользователю sudo. Однако базовый синтаксис очень прост. Каждая запись правил доступа в файле sudoers имеет следующий формат:
username host = command

Где username это имя пользователя, который может выполнять команду. Параметр host представляет собой имя машины, для которой применимо соответствующее правило. Таким образом есть возможность устанавливать правила для конкретной машины в сети.

В поле command содержится список команд для которых применимо данное правило.

Вы должны указать полный путь для каждой команды, или sudo не будет их распознавать. (Вы ведь не хотите, что бы пользователи могли, просто поменяв переменную $PATH, выполнять совсем другие команды с теми же именами?)

Умолчания принятые в sudo исключают случайности. Для того что бы разрешить пользователю выполнять определенную команду, вы должны написать для этого соответствующее правило. Если хотя бы одно из трех полей не будет соответствовать необходимому значению, пользователь не сможет ничего сделать.

Вы можете использовать ключевое слово ALL в любом из трех полей для указания значения подходящего для всего. Например, предположим, что я полностью доверяю пользователю chris и хочу позволить ему выполнять абсолютно любую команду от имени суперпользователя на любой машине:
chris ALL = ALL

Однако давать младшему администратору полный контроль над одной из моих машин не очень разумно. Как главный администратор, я должен знать, какие команды понадобятся Крису для выполнения его работы. Предположим, что Крис администрирует DNS-сервер. К файлам, описывающим зоны сервера имен, доступ ограничивается при помощи групп, но они не смогут нам помочь, когда понадобится стартовать, перезапустить или остановить сервер. Вот как я дал ему права на запуск программы контролирующей демона DNS-сервера:
chris ALL = /usr/sbin/ndc

Если я распространю этот файл на несколько машин, есть высокая вероятность, что далеко не на всех из них окажется сервер имен. Вот так я ограничиваю круг машин, на которых Крис сможет запускать управляющую программу, одним компьютером с именем dns1:
chris dns1 = /usr/bin/ndc

С другой стороны, Крис является еще и администратором машины почтового сервера mail. Он полностью отвечает за этот сервер, и, поэтому может выполнять на нем любые команды, как ему заблагорассудится. Я могу установить для него совершенно другие права доступа к почтовому серверу и, несмотря на это, использовать один и тот же файл sudoers на обеих машинах:
chris dns1 = /usr/bin/ndc
chris mail = ALL

Для того что бы указать несколько значений в одном поле, их можно разделять запятыми. Вот как можно разрешить Крису монтировать гибкий диск при помощи команды mount (8) и одновременно позволить управление сервером имен:
chris dns1 = /usr/bin/ndc, /bin/mount

В файле sudoers, вы можете указать sudo, что ей необходимо выполнять определенные команды от пользователя отличного от root. Для этого вставьте имя нужного пользователя в скобках перед командой. Допустим, что наш сервер имен выполняется не от имени суперпользователя, а от имени пользователя named и все команды для управления им должны запускаться от имени этого пользователя.
chris dns1 = (named) /usr/bin/ndc

Каждая запись в файле /etc/sudoers должна занимать одну строку. В связи с этим строки могут быть непомерно длинными. В таком случае вы можете перенести строку на другую воспользовавшись символом в конце строки:
chris server1 = /sbin/fdisk,/sbin/fsck,/sbin/kldload, /sbin/newfs,/sbin/newfs_msdos,/sbin/mount

Теперь, когда вы ознакомились, как задаются правила доступа, давайте поглядим, как использовать sudo. Воспользуйтесь visudo, и разрешите своему аккаунту выполнять любую команду. (Если вы смогли установить sudo, значит вы уже обладаете правами суперпользователя и, поэтому то, что вы дали своему аккаунту неограниченные привилегии, не будет дырой в безопасности).

При запуске sudo, во-первых она спросит вас пароль. Введите пароль своего аккаунта (не пароль суперпользователя). Если вы неправильно введете пароль, sudo оскорбит ваши умственные способности или родословную, и предложит ввести пароль еще раз. После третьего раза, sudo отвяжется от вас. Если вы хотите попытаться еще, запустите sudo снова.

Как только вы введете правильный пароль, sudo засечет время. Если вы попытаетесь запустить sudo в течение следующих пяти минут, она не будет запрашивать пароль. После истечения пяти минут, пароль придется вводить как обычно. Это делает жизнь проще в случае, если вам необходимо выполнить сразу несколько команд при помощи sudo, однако помните, что если вы отлучитесь от компьютера пять минут пройдут достаточно быстро.

Если вы простой пользователь и на вашей машине установлена sudo, то весьма вероятно, что вам будет интересен список команд, которые системный администратор счел допустимыми для выполнения вами при помощи sudo. Для вывода этого списка вам пригодится ключ -l:
$ sudo -l
Password:
User mwlucas may run the following commands on this host:
(root) ALL

Если у вас более серьезные ограничения чем у меня, все они будут выведены на экран.

Для того что бы выполнить команду при помощи sudo, просто поставьте перед ней слово sudo. Например, вот как можно выполнить команду su при помощи sudo:
$ sudo su
Password:

Использование sudo для доступа к аккаунту суперпользователя позволяет главному администратору надежно сохранять суперпользовательский пароль. Однако это не всегда полезно, поскольку младшие администраторы при наличии неограниченного sudo-доступа могут поменять пароль суперпользователя. В тоже время это хорошее начало для увеличения безопасности системы и применения sudo для выполнения всех команд.

При помощи sudo вы, так же можете запускать и более сложные команды передавая им все необходимые аргументы. Например, команда tail -f прекрасно подходит для просмотра последних сообщений в файле журнала, кроме того, новые записи будут появляться на экране по мере их появления в файле журнала. Просмотр некоторых файлов журналов доступен только для суперпользователя. Журнал программы sudo является отличной кандидатурой на такую роль. Наверняка вы хотите иметь возможность просмотра журналов без необходимости входить под аккаунтом суперпользователя.
$ sudo tail -f /var/log/authlog
openbsd/usr/src/usr.bin/sudo;sudo tail -f /var/log/secure
Jul 29 13:24:19 openbsd sudo: mwlucas : TTY=ttyp0 ;
PWD=/home/mwlucas ; USER=root ; COMMAND=list
Jul 29 13:30:03 openbsd sudo: mwlucas : TTY=ttyp0 ;
PWD=/home/mwlucas ; USER=root ;
COMMAND=/usr/bin/tail -f /var/log/authlog
...

Если вы обладаете достаточными правами, то вы сможете запускать программы не только от имени суперпользователя, но и от имени любого другого пользователя. Предположим, например, что у нас есть сервер баз данных, для работы с которым команды надо отдавать от имени пользователя под которым выполняется этот сервер. Вы можете указать необходимого пользователя в ключе -u. Например оператор базы данных имеет привилегии для выполнения программы dump, используемой для резервного копирования:
$ sudo -u operator dump /dev/sd0s1

Все это замечательно, но как проконтролировать использование sudo?

Сообщения от sudo журналируются в источник LOCAL2. Каждое сообщение содержит время его записи, имя пользователя, каталог, где запускалась sudo и команду, которая была выполнена.
Jul 29 11:21:02 openbsd sudo: chris : TTY=ttyp0 ;
PWD=/home/chris ; USER=root ;
COMMAND=/sbin/mount /dev/fd0 /mnt

При худшем варианте развития событий (если в системе что-то нарушится), вы сможете отследить, что происходило. Например, если одна из моих машин не можеhrкорректно перезагрузиться из-за того, что файл /etc/rc.conf испорчен или отсутствует, я могу проверить журнал sudo на предмет операций с этим файлом:
Jul 29 11:34:56 openbsd sudo: chris : TTY=ttyp0 ;
PWD=/home/chris ; USER=root ;
COMMAND=/bin/rm /etc/rc.conf

Если кто-нибудь для запуска команд, воспользовался бы командой su или даже sudo su вместо sudo, я не смог бы увидеть что привело к сбою системы. С журналами sudo я всегда могу выяснить кто виноват, как только доберусь до компьютера. Только из-за одного этого sudo стоит установить!

В следующий раз я расскажу о более сложных и интересных опциях конфигурации команды sudo, а так же о распространенных ошибках поджидающих новичков.



Как обойтись без прав root. Часть 3

Майкл Лукас
перевод Станислава Лапшанского
Впервые опубликован: http://www.computerra.ru.

9 августа 2005 г

Оригинал статьи находится по адресу: http://www.onlamp.com/pub/a/bsd/2002/09/12/Big_Scary_Daemons.html

В предыдущей статье мы рассмотрели Элементарную настройку sudo. Самым сложным этапом на пути использования sudo, несомненно является написание конфигурационного файла sudoers. Легко представить, что при наличии нескольких машин, с несколькими администраторами, которым требуются различные полномочия, файл sudoers быстро станет слишком большим и запутанным. Использование псевдонимов, может сильно упростить управление sudo и значительно прояснить конфигурационный файл.

Говоря по-русски, псевдоним - это просто группа пользователей, хостов или команд. Если служебные обязанности пользователя меняются, то для придания ему необходимых полномочий, вам следует просто добавить его в описание того или иного псевдонима. Для того что бы ваши системные операторы по прежнему могли делать резервное копирование, но при этом не имея полномочий для восстановления данных, вам придется всего лишь удалить из их псевдонима восстанавливающие команды. Когда вы запустите в эксплуатацию новый сервер, добавление имени этого сервера в соответствующий псевдоним позволит вам незамедлительно дать администраторам системы права, необходимые им для выполнения их работы.

Перед использованием в конфигурации, псевдонимы необходимо определить, поэтому описания псевдонимов обычно находится в начале файла sudoers. Определение псевдонима начинается с метки, которая указывает на вид объектов описываемых этим псевдонимом, затем идет название псевдонима и список объектов скрывающихся под объявляемым псевдонимом.

Пользовательский псевдоним описывает группу пользователей. Объявление пользовательского псевдонима начинается с метки User_Alias. Как нетрудно догадаться, пользовательский псевдоним содержит в себе список пользователей. Описанный в данном примере пользовательский псевдоним DNSADMINS, содержит двух пользователей mwlucas и chris:
User_Alias DNSADMINS = chris,mwlucas

Псевдоним Runas является специальным псевдонимом. Он определяет список пользователей от имени которых другие пользователи могут запускать свои команды.

Многие серверы имен могут выполняться от имени пользователя named. Очевидно, что администратору DNS-сервера может понадобиться запускать команды от имени этого пользователя, следовательно, вы можете определить для него Runas-псевдоним. Многие приложения в составе серверов баз данных выполняются под своим собственным пользователем. Во многих случаях системный администратор, отвечающий за эксплуатацию приложения захочет иметь возможность выполнять резервное копирование от имени пользователя operator. Вы можете создать один Runas-псевдоним для группы таких команд. Псевдоним Runas начинается с метки Runas_Alias.
Runas_Alias APPADMIN = named,dbuser,operator

"Хостовой" псевдоним является просто списком сетевых хостов. Признаком хостового псевдонима является метка Host_Alias. В списке хостов могут присутствовать DNS-имена машин, IP-адреса и адреса сетей. (Помните, что если вы используете DNS-имена, то ваша sudo-конфигурация будет подвержена уязвимостям связанным с системой DNS). Вот примеры записей со всеми тремя типами адресов:
Host_Alias DNSSERVERS = dns1,dns2,dns3
Host_Alias SECURITYSERVERS = 192.168.1.254,192.168.113.254
Host_Alias COMPANYNETWORK = 192.168.1.0/16

Командный псевдоним состоит из списка команд операционной системы. Он начинается с метки Cmnd_Alias. Запишем псевдоним, который будет объединять команды необходимые для резервного копирования и восстановления данных:
Cmnd_Alias BACKUPS = /bin/mt,/sbin/restore,/sbin/dump

Вы можете создать псевдоним, который будет объединять все команды в определенном каталоге. Предположим, что у нас есть некое приложение, которое выполняется от имени определенного пользователя, кроме того, все утилиты этого приложения находятся в домашнем каталоге этого пользователя. Вместо того, что бы указывать в псевдониме все эти команды по очереди, мы можем указать только полный путь к каталогу и образец имени файла, подходящий под все содержимое этого каталога:
Cmnd_Alias DBCOMMANDS = /usr/home/dbuser/bin/*

Для того что бы воспользоваться созданным псевдонимом просто подставьте его имя туда, куда вы обычно пишете имя пользователя, машины или команды соответственно. Выше мы определили пользовательский псевдоним DNSADMINS. Пусть пользователи упомянутые в этом псевдониме имеют право выполнять любые команды на любых серверах:
DNSADMINS ALL = ALL

Давайте предположим что пользователь Фил (Phil) управляет приложением, которое выполняется от имени определенного пользователя. Он может выполнить любую команду на сервере от имени этого пользователя. Воспользуемся ранее определенным Runas-псевдоним APPADMIN и командным псевдонимом DBCOMMANDS, включающим в себя необходимые команды.
phil ALL = (APPADMIN)DBCOMMANDS

Филу требуется делать резервное копирование данных его приложения. Мы уже упомянули пользователя operator в псевдониме APPOWNER (судя по всему автор просто забыл вставить абзац с определением псевдонима APPOWNER, однако его нетрудно восстановить: Runas_Alias APPOWNER = dbuser,operator - прим. переводчика), и описали командный псевдоним BACKUPS для осуществления резервного копирования. Скомбинируем их:
phil ALL = (APPOWNER) DBCOMMANDS, (APPOWNER) BACKUPS

Это выглядит куда проще "развернутой" записи, которую пришлось бы писать не будь у sudo конструкции псевдонимов.
phil ALL = (dbuser,operator)/usr/home/dbuser/bin/*,
(dbuser,operator)/bin/mt, (dbuser,operator)/sbin/restore,
(dbuser,operator)/sbin/dump

В данном случае некоторые права избыточны, поскольку резервное копирование не требует прав пользователя базы данных. Однако это намного лучше чем, если бы мы просто дали Филу права суперпользователя. Кроме того, для своих пользователей вы можете устанавливать насколько угодно жесткие ограничения.

Имеется возможность использовать вложенные псевдонимы. Например вы хотите объединить псевдонимы DBCOMMANDS и BACKUPS в один общий псевдоним. Разумеется объединяемые псевдонимы уже должны быть описаны перед объединением.
Cmnd_Alias DBADMINS = BACKUPS,DBCOMMANDS

sudo умеет брать информацию о группах пользователей определенных в операционной системе и использовать ее в качестве псевдонимов в файле sudoers. Вместо того, что бы определять пользовательский псевдоним вы можете просто взять имя группы пользователей и использовать его, поставив впереди значок процента %, для того, что бы показать, что это именно имя группы.
%wheel ALL = ALL

Теперь любой человек входящий в группу wheel сможет на любом сервере выполнять команды с правами суперпользователя.

Вы можете использовать имена псевдонимов повторно. Пользовательский псевдоним DBADMINS это совсем не то же самое что командный псевдоним DBADMINS. Это вполне позволяет делать следующие записи в файле sudoers.
Cmnd_Alias DBAPP = /usr/home/dbuser/bin/*
Host_Alias DBAPP = server8,server12,server15
RunasAlias DBAPP = dbuser,operator
User_Alias DBAPP = chris,mwlucas
DBAPP DBAPP = (DBAPP) DBAPP

Это отличный пример "технически возможного, но совершенно аморального" (имеется в виду сакраментальная фраза, характеризующая текущую точку зрения на вопрос клонирования человека - прим. переводчика). Если вы будете пользоваться этой возможностью, то кто-нибудь посторонний, кому придется разбираться в такой конфигурации, обязательно помянет вас кратким обидным словом (более того, если через некоторое время вам придется вернуться к конфигурации sudo, вы сами будете рвать на себе волосы - прим. переводчика). Кроме того, подобные вещи обычно приводят к телефонным звонкам в середине того краткого времени, которое отводит на свой сон главный администратор.

Теперь давайте пробежимся по неприятным ситуациям в которые попадают даже опытные системные администраторы. Иногда вам требуется запретить пользователям выполнять определенный набор команд, разрешив при этом выполнение всех остальных. Вы можете попробовать сделать это при помощи оператора отрицания !. Имейте в виду, что это абсолютно неэффективно. Поскольку такие попытки делаются довольно часто, мы обсудим, как это работает и в чем тут подвох.

Во-первых определим командный псевдоним, в котором будут описаны запрещенные команды. Часто запрещаются оболочки командных интерпретаторов (поскольку если вы можете выполнить оболочку от имени определенного пользователя, то вы можете делать все под именем этого пользователя) и команда su (1). А теперь давайте запретим вашему пользователю использовать команды описанные этим псевдонимом при помощи модификатора !:
Cmnd_Alias SHELLS = /bin/sh,/bin/csh,/usr/local/bin/tcsh
Cmnd_Alias SU = /usr/bin/su
mwlucas ALL = ALL,!SHELLS,!SU

Выглядит замечательно, не правда ли? Поглядим, как это работает:
$ sudo sh
Password:
Sorry, user mwlucas is not allowed
to execute '/bin/sh' as root on openbsd.

Вспомните, sudo использует полные пути для описания команд. Вы позволили пользователю запускать любую требующуюся ему команду, кроме нескольких запрещенных, описанных полными именами. Все что требуется пользователю для запуска запрещенных команд, это сменить путь к их файлам. Простейшим средством для реализации этой затеи будет простое копирование файлов в необходимое место.
$ id
uid=1000(mwlucas) gid=1000(mwlucas) groups=1000(mwlucas), 0(wheel)
$ cp /bin/sh .
$ sudo ./sh
$ id
uid=0(root) gid=0(wheel) groups=0(wheel), 2(kmem), 3(sys),
4(tty), 5(operator), 20(staff), 31(guest)

Привет, root!

Надеюсь вы теперь поняли, что такой способ ограничений может быть чрезвычайно просто обойден, любым человеком, мало-мальски разбирающимся в работе sudo. Эта проблема хорошо документирована в разнообразной литературе, а так же поставляемом с sudo руководстве. Но, несмотря на это, люди настойчиво наступают на одни и те же грабли, используя ограничения такого рода для защиты рабочих машин.

Если у вас есть пользователи, которым вы не можете доверить неограниченный доступ к системе, не пользуйтесь исключением команд при описании их привилегий. Ограничьтесь списком явно разрешенных для выполнения команд. Исключение команд может пригодиться только в случае доверенных пользователей (работников), в качестве напоминания (крайне спорно, на мой взгляд лучше вообще не пользоваться, что бы не вводить "во искушение" - прим. переводчика). Т.е. когда я зайду на машину и напечатаю sudo su, sudo скажем мне, что мне не стоит выполнять здесь такие команды.

На этом мы завершим наш разговор о sudo. Я можете узнать больше о sudo на ее сайте (см. http://www.courtesan.com/sudo/), а так же прочитав посвященные ей страницы руководства man 8 sudo и man 5 sudoers.

http://www.onlamp.com/pub/a/bsd/2002/08/16/Big_Scary_Daemons.html.

Обновлено: 12.03.2015