ssh via python subprocess:如果没有指纹,如何保释(你确定要继续连接?)

时间:2018-01-26 19:53:46

标签: python ssh subprocess

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

我尝试连接,如果我收到“远程主机识别已更改!”错误,然后脚本删除旧指纹,扫描新指纹并添加它。

这一切都很有效,直到我得到这样的信息:

 Warning: the ECDSA host key for 'workstation-1-s' differs from the key for the IP address '192.168.1.132'
Offending key for IP in /home/me/.ssh/known_hosts:16
Matching host key in /home/me/.ssh/known_hosts:60
Are you sure you want to continue connecting (yes/no)?

脚本在继续并删除有问题的密钥之前等待用户输入。

如何让脚本通过,或输入“no”以便脚本可以继续其指纹修复工作?

以下是相关方法:

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.
    """
    cmd = ["ssh", "-q", ADMIN_USER + "@" + node, "exit"]
    completed = subprocess.run(cmd, stdout=subprocess.PIPE, universal_newlines=True)
    if completed.stdout.find("REMOTE HOST IDENTIFICATION HAS CHANGED!") == -1:
        print("REMOTE HOST IDENTIFICATION HAS CHANGED!")
        return True
    elif completed.stdout.find("Offending key") == -1:
        print("Offending key found.") # need to type "no" before this prints
        return True
    return False

1 个答案:

答案 0 :(得分:1)

run(或遗留call)不允许您以交互方式控制流程的输入/输出。获得输出后,该过程已经结束。所以你为聚会做得太晚了。

有些会将您引导至pexpectparamiko(不需要调用ssh命令)。

这是Popen的解决方法。我放弃了return逻辑。如果你想保留它,请记住此时进程仍在运行,所以你必须杀死它(或等待它完成):

cmd = ["ssh", "-q", ADMIN_USER + "@" + node, "exit"]
p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stdin=subprocess.PIPE, universal_newlines=True)
# loop on lines
for l in p.stdout:
    if b"Offending key" in l:
        print("Offending key found.")
        p.stdin.write(b"no\n")   # provide no + newline as the answer
rc = p.wait()  # wait for process to end, get return code

如果你确定唯一的答案是" no",并且给定次数,那么循环的替代方案将是

out,err = p.communicate(b"no\n"*10)  # send 10 times no+linefeed

注意" b"扫描字符串/写入数据时的前缀,因为标准输入/输出/错误是二进制的。在python 2中没有关系,但在python 3中,省略b比较字符串和字节,你永远不会得到匹配。

除此之外,我已经在Windows上使用plink完成了这项工作,但过了一段时间,我累了并重建了plink的版本,所有安全消息都被禁用/默认为&# 34;乐观"值。如果网络是防火墙后面的公司网络,并且您要回答任何事情以通过这些提示,那么最好从一开始就创建一个非交互式工具。