34

I need to create tunneling to read information from a database. I use Paramiko, but I have not worked with tunneling yet. Please provide an example of a simple code that creates and closes a tunnel.

2
  • Are you looking for a server or a client, or both? Are you sure you need it in Python? How about tunneling with SSH? Commented Nov 17, 2011 at 15:35
  • try pip install sshtunnel Commented Feb 11, 2016 at 9:41

5 Answers 5

17

I used sshtunnel for my projects. Example of the forwarding remote local MySQL port to the host local port:

pip install sshtunnel
python -m sshtunnel -U root -P password -L :3306 -R 127.0.0.1:3306 -p 2222 localhost
Sign up to request clarification or add additional context in comments.

Comments

16

At work we usually create ssh tunnels forwarding ports. The way we do that is, by using the standard command ssh -L port:addr:port addr with subprocess running in a separate thread. I found this useful link: https://github.com/paramiko/paramiko/blob/master/demos/forward.py with an example of doing port forwarding with paramiko.

3 Comments

thanks for the link but I can not run this code. He asks arguments. but the arguments that I enter not working. Give an example please line launch.
Example: this command: "ssh -L 5555:machine2:55 machine1" will connect to machine1:22 and it will forward any connection from your computer:5555 through machine1:22 to machine2:55. Suppose you want to forward your own ssh service to another port, the command to do that is: "ssh -L 5555:localhost:22 localhost". So if you do "ssh localhost -p 5555" it will connect you to your own localhost:22.To do that using the paramiko "forward.py" demo, you have to run it this way: "python forward.py localhost -p 5555 -r localhost:22". Execute it and in another terminal run ssh localhost -p 5555
@dario For creating multiple forwards with -L1, -L2, -Ln?
12

Even though this does not use paramiko, I believe it's a very clean solution to implement (similar to @dario's answer but without managing the thread in python).

There's this little-mentioned feature in openssh client that allows us to control a ssh process through a unix socket, quoting man ssh:

-M      Places the ssh client into “master” mode for connection sharing.  Multiple -M options places ssh
         into “master” mode with confirmation required before slave connections are accepted.  Refer to the
         description of ControlMaster in ssh_config(5) for details.
-S ctl_path
         Specifies the location of a control socket for connection sharing, or the string “none” to disable
         connection sharing.  Refer to the description of ControlPath and ControlMaster in ssh_config(5)
         for details.

So you can start background process of ssh (with -Nf) and then check (or terminate) it with a another ssh call.

I use this in a project that requires a reverse tunnel to be established

from subprocess import call, STDOUT
import os
DEVNULL = open(os.devnull, 'wb')


CONFIG = dict(
    SSH_SERVER='ssh.server.com',
    SSH_PORT=2222,
    SSH_USER='myuser',
    SSH_KEY='/path/to/user.key',
    REMOTE_PORT=62222,
    UNIX_SOCKET='/tmp/ssh_tunnel.sock',
    KNOWN_HOSTS='/path/to/specific_known_host_to_conflicts',
)


def start():
    return call(
        [
            'ssh', CONFIG['SSH_SERVER'],
            '-Nfi', CONFIG['SSH_KEY'],
            '-MS', CONFIG['UNIX_SOCKET'],
            '-o', 'UserKnownHostsFile=%s' % CONFIG['KNOWN_HOSTS'],
            '-o', 'ExitOnForwardFailure=yes',
            '-p', str(CONFIG['SSH_PORT']),
            '-l', CONFIG['SSH_USER'],
            '-R', '%d:localhost:22' % CONFIG['REMOTE_PORT']
        ],
        stdout=DEVNULL,
        stderr=STDOUT
    ) == 0


def stop():
    return __control_ssh('exit') == 0


def status():
    return __control_ssh('check') == 0


def __control_ssh(command):
    return call(
        ['ssh', '-S', CONFIG['UNIX_SOCKET'], '-O', command, 'x'],
        stdout=DEVNULL,
        stderr=STDOUT
    )

-o ExitOnForwardFailure=yes makes sure the ssh command will fail if the tunnel cannot be established, otherwise it will not exit.

2 Comments

I'm intrigued with this solution. Once I'm connected, how may I send commands to the server?, e.g.: "ifconfig" and get the output back in my client?. Thanks.
Using this exactly, you cannot @subzero. This was meant to answer OP question which was controlling an ssh tunnel
0

Might I suggest trying something like pyngrok to programmatically manage an ngrok tunnel for you? Full disclosure, I am the developer of it. SSH example here, but it's as easy as installing pyngrok:

pip install pyngrok

and using it:

from pyngrok import ngrok

# <NgrokTunnel: "tcp://0.tcp.ngrok.io:12345" -> "localhost:22">
ssh_tunnel = ngrok.connect(22, "tcp")

1 Comment

what's the advantage of this over sshtunnel ? I have a paid ngrok account already.
-6

I used paramiko for some project I had a year ago, here is the part of my code where I connected with another computer/server and executed a simple python file:

import paramiko

ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect(hostname='...', username='...', password='...')
stdin, stdout, stderr = ssh.exec_command('python hello.py')
ssh.close()

stdin, stdout and sdterr contain the inputs/outputs of the command you executed.

From here, I think you can make the connection with the database.

Here is some good information about paramiko.

1 Comment

How does that answer the question?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.