Как запретить пользователям sudo запускать определенные команды?


29

У меня очень чувствительная сетевая настройка, и я действительно не хочу с ней связываться. Моя сеть состоит из группы пользователей с привилегиями sudo.

Я хочу остановить их бег

service NetworkManager restart
service network restart

команды.

Есть ли способ, которым я могу достичь этого?


Какой дистрибутив вы используете? Названия сервисов относятся к конкретному дистрибутиву, и я не знаю ни одного дистрибутива, который бы использовал те имена, которые у вас есть. Вы имеете в виду networkingи network-manager? Кроме того, почему ваши пользователи имеют sudoдоступ? Они не должны, если вы не хотите, чтобы у них были полные права суперпользователя.
Terdon

@terdon Я решил это. Спасибо. Я не могу опубликовать это как ответ, потому что я новый пользователь
шехар

Да, можете, пожалуйста. Я также хотел бы знать ответ, который вы нашли.
Terdon

@terdon конечно, но говорят, что мне нужно подождать 8 часов, чтобы опубликовать свой собственный ответ, потому что у меня нет даже 10 репутации
шехар

1
Ах да, извините, вам действительно нужно подождать. Я только что проголосовал, теперь у вас есть представитель :)
terdon

Ответы:


47

Использование 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скрипт или исполняемый файл, чтобы проверить, являются ли аргументы, переданные пользователем, допустимыми, и выполняйте их запрос, только если они есть.


5
Этот ответ занял много времени, но, наконец, я понял, как работает sudo. Я несколько раз сдавался в прошлом, находя ALL=(ALL:ALL) ALLслишком мало семантики, но я всегда предполагал, что где-то у него будет достойная проверка аргументов ... Я был неправ. Это действительно очень ограничено. Даже исключение root-пароля passwd, предлагаемое на man-странице, может быть сломано простым аргументом командной строки sudo passwd -q root. Авторы sudo перечисляют [некоторые альтернативы] (sudo.ws/sudo/other.html) на своем веб-сайте. Я надеюсь, что они добавят поддержку регулярных выражений в будущем.
Joeytwiddle

Вы специально используете rnanoв своем описании здесь, потому что это версия nano, в которой отсутствует функция «сохранить как»? Я не знаком с программой.
Шадур

Да. Если мы заботимся о безопасности, редактор должен редактировать только один указанный файл и не должен иметь возможности открывать оболочку. Для информации, $ man nanoзатем/-R<Enter>
joeytwiddle

Исправление: Для того, чтобы сломать пример Питом, то -qдолжны прийти потом: sudo passwd root -q. Пример Пита можно укрепить, исключив *root*.
Joeytwiddle

Подумайте об использовании, sudoeditчтобы безопасно включить изменение файла с помощью sudo.
Totor

5

Сначала откройте файл sudoers с помощью sudo visudo. Добавление user ALL=!/usr/sbin/serviceбудет, IIRC, запретить serviceкоманду для пользователя user.

Источники: http://nixcraft.com/showthread.php/15132-Sudo-Exclude-Commands-And-Disable-sudo-su-Bash-Shell


Это также прекратит работу других служб, и я этого не хочу. Спасибо за ответ. :)
шехар

в то время как ваш ответ не помог мне точно, но помог найти решение, спасибо. но вы знаете, чтобы высказать свое мнение или опубликовать мой рабочий ответ, мне не хватает репутации. Я обязательно буду благодарен, когда я буду. Спасибо.
шехар

2
Да, но все же, как и другие заявляли, вы должны быть очень осторожны с этим. Есть много способов получения доступа. Любая команда, которая может порождать оболочку и так далее. Проще понять, какие команды им действительно нужны, и разрешить их, вместо того, чтобы пытаться исключить все «запрещенные».
Бонси Скотт

