2
votes

I'm setting up an Ansible server running on CentOS 7 (with AWX as User Interface) and I want to communicate with a few windows hosts to perform basic package manipulation.

As a first approach, I'm using NTLM to communicate with my hosts (Basic Auth is disabled by the sysadmin).

However, I noticed that my playbooks fail to run when I launch ansible-playbook without sudo privileges.

I've already checked the TCP stream in both case. And it seems that when it fails (ie. without sudo rights) the server doesn't event start to communicate with the host. As if it failed without even trying (despite telling otherwise)

It's not a matter of firewall, since I am able to access the wsman endpoint with curl.

I've also checked the Windows account's rights (as was suggested for a similar problem), but everything that's needed was already there.

My playbook is this very simple taskless file:

- hosts: win
  vars:
    ansible_user: ansible_admin
    ansible_connection: winrm
    ansible_winrm_server_cert_validation: ignore
    ansible_port: 5985
    ansible_winrm_transport: ntlm

I've checked with and without tasks (like win_ping) and the ansible_winrm_server_cert_validation variable.

My /etc/ansible/hosts file is this one:

[win]
192.168.0.42

[localhost]
127.0.0.1

Here's what I get when I run the playbook without sudo right

$ ansible-playbook helloworld.yml --ask-pass -vvvvv
ansible-playbook 2.7.9
config file = /etc/ansible/ansible.cfg
configured module search path = [u'/var/lib/awx/.ansible/plugins/modules', u'/usr/share/ansible/plugins/modules']
ansible python module location = /usr/lib/python2.7/site-packages/ansible
executable location = /usr/bin/ansible-playbook
python version = 3.6.7 (default, Dec 5 2018, 15:02:05) [GCC 4.8.5 20150623 (Red Hat 4.8.5-36)]
Using /etc/ansible/ansible.cfg as config file
SSH password:
setting up inventory plugins
/etc/ansible/hosts did not meet host_list requirements, check plugin documentation if this is unexpected
Set default localhost to 127.0.0.1
Parsed /etc/ansible/hosts inventory source with ini plugin
Loading callback plugin default of type stdout, v2.0 from /usr/lib/python3.6/site-packages/ansible/callback/default.py

PLAYBOOK: hello_world.yml ******************************************************
1 plays in hello_world.yml

PLAY [win] ******************************************************

TASK [Gathering Facts] *********************************************************
task path: /home/ansible/playbooks/hello_world.yml:1
Using module file /usr/lib/python3.6/site-packages/ansible/modules/windows/setup.ps1
<192.168.0.42> ESTABLISH WINRM CONNECTION FOR USER: ansible_admin on PORT 5985 TO 192.168.0.42
checking if winrm_host 192.168.0.42 is an IPv6 address
<192.168.0.42> WINRM CONNECT: transport=ntlm endpoint=http://192.168.0.42:5985/wsman
<192.168.0.42> WINRM CONNECTION ERROR: the specified credentials were rejected by the server
Traceback (most recent call last):
  File "/usr/lib/python3.6/site-packages/ansible/plugins/connection/winrm.py", line 402, in _winrm_connect
    self.shell_id = protocol.open_shell(codepage=65001)  # UTF-8
  File "/usr/lib/python3.6/site-packages/winrm/protocol.py", line 157, in open_shell
    res = self.send_message(xmltodict.unparse(req))
  File "/usr/lib/python3.6/site-packages/winrm/protocol.py", line 234, in send_message
    resp = self.transport.send_message(message)
  File "/usr/lib/python3.6/site-packages/winrm/transport.py", line 243, in send_message
    self.build_session()
  File "/usr/lib/python3.6/site-packages/winrm/transport.py", line 232, in build_session
    self.setup_encryption()
  File "/usr/lib/python3.6/site-packages/winrm/transport.py", line 238, in setup_encryption
    self._send_message_request(prepared_request, '')
  File "/usr/lib/python3.6/site-packages/winrm/transport.py", line 266, in _send_message_request
    raise InvalidCredentialError("the specified credentials were rejected by the server") winrm.exceptions.invalidCredentialError: the specified credentials were rejected by the server
