How to close this ssh tunnel? [closed]

I opened a ssh tunnel as described in this post: Zend_Db: How to connect to a MySQL database over SSH tunnel?

But now I don't know what I actually did. Does this command affect anything on the server? And how do I close this tunnel, because now I can't use my local mysql properly.

I use OSX Lion and the server runs on Ubuntu 11.10.


Solution 1:

Assuming you ran this command: ssh -f [email protected] -L 3306:mysql-server.com:3306 -N as described in the post you linked.

A breakdown of the command:

  1. ssh: that's pretty self-explanatory. Invokes ssh.
  2. -f: (From the man ssh page)

    Requests ssh to go to background just before command execution. This is useful if ssh is going to ask for passwords or passphrases, but the user wants it in the background.

    Essentially, send ssh to background once you've entered any passwords to establish the connection; it gives the shell prompt back to you at localhost rather than logging you in to remote-host.

  3. [email protected]: the remote server you'd like to log into.
  4. -L 3306:mysql-server.com:3306: This is the interesting bit. -L (from the man ssh page):

    [bind_address:]port:host:hostport Specifies that the given port on the local (client) host is to be forwarded to the given host and port on the remote side.

    So -L 3306:mysql-server.com:3306 binds the local port 3306 to the remote port 3306 on host mysql-server.com.

    When you connect to local port 3306, the connection is forwarded over the secure channel to mysql-server.com. The remote host, mysql-server.com then connects to mysql-server.com on port 3306.

  5. -N: don't execute a command. This is useful for "just forwarding ports" (quoting the man page).

Does this command affect anything on the server?

Yes, it establishes a connection between localhost and mysql-server.com on port 3306.

And how do I close this tunnel...

If you've used -f, you'll notice that the ssh process you've opened heads into the background. The nicer method of closing it is to run ps aux | grep 3306, find the pid of the ssh -f ... -L 3306:mysql-server.com:3306 -N, and kill <pid>. (Or maybe kill -9 <pid>; I forget if just kill works). That has the beautiful benefit of not killing all your other ssh connections; if you've got more than one, re-establishing them can be a slight ... pain.

... because now I can't use my local mysql properly.

This is because you've effectively "captured" the local mysql process and forwarded any traffic that attempts to connect to it, off to the remote mysql process. A much nicer solution would be to not use local port 3306 in the port-forward. Use something that's not used, like 33060. (Higher numbers are generally less used; it's pretty common to port-forward a combination like this: "2525->25", "8080->80", "33060->3306" or similar. Makes remembering slightly easier).

So, if you used ssh -f [email protected] -L 33060:mysql-server.com:3306 -N, you'd then point your Zend connect-to-mysql function to localhost on port 33060, which would connect to mysql-server.com on port 3306. You can obviously still connect to localhost on port 3306, so you can still use the local mysql server.

Solution 2:

This will kill all ssh sessions that you have open from the terminal.

sudo killall ssh

Solution 3:

Note: adding as answer since comments don't support code blocks.

In my opinion it is better to NOT use -f and instead just background the process as normal with &. That will give you the exact pid you need to kill:

ssh -N -L1234:other:1234 server &
pid=$!
echo "waiting a few seconds to establish tunnel..."
sleep 5
... do yer stuff... launch mysql workbench whatever
echo "killing ssh tunnel $pid"
kill $pid

Or better yet, just create this as a wrapper script:

# backend-tunnel <your cmd line, possibly 'bash'>
ssh -N -L1234:other:1234 server &
pid=$!
echo "waiting a few seconds to establish tunnel..."
sleep 5
"$@"
echo "killing ssh tunnel $pid"
kill $pid

backend-tunnel mysql-workbench

backend-tunnel bash