有人解决了 Ansible 和 Windows 客户端的双跳问题吗?

有人解决了 Ansible 和 Windows 客户端的双跳问题吗?

我的情况:我有一台 Ansible 服务器、一台 Tower 服务器、一台 Windows 文件服务器和一台 Windows 客户端。通过 Ansible,我想告诉 Windows 客户端从 Windows 文件服务器复制一些文件。在找不到允许我将文件从远程主机复制到客户端计算机的 playbook 模块后,我决定尝试一系列不同的 Powershell 脚本和 cmdlet 来执行简单的文件复制。

我似乎遇到了双跳问题,由于 Ansible / Linux 服务器是此场景中的发起机器 - 而我无法控制该机器 - 我想知道是否有人解决了这个问题并设法让脚本绕过双跳。或者,如果有人知道可以将文件从远程主机复制到客户端主机的 Ansible 模块,那也会很有趣。如果我需要提交工单让 Ansible 所有者做某事,或者如果我需要做某事,或者如果我应该放弃,无论如何,感谢您的时间!

答案1

虽然这绝对是一种黑客攻击,而且我相信你已经摆脱了这个问题,但一种解决方法是创建一个计划任务(使用 Windows调度任务命令)并立即执行以执行复制。计划任务将在适当的上下文中运行,并且能够从服务器复制而不会遇到双跳问题,因为它源自客户端计算机。我确信这个问题有一个实际的 Ansible 级解决方案,但这是我目前的解决方法。

您的高级脚本可以使用 psutil 或类似的东西来监视任务,并且直到计划的任务完成后才返回。

下面是我用 Python 编写的用于实现此目的的帮助脚本:

# run_as_scheduled_task.py
import psutil
import subprocess
import time
import sys

to_match = sys.argv[1]
to_run = ' '.join(sys.argv[2:])
print("Running the following command as immediate scheduled task:")
print(to_run)
print("Will return only once process matching wildcard \"{0}\" is no longer found".format(to_match))

subprocess.call('C:\\Windows\\System32\\schtasks /delete /f /tn "QUICKSCHTASK"', stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
subprocess.call('C:\\Windows\\System32\\schtasks /create /tn "QUICKSCHTASK" /tr "{0}" /sc ONCE /st 00:00'.format(to_run), stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
subprocess.call('C:\\Windows\\System32\\schtasks /run /tn "QUICKSCHTASK"', stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
time.sleep(0.1)

def processDead(proc):
    print("Process is now dead - {0}".format(proc))
    subprocess.call('C:\\Windows\\System32\\schtasks /delete /f /tn "QUICKSCHTASK"', stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)

process = None
for proc in psutil.process_iter():
    if to_match in proc.name():
        gone, still_alive = psutil.wait_procs([proc], None, processDead)
        break

您可以从更高级别的脚本调用此脚本来执行操作并绕过双跳。非常 hack,但有效。脚本的示例用法如下:

start /wait py -3 run_as_scheduled_task.py 'robocopy' 'robocopy SOURCE DEST'

另一种方法是使用 -s 标志在目标计算机上调用 psexec 以使用系统帐户。有关更多信息,请参见此处:https://stackoverflow.com/questions/15242248/double-hop-access-to-copy-files-without-credssp

答案2

系统帐户将仅以最高权限访问本地系统内的资源。它如何访问 UNC 中的另一台服务器。

如果我们用不同的用户创建 Sch 任务并从 ansible 运行它....它是用 ansible 帐户创建的,并且 sch 任务不会运行,因为“默认选择的选项仅在用户登录时运行”

答案3

有一种解决方法可以解决此类问题。您可以在中间机器上编写一个 powershell 脚本并将其添加到任务计划程序中。然后通过执行任务本身从 ansible 服务器执行该任务计划程序

答案4

由于与调度组件在 Windows 上存储凭据的方式相关的安全问题,我们的环境不允许使用非内置帐户下的任务调度程序。(这并不奇怪)

选项 1:原生支持 -Credential 的工作 例如:Copy-Item(OP 的情况)

  • 在 powershell 脚本中使用 ansible secrets 创建凭证对象
  • 向您的 Copy-Item -Credential $credentialObject 提供凭证对象

选项 2:不支持 -Credential 的工作免责声明:我已成功在 ansible 之外完成此操作,我以管理员帐户身份进入,注册一个会话,退出会话,使用新注册的会话进入新会话,并执行不受双跳干扰的 powershell 代码,退出并清理注册的会话,以防密码轮换。例如:IIS(配置文件存储在受保护的 cifs/smb 共享中)/SCOM/SCCM/COM 类型的 windows 活动不会过载 -Credential 参数

  • 使用 ansible 创建一个 powershell 会话注册和会话注销剧本,该剧本使用 Register-PSSessionConfiguration 和 Unregister-PSSessionConfiguration 内置 cmdlet

    • 使用启用文件复制操作的凭据注册新的 PSSession
  • 使用已注册的 PSSession 名称可以帮助您克服双跳。如果 ansible 不支持通过指定配置名称连接到客户端,您可能需要从第三个实用程序服务器执行此操作。

相关内容