Ситуация: A и B - удаленные хосты. Локальная машина может SSH в A, но не B. B ТОЛЬКО принимает SSH-соединения от A.
Вопрос: Можно ли использовать ткань на локальном компьютере для выполнения команд на хосте B, желательно без установки ткани на A?
Ситуация: A и B - удаленные хосты. Локальная машина может SSH в A, но не B. B ТОЛЬКО принимает SSH-соединения от A.
Вопрос: Можно ли использовать ткань на локальном компьютере для выполнения команд на хосте B, желательно без установки ткани на A?
Мне удалось достичь этого с помощью env.gateway следующим образом:
from fabric.api import *
env.forward_agent = True
env.gateway = '[email protected]_MachineA'
env.hosts = ['[email protected]_MachineB']
def function1():
run('hostname')
env.forward_agent = True
существует только для того, чтобы включить перенаправление локального агента SSH на удаленный конец
В качестве альтернативы вы можете использовать пример ssh ProxyCommand, здесь и сообщить тканью, чтобы использовать ваш ~/.ssh/config
, используя use_ssh_config = True
, документацию здесь
Похоже, это может быть трюк:
Так как Fabric v1.5 + существует метод, называемый remote_tunnel
, чтобы решить ситуацию с клюквой.
Я использовал простую команду (имя хоста) для иллюстрации решения, но вместо нее можно использовать любую другую команду. Как вы можете видеть, мы вызывали команду, которая должна быть выполнена на remote_machineB из local_machine, используя remote_machineA в качестве хоста перехода:
from fabric.api import settings, env, run, remote_tunnel
env.hosts=["[email protected]_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("[email protected]_machineA:22022")
Если вы выполните этот файл fab в файле local_machine, это мы получим:
[[email protected]_machine ~]# fab hostname_check
[[email protected]_machineA] Executing task 'hostname_check'
[[email protected]_machineA:22022] run: hostname
[[email protected]_machineA:22022] rtunnel: opened reverse tunnel: (u'X.X.3.75', 55804) -> ('X.X.3.78', 22) -> ('remote_machineB', 22)
[[email protected]_machineA:22022] out: remote_machineB
[[email protected]_machineA:22022] out:
Terminated
Для этого очень важно настроить этот демон ssh с помощью GatewayPorts yes
. В противном случае удаленный туннель был бы доступен только с localhost.
Check:
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
Я просто оставлю это здесь: http://www.popcornfarmer.com/2009/01/ssh-tunneling-tutorial/
Я просто собираюсь ответить на часть SSH: Да, вы можете настроить двойной туннель - один SSH от локального до A, который туннели от вторичного локального порта (например, 2121) до порта 21 на B, а затем вы можете использовать SSH для localhost: 2121 и логин на B. Я делал такие вещи с помощью PuTTY.
Реализация того, что в ткани остается как упражнение.
В качестве варианта ответа yeforriak, если вы хотите сделать это только для отдельной задачи, вы можете сделать следующее:
from fabric.api import *
@with_settings(forward_agent=True, gateway='[email protected]_MachineA')
@hosts(['[email protected]_MachineB'])
def function1():
run('hostname')