Execute sudo as a different user

Hi,
To manage a large farm of servers while maintaining security we do not provide a privileged-enable user by SSH, but want to have a non-ssh user to perform sudo operations.
However, while adopting Ansible, we have not been able to acomplish this privilege escalation.

Sudo and su are mutual exclusive, but running sudo with a different user as the ssh user isn’t working, as the SSH user is the one performing the sudo operation (at the end it executes sudo -u right?).

What privilege escalation are you using on your farms?
SSH and the same user has sudo privileges?

Thanks

I’m sorry, I’m having some difficulty processing the sentences above.

The phrase “priveledge escalation” usually refers to a security vulnerability.

Are you having specific problems with su or sudo support in Ansible, and if so, can you share more details about your playbook and what “isn’t working” means to you?

I have a hard time understandingwhat “isn’t working” means.

Thanks!

Michael,
Sure!

The goal is to be able to separate the user than connects to the server from the user that runs privileged commands (even if using sudo).
If ssh user is different than sudo user, does it imply that sudo commands will be executed as sudo --user?

Are you meaning like this?

$ ansible localhost -a whoami
localhost | success | rc=0 >>
badger

$ ansible localhost -a whoami -K --sudo
sudo password:
localhost | success | rc=0 >>
root

$ ansible localhost -a whoami -K --sudo -U testuser
sudo password:
localhost | success | rc=0 >>
testuser

In a playbook, that looks something like:

$ cat test.yml
- hosts: localhost
  sudo: yes
  tasks:
    - command: whoami
      register: output
    - debug: var=output

$ ansible-playbook test.yml -K

Docs for this are at:
http://docs.ansible.com/playbooks_intro.html#hosts-and-users

-Toshio

I have a similar issue that we just ran into.

We can’t have root ssh to our clients.

We need to copy file from our master to our clients that is mode u+r / 0400 and this means our admins can’t read the file while they are “themselves”.

If we run the command as a non-priveleged user, then they can’t read the file.

[urew@cfg ansible]$ ansible 10.10.5.63 -m authorized_key -a “user=urmm key="{{ lookup(‘file’, ‘/home/urmm/.ssh/id_rsa.pub’) }}" manage_dir=yes state=present” -u urew --sudo
sudo password:
10.10.5.63 | success >> {
“changed”: false,
“key”: “”,
“key_options”: null,
“keyfile”: “/home/urmm/.ssh/authorized_keys”,
“manage_dir”: true,
“path”: null,
“state”: “present”,
“unique”: false,
“user”: “urmm”
}

[urew@cfg ansible]$

If we run the command as root, then we can’t authenticate to the clients.

[root@cfg ansible]# ansible 10.10.5.63 -m authorized_key -a “user=urmm key="{{ lookup(‘file’, ‘/home/urmm/.ssh/id_rsa.pub’) }}" manage_dir=yes state=present” -u urew
sudo password:
10.10.5.63 | FAILED => FAILED: Authentication failed.

What am I missing please? I’ve looked and I’ve looked but (obviously?) I’m looking for the wrong thing.

If I understand you correctly, you want to run the command as root so
that the file can be accessed on the local machine. Then you want to
use the credentials for an unprivileged user to login to the remote
machine. On the remote machine, you want to use sudo to switch to
either root or the user whose key you are saving.

All correct?

If so, you want something like this:

# ansible rhel6 -m authorized_key -a "user=testuser1
key=\"{{lookup('file', '/root/authorized_keys') }}\" manage_dir=yes
state=present" -u badger -k --sudo -K -U testuser1
SSH password:
sudo password [defaults to SSH password]:
rhel6 | success >> {
    "changed": true,
[...]
}

Note that we're involving three accounts here:

1) Root on the local machine. You're somehow already authenticated to
root here.

2) The account that you are using to log into the remote machine. In
my example, this is badger, in yours it's urew. The username is
specified with "-u" In my example I used an SSH password and so I
used "-k". If you want to use an SSH key, you will need to have one
of the ssh private keys belonging to root in /root/.ssh/ on the local
machine and the public key matching that key in the remote machine's
/home/urew/.ssh/authorized_keys file.

2.5) The remote account that's allowed to use sudo. This is the same
account as the one that's allowed to login. So it's badger in my
example and urew in yours. I specify "-K" and --sudo so that ansible
knows that I want to use sudo and that I need to enter a sudo password
to use it.

3) The remote user that is writing the file (the one that we're
sudo'ing to). In my example I used '-U testuser1' to sudo to the
account whose key I was writing. You could also omit the '-U
testuser1' if your admins are allowed to sudo to root on the remote
machine once they have logged in via an unprivileged user.

Hope that long explanation is helpful in understanding the concepts as
well as the solution to your problem!

-Toshio

Thanks!

Having the same user to do the connection and run sudo does not seems a good fit.
And SU is not an option since the password cannot be stored in the inventory file.

The user you connect as, and sudo to, are both seperately configurable.

Yes, but as for the sudo limitation (or scope), the user connected is the one invoking the sudo commands (even if they will be run as a different user than root).
So, at the end, and I might be a little paranoic here, the same user you’re connecting will be invoking the sudo commands.

To the end, how’s ansible invoking the sudo command when an alternative sudo user has been specified?

Provided I understand you correctly, this is how users, accounts, and permissions work on Unix-like systems. It’s nothing special to ansible.

  1. You give one user’s credentials to a system and the system then executes commands as that user. This is what happens when you ssh into a box. You would not expect to present your username and ssh private key to a machine and then be able to run commands as me.

  2. Once logged in, the system contains a few commands that let you run commands as a different user. This is what sudo is doing. From your account you could run sudo -u toshio whoami and if sudo is configured to give you that access, it lets you run whoami as my account. Similarly, sudo whoami is asking sudo to run the command as the root account and if sudo is configured to do so, it will do that.

If the system were to let you connect as one user but then run commands as a different user without going through a defined facility like su or sudo it would entirely defeat the purpose of permissions and separate accounts. Any user with an account on the box would be able to access the files of other users and run commands that performed root actions on the box.

So when ansible connects to a box with a sudo user specified it first connects to the box with your credentials, the system then allows ansible to perform actions on your behalf. Ansible then runs the equivalent of sudo -u SUDOUSER command to perform that command as the user you specified. Sudo reads its configuration to determine if you are allowed to run that command as SUDOUSER. If so, the system rubs the command as SUDOUSER and ansible returns success to you.

This is all rooted in the standard unix permission model and supported by standard unix utilities. Ansible doesn’t do anything outside of this model.

Now it sounds like what you may want to achieve is having a user account foo on your main box use ansible to run commands on another box as user account bar. You have sudo on the other box configured to allow the bar account to run administrative commands.

To do that you need foo to ssh to the other box using the bar user’s credentials (usually username and a private key whose public key is listed in bar’s .ssh/authorized_keys file.) In most cases this is best accomplished by adding the foo user’s public key to the bar user’s .ssh/authorized_keys file on the remote machine. Then seeing the ansible ssh user to bar.

Hope that helps explain where confusion about what’s going on is occurring,

-toshio

Toshio,
Thanks for your answer.
Yes, we came up with the same conclusion: to use PKI to avoid exposing a user.

Thank you!