ronf / asyncssh

AsyncSSH is a Python package which provides an asynchronous client and server implementation of the SSHv2 protocol on top of the Python asyncio framework.
Eclipse Public License 2.0
1.56k stars 153 forks source link

Dynamic forwarding uncaught exception #700

Open zanda8893 opened 1 month ago

zanda8893 commented 1 month ago
INFO:asyncssh:[conn=2] Opening direct TCP connection to www.google.com, port 443
INFO:asyncssh:[conn=2]   Client address: 127.0.0.1, port 43318
DEBUG:asyncssh:[conn=2, chan=40] Set write buffer limits: low-water=16384, high-water=65536
INFO:asyncssh:[conn=2] Opening direct TCP connection to incoming.telemetry.mozilla.org, port 443
INFO:asyncssh:[conn=2]   Client address: 127.0.0.1, port 60672
DEBUG:asyncssh:[conn=2, chan=41] Set write buffer limits: low-water=16384, high-water=65536
INFO:asyncssh:[conn=2] Opening direct TCP connection to lh3.google.com, port 443
INFO:asyncssh:[conn=2]   Client address: 127.0.0.1, port 60686
DEBUG:asyncssh:[conn=2, chan=42] Set write buffer limits: low-water=16384, high-water=65536
INFO:asyncssh:[conn=2] Opening direct TCP connection to fonts.gstatic.com, port 443
INFO:asyncssh:[conn=2]   Client address: 127.0.0.1, port 60698
DEBUG:asyncssh:[conn=2, chan=43] Set write buffer limits: low-water=16384, high-water=65536
INFO:asyncssh:[conn=2, chan=43] Closing channel
DEBUG:asyncssh:[conn=2] Uncaught exception
Traceback (most recent call last):
  File "/home/zanda/new_tools/fstn_tools/automated_vm_connection/.venv/lib/python3.12/site-packages/asyncssh/connection.py", line 1333, in data_received
    while self._inpbuf and self._recv_handler():
                           ^^^^^^^^^^^^^^^^^^^^
  File "/home/zanda/new_tools/fstn_tools/automated_vm_connection/.venv/lib/python3.12/site-packages/asyncssh/connection.py", line 1598, in _recv_packet
    processed = handler.process_packet(pkttype, seq, packet)
                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/zanda/new_tools/fstn_tools/automated_vm_connection/.venv/lib/python3.12/site-packages/asyncssh/packet.py", line 237, in process_packet
    self._packet_handlers[pkttype](self, pkttype, pktid, packet)
  File "/home/zanda/new_tools/fstn_tools/automated_vm_connection/.venv/lib/python3.12/site-packages/asyncssh/channel.py", line 625, in _process_eof
    self._flush_recv_buf()
  File "/home/zanda/new_tools/fstn_tools/automated_vm_connection/.venv/lib/python3.12/site-packages/asyncssh/channel.py", line 348, in _flush_recv_buf
    assert self._session is not None
           ^^^^^^^^^^^^^^^^^^^^^^^^^
AssertionError
INFO:asyncssh:[conn=1, chan=0] Aborting channel
INFO:asyncssh:[conn=2] Connection failure: 
zanda8893 commented 1 month ago
async def my_fun():
                conn = await asyncssh.connect(
                    host.hostname,
                    port=host.port,
                    username=host.user,
                    password=host.password,
                    client_keys=keys,
                    known_hosts=None,
                    tunnel=tunnel
                )
                listener = await conn.forward_socks(local_host, local_port)
                asyncio.create_task(listener.wait_closed())
                while True:
                      [other tasks]

Here's an example of how I'm using it in my code. I'm unsure what exactly causes the exception. It seems to happy randomly after a few minutes of connection. Perhaps because I'm not sending any commands to the remote host?

ronf commented 1 month ago

I don't think the asyncio.create_task(listener.wait_closed()) really does much for you there. That will never complete unless you have a call to listener.close() somewhere, and it would probably be better to do the wait_closed() immediately following that call to close() if you do have one. Otherwise, this code looks fine.

As for the assertion failure, can you try the version in the "develop" branch and see if that fixes your issue? A couple of previous commits introduced some problems in that area, and I fixed most of them in 2.17.0, but there were still some cases where that version was having problems. I've since reverted both the original change and the attempt to improve it and took an entirely different approach, but haven't had had a chance to do a new release which includes that change.

zanda8893 commented 1 month ago

I'm currently using 2.17.0 from pypi. I'll try using a version built from the develop branch. It may take a while to see if that fixes it. It's a quite intermittent issue. Thanks for your help

zanda8893 commented 1 month ago

Issue hasn't reappeared since switching to the develop branch code. So closing for now. Thanks again for your help.

zanda8893 commented 1 month ago
INFO:asyncssh:[conn=2] Opening direct TCP connection to github.com, port 443
INFO:asyncssh:[conn=2]   Client address: 127.0.0.1, port 34660
DEBUG:asyncssh:[conn=2, chan=18] Set write buffer limits: low-water=16384, high-water=65536
DEBUG:asyncssh:[conn=2] Uncaught exception
Traceback (most recent call last):
  File "/home/zanda/new_tools/fstn_tools/automated_vm_connection/.venv/lib/python3.12/site-packages/asyncssh/connection.py", line 1441, in _recv_data
    while self._inpbuf and self._recv_handler():
                           ^^^^^^^^^^^^^^^^^^^^
  File "/home/zanda/new_tools/fstn_tools/automated_vm_connection/.venv/lib/python3.12/site-packages/asyncssh/connection.py", line 1602, in _recv_packet
    result = handler.process_packet(pkttype, seq, packet)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/zanda/new_tools/fstn_tools/automated_vm_connection/.venv/lib/python3.12/site-packages/asyncssh/packet.py", line 238, in process_packet
    return self._packet_handlers[pkttype](self, pkttype,
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/zanda/new_tools/fstn_tools/automated_vm_connection/.venv/lib/python3.12/site-packages/asyncssh/channel.py", line 622, in _process_eof
    self._flush_recv_buf()
  File "/home/zanda/new_tools/fstn_tools/automated_vm_connection/.venv/lib/python3.12/site-packages/asyncssh/channel.py", line 351, in _flush_recv_buf
    if (not self._session.eof_received() and
            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/zanda/new_tools/fstn_tools/automated_vm_connection/.venv/lib/python3.12/site-packages/asyncssh/forward.py", line 155, in eof_received
    self._peer.write_eof()
  File "/home/zanda/new_tools/fstn_tools/automated_vm_connection/.venv/lib/python3.12/site-packages/asyncssh/forward.py", line 94, in write_eof
    assert self._transport is not None
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^
AssertionError

Apologies for reopening happened again just as I pressed close.

Different traceback however using the develop code.

ronf commented 3 weeks ago

Looking over your example more closely, what exactly is "tunnel" being set to here? Are you trying to tunnel traffic through a bastion host? What does that code look like?

Also, I'm presuming you have a SOCKS client here making requests to local_host/local_port, and it is telling you what final destination host/port to connect to. Are those connections to some kind of shell on the target system?

ronf commented 3 weeks ago

So far, I'm unable to reproduce this when going through a SOCKS dynamic listener and over an SSH tunnel to another host, with the final target host sending an EOF on the connection. Everything looks good here in terms of handling EOF and cleaning up the connection. So far, though, I haven't added any kind of tunnel. Once I know more about what you are doing with that, I'll try and include it in my testing.