![需要(某些)Root 访问权限的脚本](https://linux22.com/image/501800/%E9%9C%80%E8%A6%81%EF%BC%88%E6%9F%90%E4%BA%9B%EF%BC%89Root%20%E8%AE%BF%E9%97%AE%E6%9D%83%E9%99%90%E7%9A%84%E8%84%9A%E6%9C%AC.png)
我有一个关于系统管理脚本的一般问题,这些脚本要求“某些”命令以 root 权限执行,而其他命令则以普通非 root 用户权限执行(即 myusername 等)。我应该提到我在 Linux Red Hat 4 系统上使用 Ruby 1.8.6。到目前为止我看到的建议是:
- 允许 sudoers 访问:
USERNAME = NOPASSWD: /path/to/script, /etc/init.d/httpd, /path/to/somethingelse
这个语法正确吗?如果正确,我是否应该列出脚本中所需的所有特定命令,而我不想被提示输入密码? - 设置 suid
http://www.wellho.net/mouth/733_Perl-for-Systems-Admin-suid-scripts.html
要以 root 权限运行 Perl 脚本:
a) 将脚本的所有者设置为 root
b) 在文件上设置 suid 位 (chmod u+s filename)
c) 关闭读取权限,并为除 root 之外的所有人打开对文件的执行权限 (chmod go=x)
但其他研究表明,您只能在更高版本的 Linux 系统的二进制文件上设置 suid(我的脚本实际上将在旧版本的 RH4 上运行,但我们最终可能会升级,因此我希望向前兼容)。我不认为我想为此创建一个二进制文件! - “使用生成的公钥/私钥进行 ssh 操作。可以配置密钥以仅允许使用它执行某些命令。”
- 对于任何需要 root 权限的脚本命令,请保留 sudo:
系统“sudo rake ts:rebuild”(当然,这样做的缺点是会提示输入所有密码!) - 以 root 身份执行脚本
但是我想要以普通用户身份运行的命令该怎么办? - 以 root 身份执行 su username(对于需要以普通用户身份运行的任务)
“以 root 身份运行脚本,以 root 身份执行一系列任务,su newUser 以 newUser 身份执行一系列任务,exit(退出回 root 用户)以 root 身份执行更多任务。”(下文由 James 提出)
我为自己没有更好地掌握这个主题而感到惭愧,但我有点惊讶,我参考的 Ruby“脚本书籍”中竟然有这么多没有提到这个问题!我猜这更像是一个‘nix’问题,但似乎做任何有实质性用途的事情,你都可能会遇到这个问题。
编辑:有些东西,比如 mysql,我可以在命令中使用选项,比如 --password,所以我用这个来做到这一点:
puts "Remote Password: "
system('stty -echo')
password = STDIN.gets.chomp
puts "Mysql Password (local): "
mysql_local_password = STDIN.gets.chomp
system('stty echo')
然后我可以在脚本中使用这些密码,但它们永远不会被视为明文。但这当然不适用于所有情况。
我应该提到的另一件事是,有些命令需要以不同的用户身份运行(除了 root 和一个普通用户之外,可能还有一个“build”用户,等等)
问题:请帮助我了解这些命令的优缺点(以及任何其他建议或更好的解决方案)。此外,如果有一本权威的书、链接、手册页等,介绍脚本如何与底层系统的权限交互,您可以参考我,这也很好。
谢谢大家!
答案1
你有没有研究过类似的事情卡皮斯特拉诺,木偶,ansible或者厨师完成你的任务?
你没有提到你的工作范围是什么,所以我不知道它们对你是否有用。
我会不惜一切代价避免使用“suid”。安装了 sudo 后再使用它毫无意义,对于需要使用不同权限/用户 ID 运行命令(‘sudo -u user2 command2’等)的需求而言,这似乎是最佳选择。
此外,您可能还希望在基于密钥的 ssh 会话中以无密码方式运行一些 sudo 命令作为允许的命令(ssh sshkeyaccessonlyuser@yourhost 'sudo command')。如果您不想在 sudo 中拥有更长的密码缓存,并且您的脚本无法及时完成 sudo 命令的运行,这可以解决缓存问题。
答案2
是的,您可以在脚本中以 root 身份 su 到任何用户,而无需密码。这有点像 hack,但可以正常工作。您可能会遇到一些小问题(例如,当您 su 时,您的环境会发生变化),但您可以让它正常工作。我认为这不是“正确的”。此外,root 可以做任何事情,因此您总能找到以 root 身份做所有事情的方法。
我建议对所有事情都使用 sudo。
对于交互式操作,带密码提示的 sudo 是可以的。我更喜欢它提示您输入您自己的密码,而不是 root 的密码。这样,您可以授予有限的管理权限,而无需泄露 root 的密码(因此,完全权限)。必须输入密码对于“嘿!我正在输入密码,这意味着我正在做一些潜在的危险,让我在输入之前检查一下”很有用。您还可以将 sudo 设置为不反复提示输入密码(即,一旦您输入密码,n 分钟内的 sudo 调用就不会提示)。
另外,你可以让 sudo 让用户执行任何以 root 身份执行操作,而不仅仅是一组有限的命令。我在自己管理的机器上使用它;它比“su -”更好,可以为您提供一些现成的审计内容,您始终可以“sudo -i”(或有时为“-s”)来获取 root shell,等等。
对于非交互式的东西,还有更多选择。
我不太喜欢 suid 二进制文件。这应该只用于非常常用的需要 root 权限的二进制文件,即非常简单且经过彻底审核。例如,ping 需要 root 权限才能执行其工作。但是,suid 二进制文件中的任何安全漏洞都可能非常危险。
使用 ssh 是一种非常复杂的实现方法。
使用 sudo,将其设置为不需要脚本所需的特定命令的密码。“man sudoers”很长,但绝对很有趣 - 你可以用 sudo 做很多事情......
答案3
我选择#4:
对于需要 root 权限的任何脚本命令,请保留 sudo:system 'sudo rake ts:rebuild'
您不需要过于担心重复的密码提示;sudo 将在短时间内(默认情况下约为 5 分钟)缓存您使用密码进行身份验证的事实。从手册页:
一旦用户通过了身份验证,时间戳就会更新,然后用户可以在短时间内(5 分钟,除非在 sudoers 中被覆盖)无需密码使用 sudo。
从man sudoers
:
时间戳超时
sudo 再次要求输入密码之前可以经过的分钟数。默认值为 5。将其设置为 0 以始终提示输入密码。如果设置为小于 0 的值,则用户的时间戳将永不过期。这可用于允许用户分别通过 sudo -v 和 sudo -k 创建或删除自己的时间戳。
因此,只要脚本运行时间少于 5 分钟,用户就只会看到一个密码提示 - 如果用户最近已经进行过身份验证,则根本不会显示任何密码提示。
答案4
首先我想说的是,我对 ruby 一点都不熟悉,因为它似乎是一种非常规的管理任务语言选择。查看下面列出的选项,5 似乎是最佳选择。如果脚本的任何部分需要 root 权限,我会说运行该脚本需要 root 权限。
给出上述所有选项,我没有看到以 root 身份运行脚本并在以用户身份运行命令之前只运行“su username”的选项。它的好处是不需要密码提示(不需要 root 身份的密码权限),它应该可以满足您的所有需求。
以 root 身份运行脚本,以 root 身份执行一系列任务,su newUser 以 newUser 身份执行一系列任务,exit(退出回 root 用户)以 root 身份执行更多任务。