[英]Python ssh tunneling over multiple machines with agent
對於這個問題,有一點上下文:我正在制作一個應用程序,將文件/文件夾從一台機器復制到另一台機器上的python。 連接必須能夠通過多台機器。 我確實讓機器串行連接,所以我必須跳過它們,直到找到正確的機器。
目前,我正在使用 python 的子進程模塊 (Popen)。 作為一個非常簡單的例子,我有
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()
我的問題:當這樣做時,我似乎無法讓代理轉發工作,這在這樣的事情中是必不可少的。 有沒有辦法做到這一點?
我嘗試在 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
這樣做的問題是機器的名稱是由用戶輸入給出的,這意味着它們很容易注入惡意的 shell 代碼。 第二個問題是,我每次建立連接時都會運行一個新的 ssh-agent 進程。
我的 bashrc 中有一個很好的函數,它識別已經運行的 ssh-agents 並設置適當的環境變量並添加我的 ssh 密鑰,但是當然子進程無法引用我的 bashrc 中定義的函數。 我嘗試在 Popen 中使用 shell=True 設置 executable="/bin/bash" 變量無濟於事。
你應該試試Fabric 。
它提供了一套基本的操作來執行本地或遠程 shell 命令(通常或通過 sudo)和上傳/下載文件,以及諸如提示正在運行的用戶輸入或中止執行的輔助功能。
下面的程序會給你一個測試運行。 首先使用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')
切換到包含您的 fabfile 的目錄並運行fab run_interactive
然后您輸入的每個命令都將在服務器上運行
我測試了您的第一個簡單示例並且代理轉發有效。 我認為可能會導致問題的唯一想法是環境變量 SSH_AGENT_PID 和 SSH_AUTH_SOCK 在您執行腳本的 shell 中設置不正確。 您可以使用 ssh -v 來更好地了解事情發生在哪里。
嘗試設置 SSH 配置文件: https : //linuxize.com/post/using-the-ssh-config-file/
我經常需要通過堡壘服務器進行隧道傳輸,我在~/.ssh/config
文件中使用了這樣的~/.ssh/config
。 只需更改主機名和用戶名即可。 這還假定您的主機 ( /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
然后我可以使用以下語法訪問:
ssh my-bastion-server -At 'ssh my-target-host -At'
我針對my-target-host發出命令,例如:
ssh my-bastion-server -AT 'ssh my-target-host -AT "ls -la"'
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.