繁体   English   中英

通过python子进程ssh:如果没有指纹,如何保释(您确定要继续连接吗?)

[英]ssh via python subprocess: how to bail if fingerprint absent (Are you sure you want to continue connecting?)

工作站重新成像后,我正在使用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)?

该脚本将等待用户输入,然后继续并删除有问题的密钥。

如何获取脚本以进行推送或输入“否”,以便脚本可以继续其指纹修复工作?

相关方法如下:

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

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

如果您确定唯一的答案将是“否”,并且给定次数,则循环的替代方法是

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

在扫描字符串/写入数据时,请注意“ b”前缀,因为标准输入/输出/错误是二进制的。 在python 2中没关系,但是在python 3中,省略b会将字符串与字节进行比较,并且您将永远不会获得匹配。

另外,我已经在Windows上使用plink完成了此操作,但过了一会儿,我感到疲倦并重建了plink版本,其中所有安全消息均已禁用/默认为“乐观”值。 如果该网络是位于防火墙后面的公司网络,并且您要回答所有问题以使这些提示通过,则最好从一开始就创建一个非交互式工具。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM