Can Ansible use "sudo su -" if the sudo user is not allowed to run arbitrary scripts?

12,035

Solution 1

I had similar issues with teamviewer passwd, which wouldn't allow me to run with become: true either. This my task definition to setup a teamviewer password with ansible:

  - name: set teamviewer login to password only
    become: true
    become_method: sudo
    become_flags: 'su - root /bin/bash -c'
    command: 'teamviewer passwd {{ teamviewer_password }}'

This will run:

sudo su - root /bin/bash -c 'teamviewer passwd Th3Passw0r8'

As a sidenote: You can skip the become_*-stuff if you go with shell-task instead of command. But with that come ansible-warnings and far worse: escape-hell with your password. Don't go there.

Solution 2

Just add this to playbook:

become: yes
become_method: su

and before running playbook export below env variable on host server:

ANSIBLE_BECOME_EXE=’sudo su -‘

Here is the reference link.

Solution 3

I think this will work with

- name: install Git
  yum:
    name: git
    state: present
  become: yes
  become_method: sudo
  become_exe: "sudo su - /bin/bash -c"
Share:
12,035
nwinkler
Author by

nwinkler

Nothing to see here...

Updated on June 22, 2022

Comments

  • nwinkler
    nwinkler almost 2 years

    I am trying to use Ansible to automate software installation and setup on several remote machines. My personal user account on the machine is locked down, but I can use sudo su - to become the root user when I log in manually. Once I'm the root user, I can run things like yum install git and similar commands.

    When I tried to do that through Ansible, I tried the following to use Ansible's yum module:

    - name: install Git
      yum:
        name: git
        state: present
      become: yes
      become_method: sudo
      become_user: root
      become_exe: "sudo su -"
    

    When I ran this, it failed with an error saying that my user was not allowed to run the command

    sudo su - root /tmp/foobarbazblablabla
    

    What happens is that Ansible puts all of the Yum commands into a temporary script file and then tries to run that using the become method/exe.

    It turns out that my user has the permission to run sudo su -, but not run arbitrary scripts using sudo or sudo su -, and hence Ansible fails to run the above.

    I ended up using an ugly workaround like this:

    - name: install Git
      shell:
        cmd: |
          sudo su - <<EOF
          yum install -y git
          EOF
    

    This works, but is ugly and does not use Ansible's idempotent check mechanism.

    Is there a better way to do this in Ansible, where Ansible executes the sudo su - first, and then executes its set of commands in the opened sub shell? Or am I out of luck with this? I doubt that the security team will grant my user permissions to run arbitrary scripts using sudo. (On the other hand, it might not hurt to ask.)

    This is a description of a similar problem, but the suggested solutions are the same ugly hacks I used above: https://gist.github.com/nanobeep/3b3d614a709086ff832a

    One more instance of this error with a very similar error that I get: https://www.reddit.com/r/devops/comments/53hukf/ansible_centrify_become_root/

    fatal: [hostname]: FAILED! => {"changed": false, "failed": true, "module_stderr": "", 
    "module_stdout": "Sorry, user username is not allowed to execute 
    '/bin/sh -c echo BECOME-SUCCESS-msylkobbkasuuxlawgqppdpjxmeqirgd; LANG=en_US.UTF-8 LC_ALL=en_US.UTF-8 LC_MESSAGES=en_US.UTF-8 
    /usr/bin/python /home/username/.ansible/tmp/ansible-tmp-1474243234.94-154392424015843/lineinfile; rm -rf \"/home/username/.ansible/tmp/ansible-tmp-1474243234.94-154392424015843/\" > /dev/null 2>&1' 
    as root on hostname.\r\n", "msg": "MODULE FAILURE", "parsed": false}
    

    Update If I run sudo -l, this is displayed:

    User foo may run the following commands on this host:
        (root) /bin/kill
        (root) /bin/su - bar
        (root) su -
    
    • Paul Hodges
      Paul Hodges almost 6 years
      If you issue sudo -l what does it say?
    • nwinkler
      nwinkler almost 6 years
      I've added the output of sudo -l to the question
    • Kohei Nozaki
      Kohei Nozaki over 4 years
      This post says ANSIBLE_BECOME_EXE='sudo su -' helps coveros.com/ansible-privledge-escalation-using-sudo-su
  • nwinkler
    nwinkler almost 6 years
    I had tried that, and it turns out that my user is not allowed to run sudo su - /bin/bash. I am allowed to run the plain sudo su -, but not with any additional command. It might be worth asking our security team if they can grant me the permission to run sudo su - /bin/bash to make this work...
  • MillerGeek
    MillerGeek almost 6 years
    @nwinkler ultimately if they have you this locked down then allowing sudo su - is probably an accident. sudo is always better than su for auditability reasons, so if they are blocking sudo usage, allowing sudo su seems unintentional.
  • nwinkler
    nwinkler almost 6 years
    That was actually the first thing I tried, and it failed with the above error. Your second recommendation is similar to what I'm using now, where I'm wrapping the call to yum into an explicit sudo su -call, which works, but has the downside of not using the Ansible yum module with all its benefits...
  • ConstantFun
    ConstantFun over 3 years
    @MillerGeek What final command will be run when your playbook is run by ansible?