3
Белые списки не поддерживаются во многих сценариях. Реальная цель может заключаться не в том, чтобы помешать им что-то сделать, а в том, чтобы не дать им сделать что-то плохое по ошибке, не ограничивая их иным образом. Черные списки хороши в этих случаях. Вы заносите в черный список способы, которыми разумный пользователь будет выполнять эту задачу. Но внесение в черный список с помощью sudo может быть недостаточным - люди могут использовать sudo bash. Один из подходов состоит в том, чтобы обернуть команду «service», и в случаях, когда вы не хотите, чтобы они использовали, сообщите им. Но вы никогда не перечислите все хорошие действия в белый список, и все плохие в черный список.
Боб Кернс

1
Я согласен с тобой, Боб. Чтобы обеспечить гибкость, не предоставляя полный доступ, вам часто нужно будет развернуть собственное решение в качестве вспомогательного сценария и добавить в белый список только этот сценарий. Белые списки sudo могут делать то, что вам нужно, но часто они либо слишком ограничены, либо слишком просты в использовании.
Joeytwiddle

5

Я нашел решение.

Я открыл терминал и перешел в пользователя root, su -затем набрал текст visudoдля редактирования.

тогда в конце я написал такие строки, как

user ALL=!/etc/init.d/NetworkManager restart
user ALL=!/etc/init.d/network restart

Тогда я сохранил и закрыл и перезапустил тоже.

Теперь, если я печатаю как service network restartили service NetworkManager restartтогда, это не позволяет мне и выдает ошибку вроде

Sorry user is not allowed to execute '/sbin/service NetowkrManager restart' as root on localhost.localdomain

и аналогично для service network restartкоманды также.


12
Это будет работать для неопытных и неопытных пользователей, но легко обойти ограничения sudo (например, sudo cp -p /etc/init.d/network /etc/init.d/network-not-in-sudoи тогда sudo /etc/init.d/network-not-in-sudo restart). Вот почему гораздо безопаснее создавать включения, а не исключения в файле sudoers, например, указывать, с какими службами им разрешено взаимодействовать.
Томас

Все, что делает «перезапуск сервисной сети», вы можете делать с другими командами, например, в сетевом скрипте init.d. Я даже не буду пытаться перечислить их здесь. Но если вы хотите, например, на самом деле предотвратить изменение состояния интерфейса, тогда мне кажется, что политика SELinux - это то, что нужно. Это сложная тема, но когда белый список слишком ограничен или обременителен, а черный список неадекватен, это, вероятно, ваш лучший вариант. Он реализован в ядре и позволяет вам ограничивать доступ к сетевым интерфейсам (и другим ресурсам) даже пользователям sudo'd.
Боб Кернс

Если это возможно с SELinux, то было бы более приятно. @BobKerns Спасибо. Я постараюсь таким образом.
шехар

3

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

joe@box:~$ sudo bash root@box:~# service network restart

Или другую забавную команду, которую они могли бы использовать, чтобы обойти ваши ограничения в файле sudoers:

sudo visudo

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


Да. Следует избегать команд, которые могут порождать оболочку изнутри.
Бонси Скотт

1
Проблема в том, что вы хотите защитить не команды, а состояние объектов ядра, таких как таблицы маршрутизации, интерфейсы и т. Д., Независимо от того, какая команда (или системный вызов) используется. И вы хотите защитить его от некоторых, но не от всех пользователей root. SELinux разработан вокруг такого сценария. Но сначала я бы начал с обзора того, почему все эти пользователи имеют доступ к sudo. Если им нужно всего лишь сделать несколько конкретных вещей, вам могут понадобиться операции с «белым списком» в sudoers.
Боб Кернс

2

Используйте firejail, чтобы ограничить пользователей песочницами.

https://github.com/netblue30/firejail/

Установите firejail как shell вместо bash в / etc / passwd для каждого пользователя, которого вы хотите ограничить. Он очень прост в использовании и имеет хорошую документацию.

Пример:

user:x:1000:1000:user:/home/user:/usr/bin/firejail
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.