我正在尝试实现一个python脚本,它在远程CyberArk机器上执行本地bash脚本或简单命令。这是我的代码:
if __name__ == '__main__':
for ip in IP_LIST:
bash_cmd = f"ssh -o stricthostkeychecking=no {USER}%{LOCAL_USER}%{ip}@{PROXY} 'bash -s' < {BASH_SCRIPT}"
exit_code = subprocess.call(bash_cmd, shell=True)
print(exit_code)
bash_cmd = f"scp {USER}%{LOCAL_USER}%{ip}@{PROXY}:server_info_PY.txt ."
exit_code = subprocess.call(bash_cmd, shell=True)
print(exit_code)
主要的问题是,大多数情况下我都会得到这个CyberArk身份验证错误,但并不总是这样,所以它是随机的,我不知道为什么:
PSPSD072E Perform session error occurred. Reason: PSPSD033E Error receiving PSM For SSH server
response (Extra information: [289E [4426b00e-cc44-11ec-bca1-005056b74f99] Failed to impersonate as
user <user>. Error: [ITATS004E Authentication failure for User <user>.
在本例中,ssh退出代码为255,但如果我在远程机器上检查sshd服务日志,则不会出现错误。我甚至尝试使用os库来执行bash命令,但是得到了相同的结果。
在执行这个脚本很多次之后,我想要挂起多个ssh会话,但是在远程机器上,我只找到了我正在使用的会话。
有人能解释一下发生了什么事或者你有什么想法吗?
备注:--我对存储在变量代理中的PSM服务器没有任何访问权限
编辑1:我尝试使用Paramiko库创建ssh连接,但是我得到了一个与Paramiko相关的身份验证错误,而与CyberArk无关。我也尝试过基于Paramiko的织物库,所以它不起作用。
如果我尝试从我的终端手动运行相同的ssh命令,它就能工作,并且我可以看到它首先连接到代理,然后连接到远程机器的ip。从脚本端看,由于CyberArk身份验证错误,他甚至无法连接到代理。
编辑2:我记录了一些有关在执行python时运行的所有命令的信息,我发现启动的第一个命令是/bin/sh/ -c加上ssh字符串:
/bin/sh -c ssh <user>@<domain>
这可能是主要问题吗?/bin/sh -c的前缀?还是在使用子进程库时这是一种正常的行为?有一种方法可以只执行ssh命令,而不需要这个前缀?
编辑3:我删除了shell=True,但得到了相同的编辑错误。因此,如果我手动执行ssh命令,我不会得到任何错误,但是如果它是从python脚本执行的,我就会得到错误,但是在这两种情况下,我都找不到在进程级别使用ps的任何矛盾。
发布于 2022-05-10 15:39:48
由于身份验证错误是随机的,我只是添加了一个while循环,它重置known_hosts文件并运行ssh命令进行n次重试。
succeeded_cmd_exec = False
retries = 5
while not succeeded_cmd_exec:
if retries == 0:
break
bash_cmd = f'ssh-keygen -f "{Configs.KNOWN_HOSTS}" -R "{Configs.PROXY}"'
_, _, exit_code = exec_cmd(bash_cmd)
if exit_code == 0:
radius_password = generate_password(Configs.URI, Configs.PASSWORD)
bash_cmd = f"sshpass -p \"{radius_password}\" ssh -o stricthostkeychecking=no {Configs.USER}%{Configs.LOCAL_USER}%{ip}@{Configs.PROXY} 'ls'"
stdout, stderr, exit_code = exec_cmd(bash_cmd)
if exit_code == 0:
print('Output from SSH command:\n')
print(stdout)
succeeded_cmd_exec = True
else:
retries = retries - 1
print(stdout)
print('SSH command failed, retrying ... ')
print('Sleeping 15 seconds')
time.sleep(15)
else:
print('Reset known hosts files failed, retrying ...')
if retries == 0 and not succeeded_cmd_exec:
print(f'Failed processing IP {ip}')
exec_cmd函数的定义如下:
def exec_cmd(bash_cmd: str):
process = subprocess.Popen(bash_cmd, shell=True, executable='/bin/bash', stdout=subprocess.PIPE, stderr=subprocess.PIPE)
stdout, stderr = process.communicate()
process.wait()
return stdout.decode('utf-8'), stderr.decode('utf-8'), process.returncode
https://stackoverflow.com/questions/72123759
复制相似问题