2

My situation: I have an Ansible server, a Tower server, a Windows file server, and a Windows client. Through Ansible, I want to tell the Windows client to copy some files from the Windows file server. After having trouble finding a playbook module that would allow me to copy files from a remote host to a client machine, I decided to try a series of different Powershell scripts and cmdlets to perform the simple file copy.

I appear to be running into the double hop problem and since an Ansible / Linux server is the originating machine in this scenario- and I don't have control of that machine- I was wondering if anyone has solved this problem and managed to get scripts to get past the double hop. Alternatively, if anyone knows of an Ansible module that can copy files from a remote host to a client host, that would be of interest, too. If I need to submit a ticket for the Ansible owners to do something, or if I need to do something, or if I should give up, whatever the case, thanks for your time!

DrewJenseric
  • 23
  • 1
  • 3
  • have you tried enabling kerberos delegation on the windows client computer? is everyone a domain joined machine? what about ansible...do you use kerberos or password authentication to winrm? – Jacob Evans Mar 22 '17 at 00:11
  • Why don't you mount the a file share from the file server on the target system and use `win_copy`? – Henrik Pingel Mar 22 '17 at 06:58
  • @JacobEvans, I knew I left out an important detail: In this scenario, I don't have any AD member machines; only workgroup machines. The file share mount idea... I will definitely try right now. – DrewJenseric Mar 22 '17 at 17:33
  • Looks like attempting to mount a share still requires that credentials be provided. – DrewJenseric Mar 22 '17 at 17:57
  • You don't have to mount the share to use it in PowerShell. You can access it directly through UNC path. `copy-item \\server\share\file.ext $destination` However, the account doing the copying needs permissions. Not sure if this helps, so that's why it's a comment instead of an answer. – Jeter-work Apr 28 '17 at 22:37
  • Good thinking- that's exactly the issue here, though. Because commands are invoked from the Ansible server to run on the Ansible client, credentials cannot be passed to the file server and the file server metaphorically taps its foot and tuts at the client for not having any credentials at all. CredSSP exists to get around this so I was happy to hear our Ansible admins were able to configure it for CredSSP. – DrewJenseric Apr 29 '17 at 02:09
  • The double-hop problem makes it so that there is no credential passed when attempting to access the UNC path. No matter what you do, by default, when operating remotely, no credential will be passed to anything that needs a credential, be it remote access or anything else, hence it being an issue with a name. – DrewJenseric May 03 '17 at 16:30

4 Answers4

3

While this is an absolute hack, and I'm sure you've already moved on from this problem, one workaround is to create a scheduled task (using the Windows schtasks command) and execute it immediately to perform the copy. The scheduled task will run in the proper context and be able to copy from the server without encountering the double-hop issue, because it originates from the client machine. I'm sure there's an actual Ansible-level solution to this problem, but this is my current workaround.

Your higher level script can use psutil or something similar to monitor the task and not return until the scheduled task has completed.

Here's an helper script I wrote in Python for accomplishing this:

# 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

You can call this from a higher level script to perform operations and circumvent the double hop. Very hacky, but it works. Example usage of script would be:

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

An alternative method is to call psexec on the target machine with the -s flag to use the System account. More information on that here: https://stackoverflow.com/questions/15242248/double-hop-access-to-copy-files-without-credssp

Robert Kelly
  • 146
  • 3
  • 2
    I have indeed moved on- turns out the server admin team found they can enable CredSSP on the Ansible server- but this solution is brilliant. Thank you. – DrewJenseric Apr 26 '17 at 22:58
0

Task scheduler under a non-built in account is not allowed in our environment due to security issues related to how the scheduling component stores credentials on windows. (No surprise there)

OPTION 1: Work that natively supports -Credential Ex: Copy-Item (OP's situation)

  • Create credential object using ansible secrets in your powershell script
  • Provide credential object to your Copy-Item -Credential $credentialObject

OPTION 2: Work that does not natively support -Credential DISCLAIMER: I have successfully done this outside of ansible where I go in as one admin account, register a session, exit the session, enter a new session using the newly registered session and execute powershell code undisturbed by double hop, get out and clean-up the registered session for situations where there is password rotation. Ex: IIS (where configuration file is stored on a protect cifs/smb share)/SCOM/SCCM/COM type of windows activity that does not overload -Credential parameter

  • Using ansible create a powershell session registration & session unregistration playbook that uses Register-PSSessionConfiguration & Unregister-PSSessionConfiguration built-in cmdlets

    • Register a new PSSession using the credentials that enable the file copy operation
  • Use the registered PSSession by name which will enable to you overcome double hop. You might need to do this from a 3rd utility server if ansible does not support connecting to the client by specifying a configuration name.

0

system account will access only resource inside local system with highest privileges. How can it access another server in UNC.

And if we create Sch taks with a different user and run it from ansible....it is creating with ansible account and sch tasks doesn't run as "the option selected by default is RUN only when user logged in"

0

There is a workaround for such issues. You can write a powsershell script on the middle machine and add it to task scheduler. Then execute that task-scheduler from ansible server, by executing the task itself