【问题标题】:Paramiko SSH start_server function raising EOF error?Paramiko SSH start_server 函数引发 EOF 错误?
【发布时间】:2021-08-12 11:33:09
【问题描述】:

我正在尝试使用 paramiko 实现 SSH 服务器,但我不断收到 EOFError,我不知道为什么

class Ctx(paramiko.ServerInterface):
    def check_auth_password(self, username, password):
        if password == "1999":
            return paramiko.AUTH_SUCCESSFUL
        else:
            print("[+] Wrong Password...")
            return paramiko.AUTH_FAILED        
    def create_socket():
        sock = socket.socket()
        return sock
ctx = Ctx()
sock = Ctx.create_socket()
sock.bind(("127.0.0.1", 5555))
server = paramiko.Transport(sock)
server.start_server(server=ctx)

错误是由start_server 引起的,我不明白为什么。回溯是

Traceback (most recent call last):
  File "test.py", line 26, in <module>
    server.start_server(server=ctx)
  File "/home/khaled/Documents/materials/python/env/lib/python3.8/site-packages/paramiko/transport.py", line 728, in start_server
    raise e
  File "/home/khaled/Documents/materials/python/env/lib/python3.8/site-packages/paramiko/transport.py", line 2034, in run
    self.packetizer.write_all(b(self.local_version + "\r\n"))
  File "/home/khaled/Documents/materials/python/env/lib/python3.8/site-packages/paramiko/packet.py", line 367, in write_all
    raise EOFError()
EOFError

文档没有显示 start_server 返回 EOFError 而是返回 SSHExceptionServerInterface 相同的类文档没有提及此错误类型,仅提及它在 socket() 中,这对我来说似乎很好,它绑定到一个没有错误的端口。 Paramiko 版本是 2.7.2 安装在 python 虚拟环境中。

【问题讨论】:

  • @CharlesDuffy 刚刚使用版本信息编辑了问题。见最后一行。并且没有远程端,一切都在同一台机器上测试,我没有尝试连接。仅通过运行程序就会发生此错误。
  • write_all() 如果您只是启动侦听套接字,则没有任何意义。
  • @CharlesDuffy 这很奇怪我确定我没有建立任何联系怎么会发生这种情况。这是 paramiko 错误吗
  • 首先,在建立任何连接之前创建传输是错误的。我非常怀疑这是一个 paramiko 错误;看起来像是滥用 API。
  • (“传输”是 SSH 客户端和 SSH 服务器之间的 TCP 连接;在客户端连接到您之前,作为服务器,您不能建立一个 TCP 连接)

标签: python python-3.x networking ssh paramiko


【解决方案1】:

您不能围绕绑定套接字本身创建传输。

接受来自客户端的连接,并围绕那个创建一个传输。

引用 https://github.com/paramiko/paramiko/blob/master/demos/demo_server.py,为简单起见删除了异常处理并添加了一些解释性 cmets --

# first, we create our listening socket
# but we don't actually wrap it in a transport yet!
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
sock.bind(("", 2200))

# next, tell the socket to start listening
# here, we're allowing up to a 100-connection backlog; tune to taste
sock.listen(100)

# here, we're blocking until a client actually connects
print("Listening for connection ...")
client, addr = sock.accept()

# only now, after we have a client, can we create a transport
print("Got a connection!")
t = paramiko.Transport(client, gss_kex=DoGSSAPIKeyExchange)

【讨论】:

  • 这出乎意料,我认为 paramiko 会处理这一切,因为它没有在文档中提到这一点。
  • 演示服务器是文档的一部分。
  • @Khaled, ...而且更重要的是,任何其他设计都是不灵活的,因为这意味着 paramiko 只能直接在真正的 TCP 套接字上运行,而不能通过其他协议。
  • 不是官方文档网站http://docs.paramiko.org/en/stable/index.htmland more to the point, any other design would be inflexible 不,为什么不我已经打开了套接字并指定了它的类型,它只需要监听并接受为它而来的连接
  • @Khaled,我已经打开了套接字并指定了它的类型——是的,但那是一个 listen 套接字。如果 paramiko 代码是为与监听套接字一起工作而编写的,那么它就不能与预先建立的套接字一起工作,除非你有一个单独的代码路径和 API。如果你只打算做其中一个,预先建立的方法更灵活。
猜你喜欢
  • 1970-01-01
  • 2020-08-01
  • 1970-01-01
  • 1970-01-01
  • 2016-11-28
  • 1970-01-01
  • 2011-11-04
  • 2012-05-31
  • 1970-01-01
相关资源
最近更新 更多