【问题标题】:How can I make my custom shell work with ssh?如何使我的自定义 shell 与 ssh 一起使用?
【发布时间】:2014-10-02 08:21:15
【问题描述】:

我正在用 Python 为服务器上的一个非常有限的用户制作一个自定义 shell,该用户通过 ssh 使用公钥身份验证登录。他们需要能够在具有一定限制的特定目录中运行lsfind -type dcat。如果您运行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,因此他们无法登录。

标签: python linux ssh stdio


【解决方案1】:

ssh 没有响应的问题与ssh user@host cmd 没有为正在运行的命令打开终端有关。尝试拨打ssh user@host -t cmd

但是,即使您传递了-t 选项,您的脚本仍然存在另一个问题:它只能以交互方式工作,并且完全忽略了正在传递的 $SSH_ORIGINAL_PROGRAM。一个天真的解决方案是检查sys.argv,如果它大于 1,你就不会永远循环,而是只执行你在其中的任何命令。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-04-20
    • 1970-01-01
    • 2017-11-09
    • 2021-05-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多