使用 CmndAliasALL永远不会安全

使用 CmndAliasALL永远不会安全

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

我想阻止他们逃跑

service NetworkManager restart
service network restart

命令。

有什么方法可以实现这个目的吗?

答案1

使用 CmndAliasALL永远不会安全

有 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,以防将来在工具中添加无害标志service。假设--verbose将来添加了一个标志,那么用户将能够运行以下命令:

$ sudo service --verbose network restart

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


让用户使用组权限编辑文件

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

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

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

在这种情况下,恶意用户可以编辑任何其他 upstart 服务脚本,然后运行它:

$ 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目前仅提供全局图案,可以*匹配任何内容- 它不是一个正则表达式!

(编辑:我确实考虑过如果你可能在你的情况下,可以不用上述方法,因为下面没有子文件夹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/..(从技术上讲,排除使排除变得多余,但为了清晰起见/.,我保留了两者。)/./..

我找到了文件夹,并且/.需要排除,因为否则用户可能会将文件夹本身作为目标。现在你可能会认为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脚本或可执行文件来检查用户传递的参数是否合法,并且只有在合法的情况下才执行他们的请求。

答案2

首先,使用 打开 sudoers 文件sudo visudo。添加user ALL=!/usr/sbin/servicewill,IIRC,禁止service用户执行该命令user

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

答案3

我找到了解决方案。

我已经打开终端并更改为 root 用户,然后su -输入visudo要编辑的内容。

然后最后我写了如下几行

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

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

现在,如果我输入service network restartservice NetworkManager restart,它不允许我输入,并给出如下错误

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

命令也是如此service network restart

答案4

使用 firejail 来限制具有沙箱的用户。

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

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

例子:

user:x:1000:1000:user:/home/user:/usr/bin/firejail

相关内容