[英]Python ssh tunneling over multiple machines with agent
A little context is in order for this question: I am making an application that copies files/folders from one machine to another in python.对于这个问题,有一点上下文:我正在制作一个应用程序,将文件/文件夹从一台机器复制到另一台机器上的python。 The connection must be able to go through multiple machines.
连接必须能够通过多台机器。 I quite literally have the machines connected in serial so I have to hop through them until I get to the correct one.
我确实让机器串行连接,所以我必须跳过它们,直到找到正确的机器。
Currently, I am using python's subprocess module (Popen).目前,我正在使用 python 的子进程模块 (Popen)。 As a very simplistic example I have
作为一个非常简单的例子,我有
import subprocess
# need to set strict host checking to no since we connect to different
# machines over localhost
tunnel_string = "ssh -oStrictHostKeyChecking=no -L9999:127.0.0.1:9999 -ACt machine1 ssh -L9999:127.0.0.1:22 -ACt -N machineN"
proc = subprocess.Popen(tunnel_string.split())
# Do work, copy files etc. over ssh on localhost with port 9999
proc.terminate()
My question: When doing it like this, I cannot seem to get agent forwarding to work, which is essential in something like this.我的问题:当这样做时,我似乎无法让代理转发工作,这在这样的事情中是必不可少的。 Is there a way to do this?
有没有办法做到这一点?
I tried using the shell=True keyword in Popen like so我尝试在 Popen 中像这样使用 shell=True 关键字
tunnel_string = "eval `ssh-agent` && ssh-add && ssh -oStrictHostKeyChecking=no -L9999:127.0.0.1:9999 -ACt machine1 ssh -L9999:127.0.0.1:22 -ACt -N machineN"
proc = subprocess.Popen(tunnel_string, shell=True)
# etc
The problem with this is that the name of the machines is given by user input, meaning they could easily inject malicious shell code.这样做的问题是机器的名称是由用户输入给出的,这意味着它们很容易注入恶意的 shell 代码。 A second problem is that I then have a new ssh-agent process running every time I make a connection.
第二个问题是,我每次建立连接时都会运行一个新的 ssh-agent 进程。
I have a nice function in my bashrc which identifies already running ssh-agents and sets the appropriate environment variables and adds my ssh key, but of cource subprocess cannot reference functions defined in my bashrc.我的 bashrc 中有一个很好的函数,它识别已经运行的 ssh-agents 并设置适当的环境变量并添加我的 ssh 密钥,但是当然子进程无法引用我的 bashrc 中定义的函数。 I tried setting the executable="/bin/bash" variable with shell=True in Popen to no avail.
我尝试在 Popen 中使用 shell=True 设置 executable="/bin/bash" 变量无济于事。
You should give Fabric a try.你应该试试Fabric 。
It provides a basic suite of operations for executing local or remote shell commands (normally or via sudo) and uploading/downloading files, as well as auxiliary functionality such as prompting the running user for input, or aborting execution.
它提供了一套基本的操作来执行本地或远程 shell 命令(通常或通过 sudo)和上传/下载文件,以及诸如提示正在运行的用户输入或中止执行的辅助功能。
The program below will give you a test run.下面的程序会给你一个测试运行。 First install fabric with
pip install fabric
then save the code below in fabfile.py
首先使用
pip install fabric
然后将下面的代码保存在fabfile.py
from fabric.api import *
env.hosts = ['server url/IP'] #change to ur server.
env.user = #username for the server
env.password = #password
def run_interactive():
with settings(warn_only = True)
cmd = 'clear'
while cmd is not 'stop fabric':
run(cmd)
cmd = raw_input('Command to run on server')
Change to the directory containing your fabfile and run fab run_interactive
then each command you enter will be run on the server切换到包含您的 fabfile 的目录并运行
fab run_interactive
然后您输入的每个命令都将在服务器上运行
I tested your first simplistic example and agent forwarding worked.我测试了您的第一个简单示例并且代理转发有效。 The only think that I can see that might cause problems is that the environment variables SSH_AGENT_PID and SSH_AUTH_SOCK are not set correctly in the shell that you execute your script from.
我认为可能会导致问题的唯一想法是环境变量 SSH_AGENT_PID 和 SSH_AUTH_SOCK 在您执行脚本的 shell 中设置不正确。 You might use ssh -v to get a better idea of where things are breaking down.
您可以使用 ssh -v 来更好地了解事情发生在哪里。
Try setting up a SSH config file: https://linuxize.com/post/using-the-ssh-config-file/尝试设置 SSH 配置文件: https : //linuxize.com/post/using-the-ssh-config-file/
I frequently am required to tunnel through a bastion server and I use a configuration like so in my ~/.ssh/config
file.我经常需要通过堡垒服务器进行隧道传输,我在
~/.ssh/config
文件中使用了这样的~/.ssh/config
。 Just change the host and user names.只需更改主机名和用户名即可。 This also presumes that you have entries for these host names in your hosts (
/etc/hosts
) file.这还假定您的主机 (
/etc/hosts
) 文件中有这些主机名的条目。
Host my-bastion-server
Hostname my-bastion-server
User user123
AddKeysToAgent yes
UseKeychain yes
ForwardAgent yes
Host my-target-host
HostName my-target-host
User user123
AddKeysToAgent yes
UseKeychain yes
I then gain access with syntax like:然后我可以使用以下语法访问:
ssh my-bastion-server -At 'ssh my-target-host -At'
And I issue commands against my-target-host like:我针对my-target-host发出命令,例如:
ssh my-bastion-server -AT 'ssh my-target-host -AT "ls -la"'
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.