fatal: [192.168.0.42]: UNREACHABLE! => {
    "changed": false, 
    "msg": "ntlm: the specified credentials were rejected by the server",
    "unreachable": true
}
        to retry, use: --limit @/home/ansible/playbooks/hello_world.retry
PLAY RECAP *********************************************************************
192.168.0.42               : ok=0    changed=0    unreachable=1    failed=0   

But when I run the playbook with sudo rights, this works just fine

$ sudo ansible-playbook helloworld.yml --ask-pass -vvvvv
ansible-playbook 2.7.9
config file = /etc/ansible/ansible.cfg
configured module search path = [u'/var/lib/awx/.ansible/plugins/modules', u'/usr/share/ansible/plugins/modules']
ansible python module location = /usr/lib/python2.7/site-packages/ansible
executable location = /usr/bin/ansible-playbook
python version = 3.6.7 (default, Dec 5 2018, 15:02:05) [GCC 4.8.5 20150623 (Red Hat 4.8.5-36)]
Using /etc/ansible/ansible.cfg as config file
SSH password:
setting up inventory plugins
/etc/ansible/hosts did not meet host_list requirements, check plugin documentation if this is unexpected
Set default localhost to 127.0.0.1
Parsed /etc/ansible/hosts inventory source with ini plugin
Loading callback plugin default of type stdout, v2.0 from /usr/lib/python3.6/site-packages/ansible/callback/default.py


PLAYBOOK: hello_world.yml ******************************************************
1 plays in hello_world.yml

PLAY [win] ******************************************************

TASK [Gathering Facts] *********************************************************
task path: /home/ansible/playbooks/hello_world.yml:1
Using module file /usr/lib/python3.6/site-packages/ansible/modules/windows/setup.ps1
<192.168.0.42> ESTABLISH WINRM CONNECTION FOR USER: ansible_admin on PORT 5985 TO 192.168.0.42
checking if winrm_host 192.168.0.42 is an IPv6 address
<192.168.0.42> WINRM CONNECT: transport=ntlm endpoint=http://192.168.0.42:5985/wsman
<192.168.0.42> WINRM OPEN SHELL: E04DA2D8-15E4-4B28-A079-A5C795B612C5
EXEC (via pipeline wrapper)
<192.168.0.42> WINRM EXEC 'Powershell' ['-NoProfile', '-NonInteractive', '-ExecutionPolicy', 'Unrestricted', '-EncodedCommand', '<-- Very long string here -->']
<192.168.0.42> WINRM RESULT '<Response code 1, out "{"changed":false,"an", err "#< CLIXML\r\n<Objs Ver">'
<192.168.0.42> WINRM CLOSE SHELL: E04DA2D8-15E4-4B28-A079-A5C795B612C5
ok: [192.168.0.42]

PLAY RECAP *********************************************************************
192.168.0.42               : ok=1    changed=0    unreachable=0    failed=0 

Does someone have an explanation for this?

Or, as a workaround, is it possible to run a playbook on AWX with sudo privileges?

Edit: Added output with extra verbosity

1
Hi Gkyo, welcome to SO. Please run ansible-playbook with increased verbosity, so maybe we can find out if there is a debug message that would explain your experience: ansible-playbook -vvvv helloworld.yml --ask-pass. And, as always, please post your playbookmdaniel
Hi Matthew, thanks for your reply. I've edited the original post to include the output with level 5 verbosity, the playbook, and the hosts file.Gkyo
What I suspect is going on is that there is some magic config present in /root or maybe the opposite: a python package is installed with the wrong permissions such that the normal ansible user can't read them. I would suggest you try two things: install ansible into a virtualenv to ensure you have all the deps needed and to isolate it from whatever might be going on with that machine, and then if it still doesn't work, try some of the test scripts in the winrm.tests package to see if you can, in fact, use winrm at allmdaniel

1 Answers

0
votes

If you're using AWX, you need to check your credentials correctly, especially on Privilege Escalation Method, if you want to specify the type of escalation privilege to assign to specific users.