question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Received disconnect: Timeout, your session not responding.

See original GitHub issue

Hi,

I am trying to use asyncssh on top of python_prompt_toolkit to modernize a legacy console (colorize output, autocompletion etc.), which can be connected via SSH. I want to set an interactive input and use the same session, so that users can use the existing console with added features. The code below does the job okay, until users do not send any command (i.e, session stays idle) after a few seconds (around 20-30 seconds). Then the protocol error is received: “Timeout, your session not responding”; connection and channel are closed.

Here is the code:

#!/usr/bin/env python

import asyncio
import logging
import sys

import asyncssh
from asyncssh.connection import SSHClientConnection
from asyncssh.process import SSHClientProcess


from prompt_toolkit.shortcuts import print_formatted_text
from prompt_toolkit.shortcuts.prompt import PromptSession


logging.basicConfig()
logger = logging.getLogger()
logger.setLevel(logging.DEBUG)
asyncssh.logger.set_debug_level(3)

# Alias 'print_formatted_text', so that 'print' calls go to the SSH client.
print = print_formatted_text
PROMPT = "< "


async def wait_until_banner(p: SSHClientProcess) -> str:
    out = ""
    while True:
        out = await asyncio.wait_for(p.stdout.read(65536), timeout=5)
        print(out, end='')
        if PROMPT in out:
            break
    return out


async def interact() -> None:
    prompt_session = PromptSession(message="")
    async with asyncssh.connect(host='1.2.3.4', username="foo", password="bar", keepalive_interval=5000) as conn:
        conn: SSHClientConnection
        async with conn.create_process(term_type="auto") as p:
            p: SSHClientProcess
            await wait_until_banner(p)
            # Interactive user input loop
            while True:
                out = ""
                cmd = ""
                try:
                    cmd = await asyncio.wait_for(prompt_session.prompt_async(), timeout=5)
                    p.stdin.write(f"{cmd}\r\n")
                    while True:
                        try:
                            out = await asyncio.wait_for(p.stdout.read(65536), timeout=15)
                            print(out, end='')
                            if "DESTROYING SESSION" in out and "EXIT;" in cmd:
                                return
                            elif PROMPT in out:
                                break
                        except:
                            conn.logger.debug("Timeout")
                            break
                except:
                    pass  # conn.send_packet(98) ?


try:
    asyncio.get_event_loop().run_until_complete(interact())
except (OSError, asyncssh.Error) as exc:
    sys.exit('SSH connection failed: ' + str(exc))

Here is the output:

...snip until prompt
<  
DEBUG:asyncssh:[conn=0, chan=0, pktid=13] Received MSG_CHANNEL_REQUEST (98), 31 bytes
  00000000: 62 00 00 00 00 00 00 00 15 6b 65 65 70 61 6c 69  b........keepali
  00000010: 76 65 40 6f 70 65 6e 73 73 68 2e 63 6f 6d 01     ve@openssh.com.
DEBUG:asyncssh:[conn=0, chan=0] Received OpenSSH keepalive channel request
DEBUG:asyncssh:[conn=0, pktid=15] Sent MSG_IGNORE (2), 5 bytes
  00000000: 02 00 00 00 00                                   .....
DEBUG:asyncssh:[conn=0, chan=0, pktid=16] Sent MSG_CHANNEL_SUCCESS (99), 5 bytes
  00000000: 63 00 00 00 00                                   c....
DEBUG:asyncssh:[conn=0, pktid=14] Received MSG_UNIMPLEMENTED (3), 5 bytes
  00000000: 03 00 00 00 10                                   .....
 
DEBUG:asyncssh:[conn=0, chan=0, pktid=15] Received MSG_CHANNEL_REQUEST (98), 31 bytes
  00000000: 62 00 00 00 00 00 00 00 15 6b 65 65 70 61 6c 69  b........keepali
  00000010: 76 65 40 6f 70 65 6e 73 73 68 2e 63 6f 6d 01     ve@openssh.com.
DEBUG:asyncssh:[conn=0, chan=0] Received OpenSSH keepalive channel request
DEBUG:asyncssh:[conn=0, pktid=17] Sent MSG_IGNORE (2), 5 bytes
  00000000: 02 00 00 00 00                                   .....
DEBUG:asyncssh:[conn=0, chan=0, pktid=18] Sent MSG_CHANNEL_SUCCESS (99), 5 bytes
  00000000: 63 00 00 00 00                                   c....
DEBUG:asyncssh:[conn=0, pktid=16] Received MSG_UNIMPLEMENTED (3), 5 bytes
  00000000: 03 00 00 00 12                                   .....
 
