ткань: как сделать двойной тоннель

Ситуация: A и B — удаленные хосты. Локальная машина может подключиться по SSH к A, но не к B. B принимает SSH-соединения ТОЛЬКО от A.

Вопрос. Можно ли использовать структуру на локальном компьютере для выполнения команд на хосте Б, желательно без установки структуры на А?


person cranberry    schedule 28.05.2011    source источник


Ответы (6)


Мне удалось добиться этого с помощью env.gateway следующим образом:

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 предназначен только для включения переадресации вашего локального агента SSH на удаленный конец.

В качестве альтернативы вы можете использовать ssh ProxyCommand, пример здесь, и указать Fabric использовать ваш ~/.ssh/config с помощью use_ssh_config = True, документация здесь

person yeforriak    schedule 16.02.2016

Похоже, это может быть трюком:

https://gist.github.com/856179

person jsw    schedule 22.07.2011
comment
Попробовал это, и он делает именно то, что ОП просил +1 - person radman; 25.05.2012

Начиная с Fabric v1.5+, существует метод remote_tunnel для решения ситуации с клюквой.

Я использовал простую команду (имя хоста), чтобы проиллюстрировать решение, но вместо нее можно использовать любую другую команду. Как видите, мы вызвали команду для выполнения на remote_machineB с local_machine, используя remote_machineA в качестве узла перехода:

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")

Если вы запустите этот потрясающий файл в local_machine, вот что мы получим:

[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

Для этого очень важно настроить этот демон ssh машины перехода с GatewayPorts yes. В противном случае удаленный туннель был бы доступен только с локального хоста.

Проверять:

tcp        0      0 127.0.0.1:22022         0.0.0.0:*               LISTEN     

против:

tcp        0      0 0.0.0.0:22022           0.0.0.0:*               LISTEN     

Для получения дополнительной информации см. официальную документацию http://docs.fabfile.org/en/latest/api/core/context_managers.html#fabric.context_managers.remote_tunnel

person Fernando Martin    schedule 17.12.2014

Я просто оставлю это здесь: http://www.popcornfarmer.com/2009/01/ssh-tunneling-tutorial/

person Hassek    schedule 11.04.2012

В качестве варианта ответа yeforriak, если вы хотите сделать это только для отдельной задачи, вы можете сделать:

from fabric.api import *

@with_settings(forward_agent=True, gateway='user@remote_MachineA')
@hosts(['user@remote_MachineB'])
def function1():
  run('hostname')
person gasman    schedule 01.10.2019

Я просто собираюсь ответить на часть SSH: Да, вы можете настроить двойной туннель — один SSH от локального до A, который туннелирует от дополнительного локального порта (например, 2121) к порту 21 на B, а затем вы можете SSH на localhost:2121 и войдите в систему B. Я делал подобные вещи с PuTTY.

Реализация этого в ткани остается в качестве упражнения.

person LHMathies    schedule 28.05.2011