如何防止sudo用户运行特定命令?


29

我的网络设置非常敏感,我真的不想弄乱它。我的网络由一群拥有sudo特权的用户组成。

我想阻止他们跑

service NetworkManager restart
service network restart

命令。

有什么办法可以做到这一点?


您正在使用哪个发行版?服务名称是特定于发行版的,我不知道使用您那里的名称的任何发行版。你是说networkingnetwork-manager?另外,为什么您的用户有权sudo访问?除非您希望它们具有完整的root特权,否则不应该这样做。
terdon 2014年

@terdon我已经解决了。谢谢。我无法将其发布为答案,因为我是新用户
shekhar 2014年

是的,可以,请这样做。我也想知道你找到的答案。
2014年

@terdon可以肯定,但是它的说法是我需要等待8小时才能发表自己的答案,因为我什至没有10个声誉
shekhar 2014年

1
啊,是的,对不起,您确实需要等待。我刚刚投票,您现在拥有代表:)
terdon 2014年

Answers:


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.

(实际上,手册页中的此示例是不安全的,可以利用它更改root的密码!有关如何操作,请参见下面的评论。)

我们可以尝试根据您的情况进行调整,以service向人员组提供所有命令,但排除service network您有关的命令:

%staff ALL =   /usr/sbin/service *,                            \
             ! /usr/sbin/service *network*,                    \
             ! /usr/sbin/service *NetworkManager*

(该ALL位置是指Host_Alias,而不是Cmnd_Alias-是令人困惑的吗?)

用户将无法运行sudo bashsudo teesudo wgetsudo /path/to/malicious_script。如果您小心的话,可以将更多管理员命令列入白名单。只是具体一点!

注意:我*network上面的单词前添加了“ before” ,以防万一service将来会在工具中添加无害标志。假设--verbose将来添加了一个标志,那么用户将能够运行以下命令:

$ sudo service --verbose network restart

因此,我们需要*在服务名称之前使用任何标志。一个缺点是,这可能会阻止您实际上并不介意用户运行的其他服务,例如称为safe-networknetwork-monitor也将被拒绝的服务。


允许用户使用组权限编辑文件

在下面,您可以找到各种尝试rnanosudo以使用户可以编辑一个或多个文件。但是实际上,它们比应有的更复杂,更危险。

一个更简单,更安全的解决方案是更改要为其打开编辑权限的特定文件的组权限。以下是几个示例:

### 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

(Sudo实际上阻止...扩展了该命令,但不幸的是没有扩展该参数。)

我希望这样的事情可能会起作用,但是仍然不安全:

%staff ALL = /bin/rnano /etc/nginx/sites-available/[A-Za-z0-9_-]*   # UNSAFE!

由于sudo当前仅提供glob模式,因此*可以匹配任何内容 -它不是正则表达式!

(编辑:我确实考虑过您是否遇到上述情况,因为下面没有子文件夹sites-available。我们确实要求在文件夹后匹配一个字符,并且/..在文件名后应该失败。但这不是可行的解决方案,因为它rnano接受多个参数。而且总的来说,这对于带有子文件夹的文件夹还是不安全的!)

即使我们没有子文件夹,也不包含任何包含/../的行,*仍然可以利用提供glob 的规则,因为它rnano接受多个参数(在上循环遍历它们<C-X>,并且该空间很高兴地被*glob 接受。

$ 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是否传递if /../.or 或直接将文件夹作为目标的任何调用。(从技术上讲,/.排除使排除成为/..多余,但为清楚起见,我将两者都留了下来。)

我发现该文件夹/.需要排除,因为否则用户可以将文件夹本身作为目标。现在,您可能会认为rnano如果指向文件夹会阻塞,但是您错了。实际上,我的版本(2.2.6-1ubuntu1)开头是轻微警告,文件为空,然后<C-X>要求我输入要保存的任何文件名,从而打开新的攻击媒介!好吧,至少它拒绝覆盖现有文件(在我所做的一项测试中)。无论如何,由于无法使用sudo将子文件夹列入黑名单,因此我们必须得出结论,这种方法再次是不安全的。对不起用户!

这个发现使我怀疑nano'restricted'模式的彻底性。他们说,一条链只有最薄弱的一环才牢固。我开始感到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

请勿随时使用a*。有关原因,请参见上文第1.和2.节。切记:一小笔便会损害整个超级用户帐户和整个系统。

4.编写自己的参数检查器(现在,安全是您的责任)

我希望他们将来会增加对regexp的支持sudo;如果使用正确,它可以解决很多问题。但是我们可能还需要具有检查参数属性的功能(仅允许文件,文件夹或某些标志)。

但是有一种方法可以在sudo中创建灵活性。把钱递过去:

%staff ALL = /root/bin/staffedit *

然后编写您自己的staffedit脚本或可执行文件,以检查用户传递的参数是否合法,并且只有在执行请求时才执行。


5
这个答案花了很长时间,但最终我想我了解sudo的工作原理。过去,我在各种场合都放弃了,发现ALL=(ALL:ALL) ALL语义太缺乏了,但是我一直以为它在某个地方会有一个不错的参数检查器……我错了。真的非常有限。甚至手册页中提供的passwd根排除也可以使用简单的命令行参数来破坏sudo passwd -q root。sudo作者的确在其网站上列出了[一些替代方法](sudo.ws/sudo/other.html)。我希望他们将来会增加对regexp的支持。
joeytwiddle 2014年

您是否rnano在此处特别描述了您的描述,因为它是缺少“另存为”功能的nano版本?我对程序不熟悉。
2014年

是。如果我们关心安全性,则编辑器应编辑指定的一个文件,而不能打开外壳。对于信息,$ man nano然后/-R<Enter>
joeytwiddle

更正:要打破皮特的例子,-q必须紧随其后:sudo passwd root -q。可以通过排除来加固pete示例*root*
joeytwiddle

考虑使用sudoedit来安全启用文件修改sudo
Totor

5

首先,使用打开sudoers文件sudo visudouser ALL=!/usr/sbin/serviceIIRC 添加will将禁止serviceuser命令user

来源:http//nixcraft.com/showthread.php/15132-Sudo-Exclude-Commands-And-Disable-sudo-su-Bash-Shell


这也将停止运行其他服务,我不希望那样。感谢您的回答。:)
shekhar 2014年