DEBUG:asyncssh:[conn=0, chan=0, pktid=17] Received MSG_CHANNEL_REQUEST (98), 31 bytes
  00000000: 62 00 00 00 00 00 00 00 15 6b 65 65 70 61 6c 69  b........keepali
  00000010: 76 65 40 6f 70 65 6e 73 73 68 2e 63 6f 6d 01     ve@openssh.com.
DEBUG:asyncssh:[conn=0, chan=0] Received OpenSSH keepalive channel request
DEBUG:asyncssh:[conn=0, pktid=19] Sent MSG_IGNORE (2), 5 bytes
  00000000: 02 00 00 00 00                                   .....
DEBUG:asyncssh:[conn=0, chan=0, pktid=20] Sent MSG_CHANNEL_SUCCESS (99), 5 bytes
  00000000: 63 00 00 00 00                                   c....
DEBUG:asyncssh:[conn=0, pktid=18] Received MSG_UNIMPLEMENTED (3), 5 bytes
  00000000: 03 00 00 00 14                                   .....
 
DEBUG:asyncssh:[conn=0, pktid=19] Received MSG_DISCONNECT (1), 50 bytes
  00000000: 01 00 00 00 02 00 00 00 25 54 69 6d 65 6f 75 74  ........%Timeout
  00000010: 2c 20 79 6f 75 72 20 73 65 73 73 69 6f 6e 20 6e  , your session n
  00000020: 6f 74 20 72 65 73 70 6f 6e 64 69 6e 67 2e 00 00  ot responding...
  00000030: 00 00                                            ..
DEBUG:asyncssh:[conn=0] Received disconnect: Timeout, your session not responding. (2)
INFO:asyncssh:[conn=0] Connection failure: Timeout, your session not responding.
INFO:asyncssh:[conn=0, chan=0] Closing channel due to connection close
INFO:asyncssh:[conn=0, chan=0] Channel closed: Timeout, your session not responding.

On Windows SSH to the same server and staying idle (as long as the server allows) does not disconnect. Here, I could see from debug lines that the server sends packet type 98 SSH_MSG_CHANNEL_REQUEST, and client sends back packet type 100 SSH_MSG_CHANNEL_FAILURE. I am not sure if this is what keeps the session alive.

PS: C:\ssh -V
OpenSSH_for_Windows_8.1p1, LibreSSL 3.0.2

PS: C:\ssh <problematic_server_IP> -vvv
... snip until prompt
< debug3: receive packet: type 98
debug1: client_input_channel_req: channel 0 rtype keepalive@openssh.com reply 1
debug3: send packet: type 100
debug3: receive packet: type 98
debug1: client_input_channel_req: channel 0 rtype keepalive@openssh.com reply 1
debug3: send packet: type 100
...

Another weird thing is that the python code works okay when connected to a linux server. That is, client sessions kept alive as long as the server allows. So there is something else I need to do to keep the session alive for the problematic server.

Do you have any pointer to help me?

Issue Analytics

  • State:closed
  • Created 2 years ago
  • Comments:13 (8 by maintainers)

github_iconTop GitHub Comments

2reactions
ronfcommented, Dec 5, 2021

Wow - OpenSSH 4.3 is REALLY old. It was released over 15 years ago (Feb 1, 2006).

I think you may be running into https://bugzilla.mindrot.org/show_bug.cgi?id=1307, which was fixed in OpenSSH back in version 4.9 in 2008, or perhaps the change to accept more packet types was an accidental side effect of another keepalive-related change (and I see a handful of those over the years).

That said, if sending a MSG_CHANNEL_FAILURE instead of MSG_CHANNEL_SUCCESS in AsyncSSH is enough to work around the problem, I’d be willing to make the change to _process_keepalive_at_openssh_dot_com_request to do that, since modern versions of OpenSSH seems to accept either. There’s no need to submit a pull request here – I can take care of this after I get some other changes checked in. I’m hoping it’s just a one-line change.

0reactions
ronfcommented, Jan 23, 2022

This change is now available in AsyncSSH 2.9.0.

Read more comments on GitHub >

github_iconTop Results From Across the Web

SSH timeout server not responding - How to fix and avoid it?
The ssh timeout server not responding error occur due to bad server settings, wrong host address, firewall restrictions etc.
Read more >
6730 – SSH - Disconnect message received:Timeout, your ...
I have just recently been experiencing an issue with my SSH sessions to our SME Server v8b6 timing out too soon.
Read more >
Idle SSH session not disconnecting after set time.
Having ClientAliveCountMax set to 0 and ClientAliveInterval set to 10 seconds (for testing purposes) in the sshd_config file, an idle session ...
Read more >
How to Stop SSH Session From Getting Timed Out
The Linux ssh server never disconnects ssh session from server side by default, check switch/router/firewall configuration to avoid the issue without ...
Read more >
Why am I getting a connection timeout error with ssh?
SSH sits on top of TCP. When you get connection timed out errors it means that the problem is that the SSH client...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found