【问题标题】:ssh via python subprocess.Popen: terminate if password requested通过python subprocess.Popen ssh:如果请求密码则终止
【发布时间】:2018-07-06 07:09:39
【问题描述】:

在重新映像工作站后,我正在使用 python 脚本来管理 ssh 指纹问题。

我尝试连接 ssh,如果我收到任何警告,我会处理它们。

但是,如果没有错误,则会要求我输入密码以进行连接。此时我想终止该过程。但是,脚本挂在密码请求上。

方法如下:

def ssh_fingerprint_changed(node):
    """
    Checks if a node's ssh fingerprint has changed or an old key is found, which can occur when a node is reimaged.
    It does this by attempting to connect via ssh and inspecting stdout for an error message.
    :param node: the ip or hostname of the node
    :return: True if the node's fingerprint doesn't match the client's records. Else False.
    """
    changed = False
    cmd = ["ssh", "-q", ADMIN_USER + "@" + node, "exit"]
    proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, stdin=subprocess.PIPE, universal_newlines=True)
    print("Checking for fingerprint changes")

    for line in proc.stdout:  # loop on lines
        print("in for loop") # NEVER REACHES HERE IF NO ERRORS, WAITING FOR PASSWORD
        if b"Offending key" in line:
            print("Offending key found.")
            proc.stdin.write(b"no\n")   # don't connect
            changed = True
        elif b"REMOTE HOST IDENTIFICATION HAS CHANGED!" in line:
            print("REMOTE HOST IDENTIFICATION HAS CHANGED!")
            changed = True

    print(changed) # NEVER REACHES HERE IF NO ERRORS, WAITING FOR PASSWORD
    if not changed:  # then everything's good, but it will be waiting for a password to connect
        print("Good to go, terminating ssh test.")
        rc = proc.terminate()
    else:
        rc = proc.wait()

    return changed

如果我从终端 ./my_python_script.py 运行它,我就会遇到问题。奇怪的是,如果我在 PyCharm 中运行,它不会挂在密码请求上并终止 shh,并按预期继续执行脚本。

【问题讨论】:

  • 解释它的“原因”——没有换行符的行将进入循环。
  • 至于如何修复它——为什么不直接通过 ssh 适当的命令行参数来禁用密码验证?
  • (也就是说,你有没有考虑过使用 Paramiko 来代替?那样可以控制更多)。
  • 我不确定我是否理解您的“为什么”?另外我不想禁用密码验证,我什至不想在这里连接。我只需要错误/警告来删除旧的键印并添加新的。
  • 正确,我的意思是不会到达循环。一行只有在它后面有换行时才是完整的。没有完整的行 -> 阅读程序等待完成打印。

标签: python ssh subprocess


【解决方案1】:

简单的答案就是告诉ssh您根本不想支持密码验证;如果主机密钥被更改,您仍然会收到您想要的消息,但您永远不会让进程挂起等待输入密码。

cmd = ['ssh',
       '-o', 'PasswordAuthentication no',  ### <-- THIS LINE HERE
       '-o', 'StrictHostKeyChecking yes',  ### also, never modify known_hosts
       '-q',
       '%s@%s' % (ADMIN_USER, + node),
       'exit']

如果您不想处理其他提示,我建议设置 stdin=subprocess.DEVNULL(在 Python 3 中)或将 -n 参数传递给 ssh 以防止将标准输入传递给进程。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-02-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-10-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多