Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

open_tunnel is not closing sockets when it throws an exception #288

Open
gabeblack opened this issue Jan 11, 2024 · 3 comments
Open

open_tunnel is not closing sockets when it throws an exception #288

gabeblack opened this issue Jan 11, 2024 · 3 comments

Comments

@gabeblack
Copy link

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.

@pahaz pahaz added the wontfix label May 12, 2024
@pahaz
Copy link
Owner

pahaz commented May 12, 2024

Do you want to fix this bug?

@pahaz pahaz added the bug label May 12, 2024
@gabeblack
Copy link
Author

no, sorry. -- Found just invoking ssh -fN is a much better solution. I had forgotten that ssh client itself has very good tunnel 'daemon' support.

I contribute to projects on occasion and have to pick my battles.

@curlicode
Copy link

@gabeblack Thanks for pointing that alternative out. I packaged ssh_tunnel in the hopes of abstracting the process for others, but because my deployment environment does not need an ssh tunnel, it's probably better if I remove it altogether.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants