在本地主机上使用 python 脚本将文件 (scp) 和 运行 命令从 jumpserver 传输到最终服务器
Transfer file(scp) and run command from jumpserver to finalserver using python script on localhost
需要将文件上传到最终服务器,并且需要 运行 使用该文件作为输入的命令。
以下是执行整个操作的步骤(但我卡在了第 3 步):
1 - 将文件从本地主机传输到 jumpserver(使用 scp)
2 - ssh 到 jumpserver
3 - 将文件从 jumpserver 传输到 finalserver(使用 scp)
4 - ssh 到最终服务器
5 - 运行 finalserver 上的命令(以文件作为输入)
try:
cmd_str = "scp " + file_path + " " + user + "@" + jumpbox + ":/tmp/"
print "---------local to jumpbox initiated:"
#print cmd_str
child = pexpect.spawn(cmd_str) #-------------------------------------------------------step 1
child.expect("password:")
#pwd = raw_input("please enter password along with yubikey:")
pwd = getpass.getpass("Enter password along with yubikey:")
child.sendline(pwd)
i = child.expect(['Permission denied', filename])
if i==0:
print "Permission denied on host. Can't login"
pwd = getpass.getpass("Enter password along with yubikey:")
child.sendline(pwd)
#child.kill(0)
elif i==1:
print "file successfully transferred to jumpbox"
#----SSHing into jumpbox
ssh_jump_cmd = "ssh " + user + "@" + jumpbox
print ssh_jump_cmd
ssh_child = pexpect.spawn(ssh_jump_cmd) #-------------------------------------------------------step 2
ssh_child.expect("password:")
pwd2 = getpass.getpass("Enter password along with yubikey:")
ssh_child.sendline(pwd2)
i2 = ssh_child.expect(['Permission denied', '[#$]'])
if i2 == 0:
print "Permission denied on host. Can't login. Try again"
pwd2 = getpass.getpass("Enter password along with yubikey:")
ssh_child.sendline(pwd2)
elif i2 == 1:
print "--------------Inside Jumpbox:"
#sending file from jumpbox to finalserver
ba_cmd = "scp /tmp/"+ filename + " " + cmd_var + ":/tmp/"
print ba_cmd
ba_child = pexpect.spawn(ba_cmd) #-------------------------------------------------------step 3
ba_child.expect("Enter passphrase for key:")
phrase = getpass.getpass("Enter passphrase: ")
ba_child.sendline(phrase)
print "Password should be asked:"
i3 = ba_child.expect(['Enter passphrase for key', 'Permission denied', filename])
if i3 == 0:
phrase = getpass.getpass("Enter passphrase: ")
ba_child.sendline(phrase)
elif i3 == 1:
print "Lost connection:"
ba_child.kill(0)
elif i3 == 2:
ssh_ba_cmd = "ssh " + smba
ba_ssh_child = pexpect.spawn(ssh_ba_cmd) #-------------------------------------------------------step 4
ba_ssh_child.expect("Enter passphrase for key: ")
phrase = getpass.getpass("Enter passphrase: ")
ba_ssh_child.sendline(phrase)
i4 = ba_ssh_child.expect(['Permission denied', '[#$]'])
if i4 == 0:
print "Passphrase incorrect. Exiting"
ba_ssh_child.kill(0)
elif i4 == 1:
final_cmd = "ls -l" + filename #- just an example for this question
final_child = pexpect.spawn(final_cmd)
print "********************"
print sys.stdout
我使用 Python Pexpect
生成子节点并成功通过 SSH 连接到 jumpserver。当脚本尝试从 jumpserver 到 finalserver 的 SCP 时,会生成以下错误:
scp /tmp/filename finalserver:/tmp/
End Of File (EOF). Exception style platform.
<pexpect.spawn object at 0x7efddfdad650>
version: 3.1
command: /usr/bin/scp
args: ['/usr/bin/scp', 'filename', 'finalserver:/tmp/']
searcher: <pexpect.searcher_re object at 0x7efddfdad5d0>
buffer (last 100 chars): ''
before (last 100 chars): 'ssh: Could not resolve hostname finalserver: Name or service not known\r\r\nlost connection\r\n'
after: <class 'pexpect.EOF'>
match: None
match_index: None
exitstatus: 1
flag_eof: True
pid: 7244
child_fd: 5
closed: False
timeout: 30
delimiter: <class 'pexpect.EOF'>
logfile: None
logfile_read: None
logfile_send: None
maxread: 2000
ignorecase: False
searchwindowsize: None
delaybeforesend: 0.05
delayafterclose: 0.1
delayafterterminate: 0.1
我经历了 但仍然需要帮助。
TIA。
我建议在服务器之间传输文件,用paramiko执行命令,看例子
import paramiko
local_path = "foo/bar"
remote_path = "bar/foo"
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect("remote_url", username='username')
sftp = ssh.open_sftp()
ssh.exec_command('mkdir -p '+ remote_path)
sftp.put(local_path, remote_path)
> ba_child = pexpect.spawn(ba_cmd)
您正在生成一个新的本地 child。您应该改为将 scp
命令发送到 ssh_child
,它是跳转服务器上的 运行 和 shell。
这里的语法不稳定,但类似于
ssh_child.sendline(ba_cmd)
需要将文件上传到最终服务器,并且需要 运行 使用该文件作为输入的命令。
以下是执行整个操作的步骤(但我卡在了第 3 步):
1 - 将文件从本地主机传输到 jumpserver(使用 scp)
2 - ssh 到 jumpserver
3 - 将文件从 jumpserver 传输到 finalserver(使用 scp)
4 - ssh 到最终服务器
5 - 运行 finalserver 上的命令(以文件作为输入)
try:
cmd_str = "scp " + file_path + " " + user + "@" + jumpbox + ":/tmp/"
print "---------local to jumpbox initiated:"
#print cmd_str
child = pexpect.spawn(cmd_str) #-------------------------------------------------------step 1
child.expect("password:")
#pwd = raw_input("please enter password along with yubikey:")
pwd = getpass.getpass("Enter password along with yubikey:")
child.sendline(pwd)
i = child.expect(['Permission denied', filename])
if i==0:
print "Permission denied on host. Can't login"
pwd = getpass.getpass("Enter password along with yubikey:")
child.sendline(pwd)
#child.kill(0)
elif i==1:
print "file successfully transferred to jumpbox"
#----SSHing into jumpbox
ssh_jump_cmd = "ssh " + user + "@" + jumpbox
print ssh_jump_cmd
ssh_child = pexpect.spawn(ssh_jump_cmd) #-------------------------------------------------------step 2
ssh_child.expect("password:")
pwd2 = getpass.getpass("Enter password along with yubikey:")
ssh_child.sendline(pwd2)
i2 = ssh_child.expect(['Permission denied', '[#$]'])
if i2 == 0:
print "Permission denied on host. Can't login. Try again"
pwd2 = getpass.getpass("Enter password along with yubikey:")
ssh_child.sendline(pwd2)
elif i2 == 1:
print "--------------Inside Jumpbox:"
#sending file from jumpbox to finalserver
ba_cmd = "scp /tmp/"+ filename + " " + cmd_var + ":/tmp/"
print ba_cmd
ba_child = pexpect.spawn(ba_cmd) #-------------------------------------------------------step 3
ba_child.expect("Enter passphrase for key:")
phrase = getpass.getpass("Enter passphrase: ")
ba_child.sendline(phrase)
print "Password should be asked:"
i3 = ba_child.expect(['Enter passphrase for key', 'Permission denied', filename])
if i3 == 0:
phrase = getpass.getpass("Enter passphrase: ")
ba_child.sendline(phrase)
elif i3 == 1:
print "Lost connection:"
ba_child.kill(0)
elif i3 == 2:
ssh_ba_cmd = "ssh " + smba
ba_ssh_child = pexpect.spawn(ssh_ba_cmd) #-------------------------------------------------------step 4
ba_ssh_child.expect("Enter passphrase for key: ")
phrase = getpass.getpass("Enter passphrase: ")
ba_ssh_child.sendline(phrase)
i4 = ba_ssh_child.expect(['Permission denied', '[#$]'])
if i4 == 0:
print "Passphrase incorrect. Exiting"
ba_ssh_child.kill(0)
elif i4 == 1:
final_cmd = "ls -l" + filename #- just an example for this question
final_child = pexpect.spawn(final_cmd)
print "********************"
print sys.stdout
我使用 Python Pexpect
生成子节点并成功通过 SSH 连接到 jumpserver。当脚本尝试从 jumpserver 到 finalserver 的 SCP 时,会生成以下错误:
scp /tmp/filename finalserver:/tmp/
End Of File (EOF). Exception style platform.
<pexpect.spawn object at 0x7efddfdad650>
version: 3.1
command: /usr/bin/scp
args: ['/usr/bin/scp', 'filename', 'finalserver:/tmp/']
searcher: <pexpect.searcher_re object at 0x7efddfdad5d0>
buffer (last 100 chars): ''
before (last 100 chars): 'ssh: Could not resolve hostname finalserver: Name or service not known\r\r\nlost connection\r\n'
after: <class 'pexpect.EOF'>
match: None
match_index: None
exitstatus: 1
flag_eof: True
pid: 7244
child_fd: 5
closed: False
timeout: 30
delimiter: <class 'pexpect.EOF'>
logfile: None
logfile_read: None
logfile_send: None
maxread: 2000
ignorecase: False
searchwindowsize: None
delaybeforesend: 0.05
delayafterclose: 0.1
delayafterterminate: 0.1
我经历了 但仍然需要帮助。
TIA。
我建议在服务器之间传输文件,用paramiko执行命令,看例子
import paramiko
local_path = "foo/bar"
remote_path = "bar/foo"
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect("remote_url", username='username')
sftp = ssh.open_sftp()
ssh.exec_command('mkdir -p '+ remote_path)
sftp.put(local_path, remote_path)
> ba_child = pexpect.spawn(ba_cmd)
您正在生成一个新的本地 child。您应该改为将 scp
命令发送到 ssh_child
,它是跳转服务器上的 运行 和 shell。
这里的语法不稳定,但类似于
ssh_child.sendline(ba_cmd)