【发布时间】:2014-10-02 08:21:15
【问题描述】:
我正在用 Python 为服务器上的一个非常有限的用户制作一个自定义 shell,该用户通过 ssh 使用公钥身份验证登录。他们需要能够在具有一定限制的特定目录中运行ls、find -type d 和cat。如果您运行ssh user@server -i keyfile 之类的东西,这会很好,因为您会看到交互式提示,并且可以运行这些命令。但是,ssh user@server -i keyfile "ls /var/log" 之类的东西不会。 ssh 只是挂起,没有响应。通过使用-v 开关,我发现连接成功,所以问题出在我的shell 中。我也相当确定脚本甚至没有启动,因为程序开头的print sys.argv 什么都不做。代码如下:
#!/usr/bin/env python
import subprocess
import re
import os
with open(os.devnull, 'w') as devnull:
proc = lambda x: subprocess.Popen(x, stdout=subprocess.PIPE, stderr=devnull)
while True:
try:
s = raw_input('> ')
except:
break
try:
cmd = re.split(r'\s+', s)
if len(cmd) != 2:
print 'Not permitted.'
continue
if cmd[0].lower() == 'l':
# Snip: verify directory
cmd = proc(['ls', cmd[1]])
print cmd.stdout.read()
elif cmd[0].lower() == 'r':
# Snip: verify directory
cmd = proc(['cat', cmd[1]])
print cmd.stdout.read()
elif cmd[0].lower() == 'll':
# Snip: verify directory
cmd = proc(['find', cmd[1], '-type', 'd'])
print cmd.stdout.read()
else:
print 'Not permitted.'
except OSError:
print 'Unknown error.'
这是来自 ~/.ssh/authorized_keys 的相关行:
command="/path/to/shell $SSH_ORIGINAL_COMMAND" ssh-rsa [base-64-encoded-key] user@host
如何在命令行上传递命令时制作 shell 脚本,以便在不启动交互式 shell 的情况下在脚本中使用它?
【问题讨论】:
-
查看 /etc/passwd。最后一个字段是用户使用的 shell 的路径。您可以设置一个测试用户并让该用户的外壳成为您的外壳进行测试。这样你就不必一直用命令调用你的 shell。
-
出于某种原因,以您建议的方式修改 /etc/passwd 会破坏公钥登录,即使 authorized_keys 的
command部分不存在。我不确定我是否理解为什么会发生这种情况。也许 SELinux 不喜欢它? -
您的 shell 可能过早退出。一个针对 *nix 用户的老恶作剧是将人们的 shell 设置为
false,因此他们无法登录。