假设服务器上的用户需要运行一个资源匮乏的命令。我想用一个包装器脚本来包装所述命令,该脚本将解析传递的参数并确保该命令仅在特定条件或时间下使用。
问题是,如果程序本身不可执行,则包装器也将无法运行它。我还希望该命令不要以 root 身份运行。
这可能吗?
答案1
简单的答案是:这是不可能的力量您的用户使用您的包装脚本。
原因很简单; shell 脚本是一个解释的程序。这意味着bash
(或其他一些 shell 进程)必须读文件以便运行其中调用的命令。
这又意味着有权运行包装器脚本的用户必须有权执行包装器脚本中完成的所有操作。在绝大多数情况下*,shell 脚本(即使是具有大量内部逻辑和条件的脚本)在运行时执行的操作与在命令提示符中逐行键入整个脚本时执行的操作完全相同。
如果您只是想让未受过教育的用户难以降低系统速度,那么有多种方法可以做到这一点,例如 @mikeserv 在对您的问题的评论中建议的内容。我可以立即想到至少五种方法**,其中许多方法可以组合使用;理解这些的关键是他们不安全。他们实际上并不防止用户直接使用命令而不是包装器脚本,并且它们也不会(也不能)阻止用户制作自己的包装器脚本副本(他必须具有读取权限才能运行完全)并按照他喜欢的方式修改它。
它是可以编写一个简短的 C 程序来执行包装器脚本的功能,该脚本编译为二进制可执行文件,然后使该 C 程序 SUID*** 所以这是用户可以运行您正在讨论的命令的唯一方法,但这超出了我的范围和专业领域。
其他选项涉及极其奇怪的解决方法(黑客),例如设置 cronjob 来修改 sudoers 文件以允许仅在一天中的特定时间运行命令的权限......但这变得非常非常奇怪和糟糕的想法领域。
我认为完成此任务的标准方法(尽管仍然没有强迫精通技术的用户使用您的包装脚本)将是:
(我假设限制的命令是date
。)
- 确保在你的脚本中,它的调用
date
使用绝对路径:(/bin/date
你可以通过运行来找出这是什么which date
。)还要确保你的脚本有一个正确的shebang,这样它就可以运行而不需要键入,bash ./myscript
而是可以运行as./myscript
,并确保每个人都可读和可执行。 (chmod 555 myscript
) - 将您的包装器脚本放入
/usr/local/bin/
并将其重命名为date
. - 检查用户是否已
/usr/local/bin
在开始他们的$PATH
变量。 (只需以用户身份登录并运行即可echo "$PATH"
。)默认情况下他们应该已经有了这个。它不必在最开始,只要它之前在它们的路径中/bin
(或者无论原始命令的位置date
是什么)。
如果他们的路径中没有它,您可以通过运行添加它:echo 'PATH="/usr/local/bin:$PATH"' | sudo tee /etc/profile.d/my_path_prefix.sh
现在,每当用户尝试直接运行该命令时,他实际上都会运行您的包装器脚本,因为您的包装器脚本所在的目录首先出现在他的$PATH
.
一种更具黑客风格的“黑帽”解决方案是实际屏蔽原始二进制文件,不是通过将另一个版本放在用户路径的前面,而是通过将包装器脚本放在原始命令本身的位置地点。使用时请自行承担风险:
- 将命令本身放在正常
bin
目录之外的某个位置,这样就没有人会在其路径中包含它。例如,您可以将其移动到/var/local
. (可能有更好的地方,但这已经是一个黑客,所以这并不重要,不是吗?) date
确保对包装器脚本中的调用指向新的date
其绝对路径的位置:/var/local/date
在我的示例中。- 将包装器脚本移至
date
的旧位置,并date
使用 的原始名称。
主要的警告是每次任何人尝试运行该命令,包括系统初始化脚本,他们将获取您的包装脚本。
这纯粹是一种黑客行为,不符合好的系统管理。但它是这是可能的,而且你也知道这是可以做到的。更好的解决方案是我上面发布的。
*例外情况与修改环境和程序有关,这些环境和程序在交互运行时与从脚本运行时的行为不同。这些异常与权限不过,因此它们与本次讨论无关。
**如果您有兴趣,请在评论中询问它们,我将对其进行扩展。
***不是suid root。如果您这样做,只需创建一个用户,将他放入一个组中,该组是唯一有权运行您正在讨论的命令(chmod 010
或其他内容)的组,然后将chown
新编译的包装器二进制文件归该用户所有并设置它的suid位与chmod 4511
.