ngrok / ngrok-python

Embed ngrok secure ingress into your Python apps with a single line of code.
https://ngrok.com
Apache License 2.0
103 stars 19 forks source link

TCP tunnel disconnect behaviour #124

Open mathsman5133 opened 3 days ago

mathsman5133 commented 3 days ago

Hi,

I'm trying to implement a system where tunnels (specifically TCP, SSH tunnels) have a "timeout" - process goes roughly like

When I close the tunnel, I would expect any connected hosts (via SSH) to be "kicked off" (connection closed). However, what I'm seeing is that any new connections are refused, but any existing connections stay open. This can be mitigated by killing the agent (exiting the script), but that is not ideal as it would close any other tunnels the process has open, and I'm working in the context of long-running processes.

What's even stranger is that the tunnel seems to almost "disappear":

But, the tunnel still appears in the "TCP Addresses" tab:

image

... and in the "Endpoints" tab:

image

Although this is not entirely consistent - sometimes they just don't show up.

What is also strange is that while this zombie tunnel is still alive I'd (possibly) expect an error that I can't create a new tunnel with that same URI. However, I can create (and use) a new tunnel as if nothing happened, and exit the newly created one with no problems, and have the original "zombie" tunnel still active.

Some basic code to illustrate what I'm talking about:

import time

import ngrok

listener = ngrok.forward("host:port", "tcp", authtoken="token", remote_addr="xxx.ngrok.io:port")
print(listener.url())

# now in the next 20 seconds, go to your terminal and `ssh user@xxx.ngrok.io -p port`

time.sleep(20)
print("Disconnecting...")
ngrok.disconnect(listener.url())  # <--- at this point I would expect my SSH session to be kicked off, but it doesn't

time.sleep(10)
ngrok.kill()  # <--- perhaps if the above didn't work I'd definitely expect killing the agent to kick my SSH session off, but it doesn't
print("Killed agent connection, waiting...")
time.sleep(10)

# only now when the script exits does my SSH session get forcibly closed

Is this expected behaviour? A bug? I know what I'd expect to happen (disconnect = remove tunnel and disconnect any connected hosts).

If anyone could shed some light on this that would be much appreciated.

Cheers

mathsman5133 commented 3 days ago

Update: in the time it took me to put together this post (perhaps 20-30min), my SSH client was closed

Connection to 1.tcp.au.ngrok.io closed by remote host.
Connection to 1.tcp.au.ngrok.io closed.

Which was nice to see. However, it would be nice to understand what's going on here.