Использование CmndAlias ALLникогда не будет безопасным
Есть 1000 способов бегать service network restartбез дела sudo service network restart. Вот пример того, что может попробовать непослушный пользователь:
$ echo "service network restart" > /tmp/hax
$ chmod a+x /tmp/hax
$ sudo /tmp/hax
Если вы предоставите пользователям ALLпсевдоним команды, а затем попытаетесь создать черный список, они всегда смогут найти способ обойти его. Черный список Bash, и они будут использовать Python. Черный список Python, и они будут использовать Perl. Черный список Perl, и они будут использовать PHP. Никто не хочет этого!
Если вы действительно не хотите , чтобы кто - то что - то сделать, вы должны делать , как говорит Томас, и создать белый список вещей , которые они имеют право делать.
Настройка белого списка с исключением
Пример небольшого белого списка с исключением можно найти в нижней части man sudoers:
pete HPPA = /usr/bin/passwd [A-Za-z]*, !/usr/bin/passwd root
The user pete is allowed to change anyone's password except for root on the HPPA
machines. Note that this assumes passwd(1) does not take multiple user names
on the command line.
(На самом деле этот пример с man-страницы небезопасен и может быть использован для изменения пароля пользователя root! См. Комментарии ниже.)
Мы можем попытаться приспособить , что ваш случай, чтобы предложить все serviceкоманды в группе сотрудников, но исключают те service networkкоманды , которые касаются вас:
%staff ALL = /usr/sbin/service *, \
! /usr/sbin/service *network*, \
! /usr/sbin/service *NetworkManager*
(Эта ALLпозиция относится к Host_Alias, а не к Cmnd_Alias - не так ли сбивает с толку?)
Пользователь не сможет запустить sudo bashили sudo teeили sudo wgetили или sudo /path/to/malicious_script. Вы можете внести в белый список больше команд администратора для своих пользователей, если будете осторожны. Просто будьте конкретны!
Примечание: я добавил *перед словом networkвыше, на случай, если serviceв будущем в инструмент будет добавлен безвредный флаг . Давайте представим, что --verboseв будущем будет добавлен флаг, тогда пользователи смогут запустить следующее:
$ sudo service --verbose network restart
Поэтому нам нужно *использовать любые флаги перед именем службы. Единственным недостатком является то, что это может заблокировать другие службы, которые вы на самом деле не возражаете против запуска пользователей, например, вызванная служба safe-networkили network-monitorтакже будет отклонена.
Разрешить пользователям редактировать файл с помощью групповых прав
Ниже вы можете найти различные попытки использования rnanoчерез , sudoчтобы пользователи могли редактировать файл или файлы. Но на самом деле они сложнее и опаснее, чем должны быть.
Гораздо более простым и безопасным решением является изменение групповых разрешений для определенных файлов, для которых вы хотите открыть права редактирования. Вот пара примеров:
### Give steve the ability to edit his nginx config:
$ chgrp steve /etc/nginx/sites-available/steves_dodgy_project
$ chmod g+rw /etc/nginx/sites-available/steves_dodgy_project
### Let all members of the staff group edit the group_website config:
$ chgrp staff /etc/nginx/sites-available/group_website
$ chmod g+rw /etc/nginx/sites-available/group_website
Если вам нужен более детальный контроль (например, доступ только для 3 пользователей, но не для всех сотрудников), вы можете создать новую группу, используя addgroup команды и добавить в нее всего несколько пользователей.
Позвольте пользователям редактировать файл через sudo
Остальная часть этого ответа стала расследованием того, как легко оставить дыры в вашем sudo конфигурации, когда вы пытаетесь предложить пользователям гибкость. Я бы не рекомендовал делать что-либо из следующего!
Если вы хотите предоставить своим пользователям доступ к редактированию определенного файла, вы можете попробовать использовать rnano:
%staff ALL = /bin/rnano /etc/nginx/sites-available/host
rnanoтолько позволит им редактировать указанный файл. Это важно для того, чтобы злонамеренный пользователь не мог редактировать другую службу выгрузки (например,/etc/init.d/urandom ) и добавить в него строку, которая будет работать service network restart.
К сожалению, я не нашел способа rvimдостаточно ограничить (пользователь по-прежнему может открыть любой файл, используя :e), поэтому мы застряли сnano .
К сожалению, разрешить пользователям редактировать несколько файлов намного сложнее ...
Позвольте пользователям редактировать несколько файлов (намного сложнее, чем должно быть)
1. Небезопасные подходы
Будьте осторожны с подстановочными знаками! Если вы предлагаете слишком большую гибкость (или любую гибкость), ее можно использовать:
%staff ALL = /bin/rnano /etc/nginx/sites-available/* # UNSAFE!
В этом случае злонамеренный пользователь сможет отредактировать любой другой сценарий службы выскочки, а затем запустить его:
$ sudo rnano /etc/nginx/sites-available/../../../any/file/on/the/system
(Судо действительно предотвращает .и.. расширению команды, но, к сожалению, не аргументам.)
Я надеялся, что что-то подобное может сработать, но это все еще небезопасно:
%staff ALL = /bin/rnano /etc/nginx/sites-available/[A-Za-z0-9_-]* # UNSAFE!
Поскольку в sudoнастоящее время предлагаются только шаблоны глобусов , которые *будут соответствовать чему угодно - это не регулярное выражение!
(Edit: я рассмотреть , если вы могли бы уйти с вышеизложенным в вашей ситуации, потому что нет вложенных папок под sites-available. Мы сделали спрос один символ будет соответствовать после того, как папки, и /... Должны терпеть неудачу после того, как имя файла , однако это не является выполнимое решение, потому что rnanoпринимает несколько аргументов. И вообще, это все равно будет небезопасно для папки с подпапками!)
Даже если у нас нет подпапок и мы исключаем какие-либо строки, содержащие /../правило, правило, предлагающее *глоб, все еще может быть использовано, потому что rnanoпринимает несколько аргументов (циклически перебирая их <C-X>, и пространство счастливо принимается *глобаном.
$ rnano /etc/nginx/sites-available/legal_file /then/any/file/on/the/system
2. толкать конверт (также в конечном итоге небезопасно)
Так что, если мы отвергаем любые строки, содержащие пробелы, или пытаемся достичь /..? Тогда окончательное работоспособное решение может быть таким:
# I tried hard to make this safe, but in the end I failed again.
# Please don't use this unless you are really smart or really stupid.
%staff ALL = /bin/rnano /etc/nginx/sites-available/*, \
! /bin/rnano */..*, \
! /bin/rnano /etc/nginx/sites-available/, \
! /bin/rnano */., \
! /bin/rnano * *
# CONCLUSION: It is still NOT SAFE if there are any subfolders, due to
# the bug in rnano described below.
Мы принимаем что-либо «под» папкой, но мы также отклоняем любой вызов, rnanoесли /..или /.или переданы, или если папка предназначена непосредственно. (Технически /.исключение делает/.. исключение излишним, но я оставил оба для ясности.)
Я обнаружил, что папка и /.исключения были необходимы, потому что в противном случае пользователь мог бы выбрать саму папку. Теперь вы можете подумать, rnanoчто заблокирует, если указывает на папку, но вы ошибаетесь. На самом деле моя версия (2.2.6-1ubuntu1) запускается с небольшим предупреждением и пустым файлом, а затем <C-X>просит меня ввести любое имя файла, к которому я хочу сохранить, открывая новый вектор атаки! Ну, по крайней мере, он отказался перезаписать существующий файл (в одном тесте, который я сделал). В любом случае, поскольку нет возможности занести в черный список подпапки с помощью sudo, мы должны сделать вывод, что этот подход снова небезопасен. Извините, пользователи!
Это открытие заставило меня усомниться в тщательности nano«ограниченного» режима. Они говорят, что цепочка настолько же сильна, насколько ее самое слабое звено. Я начинаю чувствовать комбинацию sudoчерной магии черного списка и, rnanoвозможно, не более безопасна, чем цепь ромашек.
3. Безопасные, но ограниченные подходы
Глобусы очень ограничены - они не позволяют нам сопоставить класс персонажа несколько раз. Вы можете предложить несколько файловых изменений, если все ваши имена файлов имеют одинаковую длину (в этом случае hostследует одна цифра):
%staff ALL = /bin/rnano /etc/nginx/sites-available/host[0-9] # SAFE
Но если вы хотите предоставить пользователю доступ к редактированию различных файлов, вам может потребоваться явно указать каждый файл:
%staff ALL = /bin/rnano /etc/nginx/sites-available/hothost \
/bin/rnano /etc/nginx/sites-available/coldhost \ # SAFE
/bin/rnano /etc/nginx/sites-available/wethost \
/bin/rnano /etc/nginx/sites-available/steves_dodgy_project
Не поддавайтесь искушению использовать* в любой момент. Смотрите разделы 1. и 2. выше, почему! Помните: одна маленькая ошибка может поставить под угрозу всю учетную запись суперпользователя и всю систему.
4. Напишите свой собственный аргумент проверки (безопасность теперь ваша ответственность)
Я надеюсь, что они добавят поддержку регулярных выражений sudoв будущем; это может решить множество проблем при правильном использовании. Но нам также может понадобиться возможность проверить свойства аргументов (чтобы разрешить только файлы, только папки или только определенные флаги).
Но есть одна альтернатива для создания гибкости в sudo. Сваливать ответственность:
%staff ALL = /root/bin/staffedit *
Затем напишите свой собственный staffeditскрипт или исполняемый файл, чтобы проверить, являются ли аргументы, переданные пользователем, допустимыми, и выполняйте их запрос, только если они есть.
networkingиnetwork-manager? Кроме того, почему ваши пользователи имеютsudoдоступ? Они не должны, если вы не хотите, чтобы у них были полные права суперпользователя.