-
Notifications
You must be signed in to change notification settings - Fork 199
Description
I think I have pretty up-to-date versions installed:
- paramiko-3.4.0
- sshtunnel-0.4.0
- python 3.9.16:
I have tried with both open_tunnel and SSHTunnelForwarder. If one opens a tunnel and the tunnel throws an exception (e.g., the remote doesn't have the ssh_key installed), it seems impossible to get the tunnel to fully clean up all its resources. Even if one allows open_tunnel to go out of scope (or by calling stop() on the SSHTunnelForwarder), the local sockets that are listening for tunnel connections are not closed. Thus a subsequent attempt to open a new tunnel fails because the port is already in use. Actually, in the case of SSHTunnelForwarder, a call to close() hangs indefinitely (even if you pass in force=True).
Here is a simple example demonstrating the problem.
def run_tunnel():
with open_tunnel(tunnel_ip, ssh_pkey=pkey, local_bind_address=('',2345), remote_bind_address=(remote_ip,2345)):
time.sleep(10)
try:
run_tunnel() # don't have pkey installed at tunnel_ip, so an exception is raised
except:
print("First attempt to establish the tunnel has failed.")
print("Sleeping to give you time to run `netstat -apn | grep 2345` in another shell...")
time.sleep(30) # <--run the netstat program...
# If you install the `pkey` between the first and second call to `run_tunnel()` (i.e., during the sleep above),
# then this call will create the ssh connection, but the tunnel won't be established and you'll get error logs saying
# "Couldn't open tunnel :2345 <> <tunnel_ip>:2345 might be in use or destination not reachable
run_tunnel()
When running netstat -apn | grep 2345. You will get:
tcp 0 0 0.0.0.0:2345 0.0.0.0:* LISTEN python3
indicating that the python program is still listening on port 2345, even though at that point in the program the context manager for open_tunnel has already closed and the server and sockets should have been cleaned up.