脚本需要(一些)根访问

我有一个关于系统pipe理脚本的一般性问题,这些脚本需要使用root访问来执行“some”命令,而其他的作为普通的非root用户(即myusername等)。 我应该提到我在Linux Red Hat 4系统上使用Ruby 1.8.6。 我目前看到的build议是:

  1. 允许从sudoers访问:
    USERNAME = NOPASSWD:/ path / to / script,/etc/init.d/httpd,/ path / to / somethingelse
    这个语法是正确的吗? 如果是这样,我是否正确,我想列出脚本中所需的所有特定命令,我不想被提示input密码?
  2. 设置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)closures读取权限,然后执行权限到文件给除root以外的所有人(chmod go = x)
    但其他的研究表明,你只能在以后的Linux系统上设置suid的二进制文件(我的脚本实际上是在RH4的旧版本上运行,但是我们可能会升级,所以我想向前兼容)。 我不认为我想为此创build一个二进制文件!
  3. '用生成的公钥/私钥使用ssh。 该键可以configuration为只允许执行某些命令。
  4. 在sudo中留下任何需要root的脚本命令:
    系统'sudo rake ts:rebuild'(当然这有所有那些密码提示的缺点!)
  5. 以root身份执行脚本
    但是,我想作为普通用户运行的命令呢?
  6. 以root su用户身份执行(对于需要以普通用户身份运行的任务)
    '以root身份运行脚本,以root用户身份执行一系列任务,su用户以newUser身份执行一系列任务,退出(退出到root用户)以root用户身份执行更多任务。 (由James提出)

我对这个话题没有更好的理解感到羞愧,但是我对有多lessRuby脚本书感到有些惊讶,“我提到的这些脚本书没有解决这个问题! 我想这更像是一个'尼克斯'的事情,但似乎要做大量使用的事情,你可能会遇到这种情况。

编辑:有些东西像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”用户等等)

问题:请帮助我了解这些(以及其他build议或更好的解决scheme)的优缺点。 另外,如果有一个权威性的书籍,链接,手册页等,解决了脚本如何与底层系统的权限进行交互,那么你可以引用我的意思,这也是很棒的。

谢谢大家!

你有没有看过像卡西斯努拉 , 傀儡或厨师的任务?

你没有提到你的工作范围是什么,所以我不知道它们对你有什么用处。

我会不惜一切代价避免“suid”。 安装sudo没有意义,这似乎是用不同的权限/用户id('sudo -u user2 command2'等)运行命令的最佳select。

你也可以在你的基于密钥的ssh会话(ssh sshkeyaccessonlyuser @ yourhost'sudo command')中运行一些sudo命令无密码的许可命令。 如果您不想在sudo中使用更长的密码caching,并且您的脚本不能及时完成sudo命令的运行,则可以处理caching问题。

是的,您可以以root用户身份login脚本中的任何用户,而不需要密码。 这是一个黑客,但它会工作。 一路上你可能会有一些打嗝(例如,你的环境改变了),但你可以使它工作。 我不认为这是“正确的”。 而且,root可以做所有事情,所以你总是可以find办法做所有事情的根。

我build议使用sudo的一切。

对于互动的东西,与密码提示sudo是好的。 我更喜欢它提示你input你自己的密码,而不是root。 通过这种方式,您可以授予有限的pipe理权限,而不会泄露root用户的密码(从而获得完整的权限)。 input密码对于“嗨!我正在input密码,这意味着我正在做一些有潜在危险的事情,让我们在input之前进行检查”。 你也可以设置sudo不要反复提示input密码(例如,一旦你input密码,在n分钟内sudo invocations不会提示)。

另外,你可以让sudo让用户以root身份执行任何操作,而不仅仅是一组有限的命令。 我使用这个我pipe理的盒子上; 它比“su – ”更好,给你一些开箱即用的审计东西,你总是可以用“sudo -i”(或者“-s”,有时候)来获得一个root shell等等。

对于非交互的东西,有更多的select。

