Python Fabric 提示:致命错误:不存在的会话
我有一个来自文档的简单 fabfile.py 文件:
from fabric.api import run
def host_type():
run('uname -s')
我尝试用以下方式运行它:
fab -H 192.168.0.201 host_type
但是出现了这个错误:
me@ubuntu:~/me$ fab -H 192.168.0.201 host_type
[192.168.0.201] run: uname -s
Password for me@192.168.0.201:
Fatal error: No existing session
Aborting.
我可以正常通过 SSH 连接到 192.168.0.201。
有什么想法吗?
8 个回答
要解决这个问题
在你的 fabric 配置文件中添加以下内容:
from fabric.api import env env.key_filename = "/path/to/.ssh/ssk_non_public_key"
这段代码是为了让你的 fab 脚本能够访问你放置了公钥的服务器。
如果没有公钥的话——可以删除你的 .ssh 目录,这也可能有帮助。
或者你可以通过 ssh-keygen 创建一个新的 ssh 密钥,然后结合第 1) 和第 2) 步骤来解决问题。
如果你遇到这个错误,首先可以尝试用paramiko正在使用的具体参数来进行SSH连接,具体包括:
- 主机名
- 用户名
- 认证方式
我发现,如果SSH密钥太多,可能会导致我的一些fabric SSH连接失败,因为所有的密钥都被发送给了远程主机。以前,我也遇到过格式不正确的密钥导致这个错误(你可以通过逐个从~/.ssh/
中删除密钥来检测这些问题)。
不幸的是,Fabric并不遵循你的.ssh/config设置。如果你想调试这个问题,可以运行以下命令:
#!/usr/bin/env python
import paramiko
paramiko.util.log_to_file("/tmp/paramiko.log")
ssh = paramiko.SSHClient()
# Run this if you get host key errors: see later
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect("example.com", username="myuser", password="mypassword")
然后查看/tmp/paramiko.log
中的输出,你可能会看到类似这样的内容:
INF [20120904-16:58:52.155] thr=1 paramiko.transport: Disconnect (code 2): Too many authentication failures for myuser
你可以在Fabric环境中设置no_keys:
env.no_keys = True
但这样的话,你需要告诉Fabric为特定的主机使用特定的密钥。正如上面所提到的,你可以在你的fabfile中这样做:
from fabric.api import env
env.key_filename = "/path/to/.ssh/ssk_non_public_key"
更一般来说,这里有一个函数可以解析你的.ssh配置并提取特定的密钥 - 在这些密钥中,指定要使用的SSH密钥。为了让这个自动工作,你需要在~/.ssh/config
中添加IdentityFile:
Host example.com
IdentityFile /home/jp/.ssh/id_rsa_example
另一个导致失败的原因可能是paramiko不识别所有的主机密钥类型。这就比较麻烦了:paramiko可能会悄悄地忽略~/.ssh/known_hosts
中的主机密钥,因为它不理解这种格式的主机密钥。你可以尝试用-v选项进行ssh连接,看看SSH说找到了哪个主机密钥匹配:
debug1: Host '1.2.3.4' is known and matches the RSA host key.
debug1: Found key in /home/jp/.ssh/known_hosts:105
你可以尝试删除这一行,然后再进行ssh连接并接受(新的?)主机密钥,看看paramiko是否能正常工作。如果这是问题所在,但这样做仍然没有解决,那我就没有看到明确的解决方案了。
简短的回答是:如果你有多个SSH公钥并且想用密码认证,可以试试'-k'和'-a'这两个命令行选项。
我遇到这个错误是因为一个很特殊的情况。我在~/.ssh文件夹里有很多不同的公钥,而且这些公钥也都添加到了我的SSH代理里。我当时是想用Fabric只通过密码来连接。
这是我在服务器认证日志中看到的内容:
Nov 7 07:56:02 ubuntu sshd[1862]: Disconnecting: Too many authentication failures for user [preauth]
Nov 7 07:56:08 ubuntu sshd[1864]: Disconnecting: Too many authentication failures for user [preauth]
我告诉Fabric不要用公钥进行认证,使用了'-k'这个命令行选项。但我没注意到Fabric(通过Paramiko)默认会使用SSH代理里可用的公钥。在我的情况下,这些公钥都已经在SSH代理里注册了,所以告诉Fabric不要用公钥并不能解决问题。后来我加上了'-a'这个命令行选项,这样就告诉Fabric不要去查询SSH代理。最终,我就可以通过密码认证成功连接到服务器了。