虽然您的回答不能完全帮助我,但可以帮助您找到解决方案,谢谢。但是您知道要么给您点赞,要么发布我的工作答案,我的声誉不足。我一定会感激的。谢谢。
shekhar 2014年

2
是的,但仍然要像其他人所说的那样,对此必须非常小心。如何获得访问权限的方法有很多。任何可能产生shell等的命令。用这种方法可以更容易地找出他们真正需要什么命令并允许它们使用,而不是试图排除所有“禁止”的命令。
Bonsi Scott

3
在许多情况下,白名单都是不可维护的。真正的目标可能不是阻止他们做某事,而是防止他们在没有其他限制的情况下错误地做错事。在这些情况下,黑名单很好。您将合理的用户执行任务的方式列入黑名单。但是通过sudo列入黑名单可能还不够-人们可以并且确实使用'sudo bash'。一种方法是包装“ service”命令,如果您不希望使用它们,请通知他们。但是,您绝不会在白名单中列出所有好的行为,也不会在黑名单中列出所有不良行为。
2014年

1
我同意你的鲍勃。为了在没有完全访问权限的情况下提供灵活性,通常需要将自己的解决方案作为辅助脚本进行滚动,并仅将该脚本列入白名单。sudo白名单可能会满足您的需求,但通常它们要么太有限,要么太容易被利用。
joeytwiddle 2014年

5

我找到了解决方案。

我打开终端并用切换为root用户,su -然后键入visudo进行编辑。

然后最后我写了几行

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

然后,我保存并关闭并重新启动。

现在,如果我输入as service network restartservice 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-sudosudo /etc/init.d/network-not-in-sudo restart)。这就是为什么在sudoers文件中创建包含而不是排除要安全得多的原因,例如,说明允许它们与哪些服务进行交互。
托马斯

您可以使用“其他命令”来完成“服务网络重新启动”的所有操作,例如network init.d脚本中的命令。我什至不会尝试在这里列出它们。但是,例如,如果您想实际上防止接口状态的修改,那么SELinux策略在我看来就是可行的方法。这是一个复杂的主题,但是当白名单过于严格或繁重且黑名单不足时,这可能是您的最佳选择。它是在内核中实现的,它使您甚至可以限制对网络接口(和其他资源)的访问。
Bob Kerns 2014年

如果SELinux可以实现,那就会更高兴了。@BobKerns谢谢。我会以这种方式尝试。
shekhar 2014年

3

真正的答案是您无法真正避免这种情况。您可以通过其他答案中描述的方法来防止恶意用户意外地运行该命令,但是如果某人确实想要运行该命令并且位于sudoers列表中,则可以运行该命令。例如,他们可以执行以下操作:

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

或另一个有趣的命令,它们可以用来绕过sudoers文件中的限制:

sudo visudo

长话短说,如果您可以sudo并且不限于运行特定命令,则可以执行几乎所有您想做的事情。即使您将它们限制为一组给定的命令,也必须确保用户不可能将要运行的其他命令复制为与他们有权运行的命令相同的名称(例如覆盖他们有权运行的命令。)


是的 应该避免使用可能从内部产生外壳的命令。
Bonsi Scott

1
问题在于,这不是您要保护的命令,而是内核对象的状态,例如路由表,接口等。无论使用什么命令(或系统调用),都必须保护它。而且您想保护它不受某些(但不是全部)root用户的侵害。SELinux是围绕这种情况而设计的。但是首先,我将首先回顾为什么所有这些用户都具有sudo访问权限。如果他们只需要做一些特定的事情,那么您就可以将sudoers中的白名单操作全部包括在内。
Bob Kerns 2014年

2

使用firejail限制使用沙箱的用户。

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

对于要限制的每个用户,将firejail设置为shell而不是/ etc / passwd中的bash。它非常易于使用,并且有很好的文档。

例:

user:x:1000:1000:user:/home/user:/usr/bin/firejail
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.