我不是很喜欢suid的二进制文件。 这应该只用于需要root权限的非常常用的二进制文件,它非常简单,并且已经被彻底审核。 例如,ping需要root权限才能完成工作。 但是,suid二进制文件中的任何安全漏洞都可能是非常危险的。

使用ssh是实现这一点的一个非常复杂的方法。

使用sudo,将其设置为不需要脚本需要的特定命令的密码。 “男人们”是一个长期的阅读,但绝对有趣的是,你可以用sudo做很多事情…

我会去#4:

在sudo中留下任何需要root的脚本命令:system'sudo rake ts:rebuild'

您不需要担心重复的密码提示; sudo会caching你使用密码进行authentication的事实(默认大约5分钟)。从手册页:

一旦用户被authentication,时间戳被更新,并且用户可以在短时间内使用sudo而不需要密码(5分钟,除非在sudoers中被覆盖)。

man sudoers

timestamp_timeout

在sudo之前可以经过的分钟数将再次要求passwd。 默认值是5.设置为0总是提示input密码。 如果设置为小于0的值,则用户的时间戳永远不会过期。 这可以被用来允许用户分别通过sudo -v和sudo -k创build或删除自己的时间戳。

所以只要脚本运行时间less于5分钟,用户应该只能看到一个密码提示 – 如果他们最近通过了validation,他们根本就没有提示。

我会去sudo以及解决scheme1和5.请注意,您也可以使用别名,使您的设置更清洁,如:

 Cmnd_Alias RUBY_TOOLS = /path/to/cmnd1, /path/to/cmnd2, etc. Cmnd_Alias RUBY_TOOLS_NPW = /path/to/cmnd3 User_Alias RUBY_USERS = user1, user2, etc. User_Alias RUBY_SPECIAL_USERS = root RUBY_USERS ALL=(RUBY_SPECIAL_USERS) RUBY_TOOLS, NOPASSWD: RUBY_TOOLS_NPW 

该规则将以用户RUBY_SPECIAL_USERS的方式限制对RUBY_T​​OOLS命令的访问,并且对RUBY_T​​OOLS_NPW不使用密码。

Sudo非常灵活。 您也可以使用Host_Alias来指定要在其上应用规则的主机。 如果你需要自动生成你的sudo规则,你可以使用Augeas 。

我看到的这个方法唯一的缺点是:

  1. 在机器上需要sudo(显而易见)
  2. 每当你想要一个脚本被执行的时候,你需要调用sudo

解决第二个问题的方法之一是在您的configuration中设置SUCMDvariables,并在所有的exec调用之前使用它。 默认情况下,SUCMD将是sudo,但是如果你希望使用另一个系统,可以将其设置为'su',或者如果你不想使用SUCMD并且使用setuid或者group权限来设置你的系统。

我想说,首先,我对ruby一点也不熟悉,因为它似乎是一个非常规的select,作为pipe理任务的语言。 看看下面列出的选项,5似乎是最好的select。 如果脚本的任何部分需要root权限,我会说运行脚本需要root权限。

给出所有的select,我没有看到作为root运行脚本的选项,只是运行“su用户名”作为用户运行命令之前的选项。 它具有不需要密码提示(不需要密码权限作为根)的好处,它应该满足您的所有需求。

以root身份运行脚本,以root用户身份执行一系列任务,su用户以newUser身份执行一系列任务,退出(退出到root用户)以root用户身份执行一系列任务。

这里有另一种方法,我不时使用。 如果你真的不想要密码,也不想依赖于sudo,那么可以使用一个包装suid脚本,然后调用你的脚本。 “sudo”有它的优点,但是有时比简单的包装,比如说cron工作或者其他脚本的一部分,使用起来更困难。

我必须在我的networking日志处理中做到这一点。 以普通用户身份运行的脚本会将日志文件压缩,然后调用suid脚本将HUP发送给apache,使其重新打开新的日志文件。 只有HUP需要以root身份运行,所以只有那部分是suid。