Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

fabric: how to double tunnel

Tags:

python

ssh

fabric

Situation: A and B are remote hosts. Local machine can SSH into A, but not B. B ONLY accepts SSH connections from A.

Question: Is it possible to use fabric on the local machine to execute commands on Host B, preferably without having to install fabric on A?

like image 563
cranberry Avatar asked May 28 '11 12:05

cranberry


3 Answers

I managed to achieve this with env.gateway as follows:

from fabric.api import *

env.forward_agent = True
env.gateway = 'user@remote_MachineA'
env.hosts = ['user@remote_MachineB']

def function1():
  run('hostname')

env.forward_agent = True is there only to enable forwarding of your local SSH agent to the remote end

Alternatively, you can use ssh ProxyCommand, example here and tell fabric to use your ~/.ssh/config using use_ssh_config = True, documentation here

like image 100
yeforriak Avatar answered Nov 14 '22 01:11

yeforriak


Looks like this might to the trick:

https://gist.github.com/856179

like image 4
jsw Avatar answered Nov 14 '22 01:11

jsw


Since Fabric v1.5+ there is a method called remote_tunnel to solve cranberry situation

I have used a simple command (hostname) to illustrate the solution but any other command may be used instead. As you can see, we have invoked a command to be executed on remote_machineB from local_machine by using remote_machineA as jump host:

from fabric.api import settings, env, run, remote_tunnel

env.hosts=["user@remote_machineA"]

def funct1():
    def func1b(host):
        with settings(host_string=host):
            run("hostname")

    with remote_tunnel(remote_port=22022, local_port=22,
                       local_host="remote_machineB", remote_bind_address="0.0.0.0"):
        funct1b("user@remote_machineA:22022")

If you execute this fab file in local_machine this is what we get:

[user@local_machine ~]# fab hostname_check
[user@remote_machineA] Executing task 'hostname_check'
[user@remote_machineA:22022] run: hostname
[user@remote_machineA:22022] rtunnel: opened reverse tunnel: (u'X.X.3.75', 55804) -> ('X.X.3.78', 22) -> ('remote_machineB', 22)
[user@remote_machineA:22022] out: remote_machineB
[user@remote_machineA:22022] out:

Terminated

To do so it is very important to configure this jump machine ssh daemon with GatewayPorts yes. Otherwise remote tunnel would be accessible only from localhost.

Check:

tcp        0      0 127.0.0.1:22022         0.0.0.0:*               LISTEN     

versus:

tcp        0      0 0.0.0.0:22022           0.0.0.0:*               LISTEN     

For more info check official documentation http://docs.fabfile.org/en/latest/api/core/context_managers.html#fabric.context_managers.remote_tunnel

like image 3
Fernando Martin Avatar answered Nov 14 '22 01:11

Fernando Martin