Использование 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
позволит им редактировать только указанный файл. Это важно для предотвращения того, чтобы злонамеренный пользователь отредактировал другой сервис upstart (например, /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
предлагает только шаблоны глобусов , это *
будет соответствовать чему угодно - это не регулярное выражение!
(Редактировать: я подумал, не могли бы вы сойтись с вышеперечисленным в вашей ситуации, потому что нет никаких подпапок под 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
или исполняемый файл, чтобы проверить, являются ли аргументы, переданные пользователем, допустимыми, и выполняйте их запрос, только если они есть.