我经常在晚上回家之前让工作电脑运行一些耗时的计算。计算完成后,我希望电脑关机。然而,关闭需要 root 权限,必须使用以下方式执行须藤。显然,7 个小时后我没法输入密码,所以到目前为止,我不得不以 root 身份执行整个命令列表 (cmd1; cmd2; cmd3;...shutdown) - 这并不理想。
有没有办法在命令列表末尾“预授权” sudo?我可以在执行开始时输入我的密码,这样 bash 以后就不需要我输入密码了?
谢谢!
答案1
设置一种方法,使非特权耗时计算可以启动特权 shell 中等待的关闭操作(由sudo -s
或者 )。使用文件作为标志是一种很好的、简单的方法。因此,在非特权 shell 中,执行sudo su
cmd1; cmd2; cmd3; > ok_to_shutdown_now
然后在特权 shell 中运行一个脚本,内容如下
while [ ! -f ok_to_shutdown_now ]
do
sleep 60
done
shutdown
答案2
这里有多种方法可以实现您的目标,具体取决于您愿意承担的风险。并非所有方法都与缓存您的 sudo 凭据有关。
您可以通过在 sudoers 文件中shutdown
添加带有标签的行来关闭用户或用户执行时需要密码的功能。NOPASSWD
你可以通过运行来验证 sudo 身份sudo -v
。你的密码将被缓存 15 分钟,因此你必须运行一个sudo -v
全部(比如说 12 分钟)来更新你的凭据,并在最后一个批处理完成后终止该任务。
如果您知道批处理过程需要多长时间,您可以简单地知道shutdown
关闭系统的时间。
您可以使用 sudoers 文件中的选项增加密码缓存的默认 15 分钟超时时间timestamp_timeout
。可以任意增加,或者,如果您知道批处理过程需要多长时间,也可以增加到该时间。或者,您可以使用负值完全关闭超时时间,并在完成后使用它sudo -v
进行身份验证并“注销” sudo。在这两个调用之间,您可以运行而无需再次输入密码。sudo -k
sudo
如果您不同意 sudo 不需要密码,而是将密码存储在仅供用户读取的文本文件中,那么您可以创建一个小批处理脚本,将您的密码输出到 stdout,并将其用作 sudo 的 askpass 程序,或者简单地在管道中使用它sudo -S
,从中读取密码stdin
。结合一个小脚本,您可以在开始时将密码存储在文本文件中,由提供密码的脚本从中读取密码,sudo
最后再次删除此文件。
回显脚本
#!/bin/bash
echo mypassword
或者
#!/bin/bash
cat /mysecretpwfile
然后./echopw | sudo -S
或
export ASKPASS=~/echopw
sudo -A shutdown -h now
或者,最后,您可以简单地将关机命令放在 shell 脚本中,并将 shell 脚本设置为 suid、所有者 root、您的组、750。
答案3
更好的方法...
是的,有更好的方法。使关机不需要超级用户权限。
这需要提前进行一些设置。然后,它会尽量减少谁可以执行特权操作,以及使用该方法的人可以完成什么。(换句话说,权力的潜在滥用受到其他一些限制的制约。)
我假设安装了一些常用软件,包括sudo
(考虑到这个问题,这似乎是一个安全的假设)和 OpenSSH(或者更可能是“OpenSSH Portable”)。
创建用户帐户
由于您似乎有sudo
访问权限,我推测您可能有能力创建用户。
您可能希望将用户命名为 _sysstop 或 _sysoff 等。尽管“shutdown”不超过八个字符,但这也是要运行的命令的名称,因此使用其他名称可能不错。我还喜欢使用下划线启动完全自动化的帐户(例如这个帐户)的标准,这样从视觉上看,这个帐户最终看起来与标准用户帐户不同。
让用户无需密码即可关机
修改/etc/sudoers,并插入以下内容:_sysstop ALL=(ALL) NOPASSWD:/sbin/shutdown -h*, SETENV: ALL
当然,您可能想要自定义第一部分,即您创建的用户帐户的名称。
很多人似乎反对使用 NOPASSWD,可能是因为他们不喜欢授予在系统上执行任何操作的完全访问权限。但是,这授予了相当受限制的访问权限。此人唯一能做的就是运行以“/sbin/shutdown -h”开头的命令,这将停止系统。如果某些未经授权的人设法利用该行而没有密码,他们可能能够关闭系统,但这并不意味着这样的攻击者可以不受限制地进行许多其他类型的破坏(例如设置其他用户帐户等)。因此,与大多数人试图阻止的情况相比,这种 NOPASSWD 用法相当安全。
我想要使用“/sbin/shutdown -h”。根据您的操作系统和您的需求,您可能想要使用不同的命令,例如“halt”或“reboot”,并且可能需要不同的参数。既然您已经习惯以您想要的方式关闭系统,那么想必您已经知道如何做到这一点。
创建 SSH 密钥
ssh-keygen -t rsa -vvv -f mykey -N "" -C "mykey" | tee mykey.fng
有些人不喜欢-N ""
。好吧,这是一个完全不同的讨论,我选择不在这里进一步讨论,除了本声明的其余部分:根据让您更舒适的安全实践进行定制。
有些人可能会建议对上述示例进行其他更改。同样,这可能很棒,但与此答案的核心无关。请根据需要自定义上述内容。
请注意,上例中“mykey”出现了三次。您可以自定义第一个示例,然后其他出现的单词将与第一个出现的单词相匹配。
您不需要 mykey.fng 文件。我只是养成了保存它的习惯,这样我就可以记录 VisualHostKey(又名“random-art”),后来我才知道这些密钥以后可以再次看到,例如“ssh-keygen -lvf /etc/ssh/ssh_host_ecdsa_key”
限制使用密钥可以执行的操作
修改~$( echo username-just-created )/.ssh/authorized_keys*
文件。(例如,~_sysstop/.ssh/authorized_keys
尽管某些系统可能使用~_sysstop/.ssh/authorized_keys2
,但你可能想要使用authorized_keys)
通过在文件中插入大致如下的行来实现 ssh 密钥:
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAA... Optional-comment-after-the-space
对于“空格后的可选注释”,我喜欢包含私钥的文件名。如果我想添加额外的密钥(对于这种类型的用户,我可能不会这样做,但出于习惯,有些用户可能想要额外的密钥),那么 authorized_keys 文件可能有很多行可以通过密钥的文本识别。如果我有多个密钥,然后几个月后想删除一个,我可能很难记住哪个公钥与哪个密钥文件相关,所以我不知道要删除哪个公钥。通过利用可选注释,我可以在将来更好地保留这一点。
注意:如果您自动添加密钥(可能使用 ssh-add),则可能有一个包含用户名的默认注释。这样的注释通常毫无用处。以将来可能有用的方式进行自定义。
确保~/.ssh/authorized_keys
具有使 OpenSSH 正常运行所需的权限。
测试单个步骤
你能测试一下吗(通过关闭系统)?如果可以,这样做可以单独测试一些组件,如果出现问题,这可能会让你找到更精确的问题。
-
测试密钥设置是否正确。
-
在客户端上,使用
ssh -i ~/keys/privkey-file _sysstop@localhost
-
如果您使用PuTTY,PuTTY还支持
-i filename
(和-ssh
),或者使用GUI在Connection \ SSH \ auth(在选项的左侧框架中)中指定文件名,您只能在“新会话”屏幕上执行此操作。 (具体来说,我说“仅”是因为在尝试使用PuTTY的“系统菜单”并在现有会话上使用“更改会话”时不会出现“身份验证”屏幕) - 在此阶段,您应该会得到一个 shell。如果没有,您可能需要调整使用 SSH 密钥的实现。
-
在客户端上,使用
- 登录后,测试 sudo 是否有效(无需密码)以关闭系统
限制密钥
看到~/.ssh/authorized_keys*
文件了吗?太好了。现在,修改它。
找到以ssh-rsa
在其前面插入一些文本,使该行看起来更像这样:
command="sudo /sbin/shutdown -hp now Shutdown initiated with SSH by \\"$USER\\" CONN rem/lcl=\\"$SSH_CONNECTION\\" CLI rem/lcl=\\"$SSH_CLIENT\\" CMD=\\"$SSH_ORIGINAL_COMMAND\\"",no-agent-forwarding,no-port-forwarding,no-X11-forwarding ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAA... Optional-comment-after-the-space
结果
保护好那个 SSH 私钥文件。有了它,任何人都可以关闭系统。然而,这实际上是他们唯一能做的。
现在,关闭系统只需运行非特权命令“ssh”,并访问该文件即可。只要您控制对该文件的访问,就可以保证一切安全。但是,即使该文件确实受到损害,造成的损害也非常有限。
现在,当您想关闭系统时,甚至不需要输入 sudo。您需要确保没有未经授权的人获得该密钥(否则他们可能会关闭系统)。想必任何可以使用“sudo”窃取该文件的人也可以使用“sudo”关闭系统,因此在许多情况下,将文件留在计算机的私人区域可能是一种相对安全且合理的风险。
答案4
您可以在根环境中运行命令,这样您在计算机前输入一次密码,然后root
无需输入密码即可运行命令。
您可以使用
sudo -s
或者
sudo su
(读这里以弥补差异)
这将赋予您 root 权限,并阻止您再次输入密码。然后,您可以在此之后运行 sudo 命令,它们不会提示您输入密码。