Restrict Ansible script module using sudoers on th

2019-03-04 14:02发布

I have a playbook that performs some prechecks on the database as the Oracle user. The remote node is an AIX server and so I created a shell script that is ran via the playbook.

---
- hosts: db
  var_files:
    - ansible_var.yml

  tasks:
    - name: "DB Checks"
    become: True
    become_user: oracle
    script: "{ db_prechk }"

On the AIX server, I added the below entry to the sudoers file

 ansible ALL=(oracle) NOPASSWD: /tmp/ansible-tmp-*/db_prechecks.sh

But the playbook fails with the error that it's waiting for the privilege escalation prompt.

This runs fine if it is ran as root. However we do not want passwordless root between the Ansible controller and the remote nodes. So we created ansible user on the controller and remote nodes and exchanged the SSH keys.

This also runs if the sudoers entry is just

ansible ALL=(oracle) NOPASSWD: ALL

We do not want to provide full access to the oracle userid via the ansible user id too.

I ran the playbook in the verbose mode and can see that Ansible is copying the script to the remote_tmp dir and is executing it as the oracle userid. In that case the sudoers line should've allowed it to run?

标签: ansible
1条回答
仙女界的扛把子
2楼-- · 2019-03-04 14:56

If you look at the verbose mode output, you will see that the actual command differs from the one you specified in the sudoers file:

<127.0.0.1> SSH: EXEC ssh -o ForwardAgent=yes -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -o IdentitiesOnly=yes -o ControlMaster=auto -o ControlPersist=60s -o StrictHostKeyChecking=no -o Port=2202 -o 'IdentityFile="/Users/techraf/devops/testground/debian/.vagrant/machines/debian/virtualbox/private_key"' -o KbdInteractiveAuthentication=no -o PreferredAuthentications=gssapi-with-mic,gssapi-keyex,hostbased,publickey -o PasswordAuthentication=no -o User=ansible -o ConnectTimeout=120 -o ControlPath=/Users/techraf/.ansible/cp/ansible-ssh-%h-%p-%r -tt 127.0.0.1 '/bin/sh -c '"'"'sudo -H -S -n -u oracle /bin/sh -c '"'"'"'"'"'"'"'"'echo BECOME-SUCCESS-xoamupogqwtteubvedoscaghzmfascsr;  /tmp/ansible-tmp-1488508771.72-271591203197790/db_prechecks.sh '"'"'"'"'"'"'"'"' && sleep 0'"'"''

So what is executed after sudo -u oracle starts actually with /bin/sh -c.

I managed to filter a working string to:

ansible ALL=(oracle) NOPASSWD: /bin/sh -c echo BECOME-SUCCESS*; * /tmp/ansible-tmp-*/db_prechecks.sh*

But it is based on trial-and-error. I'm not sure yet why * is required between ; and /tmp/... and at the end, but otherwise it does not work.

In both places Ansible added superfluous space characters and it seems to be the reason, as adding a space to a shell command (specified in the sudoers file) does affect the ability to sudo.

You might try with ? instead of *, I will test later

查看更多
登录 后发表回答