# Privilege escalation by rsa key

**URL:** <https://forum.ansible.com/t/privilege-escalation-by-rsa-key/38344>\
**Category:** Ansible Project\
**Created:** [August 16, 2023, 8:31pm UTC](https://forum.ansible.com/t/privilege-escalation-by-rsa-key/38344 "2023-08-16T20:31:49Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![Evan\_Hisey](https://avatars.discourse-cdn.com/v4/letter/e/ce73a5/32.png) [@Evan\_Hisey](https://forum.ansible.com/u/Evan_Hisey)\
**Post date:** [August 16, 2023, 8:31pm UTC](https://forum.ansible.com/t/privilege-escalation-by-rsa-key/38344/1 "2023-08-16T20:31:49Z")

</div>

So I have been doing some rsa-key based to factor authentication work recently, but have hit a stumbling block with Ansible. Has anyone ever done key based privilege escalation? Apparently just use the ssh connection option ForwardAgent=true is not quite the same as “ssh -A” when doing escalation.

For those not familiar with rsa key privilege escalation via sudo this is a good link: [https://blog.byteschneiderei.com/setting-up-pam-ssh-agent-auth-for-sudo-login-7135330eb740](https://blog.byteschneiderei.com/setting-up-pam-ssh-agent-auth-for-sudo-login-7135330eb740)

Before I get advice to just use passwordless sudo, that is something I am looking for a way to avoid as it generates a massive amount of paperwork in the federal FISMA high and med spaces that require MFA and expected MFA elevated privilege access.

Manually I am very successful with the RSA key

[user@localhost vagrant-kube]$ ssh -A 10.0.0.18  
1 device has a firmware upgrade available.  
Run `fwupdmgr get-upgrades` for more information.  
Activate the web console with: systemctl enable --now cockpit.socket  
Last login: Wed Aug 16 14:07:25 2023 from 10.0.0.10  
[user@kube ~]$ sudo whoami  
root  
[user@kube ~]$ exit  
logout

However Ansible is not making the same connections:

[user@localhost vagrant-kube]$ ansible-playbook mvp.yml  
PLAY [all] \*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*  
TASK [Gathering Facts] \*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*  
fatal: [10.0.0.18]: FAILED! =\> {“msg”: “Missing sudo password”}  
PLAY RECAP \*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*  
10.0.0.18 : ok=0 changed=0 unreachable=0 failed=1 skipped=0 rescued=0 ignored=0

I have tried several options, and assume it is going to end up being something in the SSH connection options to get this working beyond using “ForwardAgent=Yes”

---

<div class="post-metadata">

**Author:** ![Pierre\_TOURON](https://avatars.discourse-cdn.com/v4/letter/p/b5a626/32.png) [@Pierre\_TOURON](https://forum.ansible.com/u/Pierre_TOURON)\
**Post date:** [August 19, 2023, 5:32pm UTC](https://forum.ansible.com/t/privilege-escalation-by-rsa-key/38344/2 "2023-08-19T17:32:39Z")

</div>

Hi,

I haven’t tested this myself, but [this article](https://jpmens.net/2021/11/21/pam-ssh-agent-authentication-with-ansible/) mentions that you’d need to set ansible\_become\_pass var somewhere with a potential dummy value. Give it a try !

---

<div class="post-metadata">

**Author:** ![Evan\_Hisey](https://avatars.discourse-cdn.com/v4/letter/e/ce73a5/32.png) [@Evan\_Hisey](https://forum.ansible.com/u/Evan_Hisey)\
**Post date:** [August 20, 2023, 1:38am UTC](https://forum.ansible.com/t/privilege-escalation-by-rsa-key/38344/3 "2023-08-20T01:38:17Z")

</div>

Pierre-  
That was the missing bit. This is definitely an issue in Ansible that probably needs to be addressed.

---

<div class="post-metadata">

**Author:** ![jborean](https://sea1.discourse-cdn.com/ansible/user_avatar/forum.ansible.com/jborean/32/1525_2.png) [@jborean](https://forum.ansible.com/u/jborean)\
**Post date:** [August 20, 2023, 10:34am UTC](https://forum.ansible.com/t/privilege-escalation-by-rsa-key/38344/4 "2023-08-20T10:34:59Z")

</div>

You can control what arguments Ansible uses to invoke the ssh binary with. See ssh\_extra\_args [1] for ways to set extra arguments. You can run Ansible with -vvv and it will show you the full ssh command being run on each connection.

[1] [https://docs.ansible.com/ansible/latest/collections/ansible/builtin/ssh\_connection.html](https://docs.ansible.com/ansible/latest/collections/ansible/builtin/ssh_connection.html)

---

<div class="post-metadata">

**Author:** ![Evan\_Hisey](https://avatars.discourse-cdn.com/v4/letter/e/ce73a5/32.png) [@Evan\_Hisey](https://forum.ansible.com/u/Evan_Hisey)\
**Post date:** [August 20, 2023, 2:18pm UTC](https://forum.ansible.com/t/privilege-escalation-by-rsa-key/38344/5 "2023-08-20T14:18:56Z")

</div>

Using ssh\_extra\_args does not solve the issue. There is already 2 other methods of ensuring the ssh side of the house work. The core issue turns out to be something of a known bug in ansible  
, ansible wants a password if you are not using passwordless sudo. The article linked by Pierre discovered ot.

This was easy to confirm by simple adding the “ansible\_become\_pass” with a garbage setting and it works, remove variable and it fails. Not sure if the ansible team is planning to address this or not.

---

<div class="post-metadata">

**Author:** ![jborean](https://sea1.discourse-cdn.com/ansible/user_avatar/forum.ansible.com/jborean/32/1525_2.png) [@jborean](https://forum.ansible.com/u/jborean)\
**Post date:** [August 20, 2023, 9:08pm UTC](https://forum.ansible.com/t/privilege-escalation-by-rsa-key/38344/6 "2023-08-20T21:08:04Z")

</div>

> ansible wants a password if you are not using passwordless sudo. The article linked by Pierre discovered ot.

Ansible only wants a password if it gets prompted by sudo for one, if there is no prompt there is no mandatory password. You can definitely use become sudo without a password normally and not have a password set.

---

<div class="post-metadata">

**Author:** ![Evan\_Hisey](https://avatars.discourse-cdn.com/v4/letter/e/ce73a5/32.png) [@Evan\_Hisey](https://forum.ansible.com/u/Evan_Hisey)\
**Post date:** [August 20, 2023, 11:22pm UTC](https://forum.ansible.com/t/privilege-escalation-by-rsa-key/38344/7 "2023-08-20T23:22:56Z")

</div>

Not true. If you dint give it a password and use rsa sudo it still.asks for password. Follow the article Pierre linked and you can reproduce the issue, i am using ansible 2.14. The only change between working and not working is setting a dummy password. I started with using the ssh args which did not work.

---

<div class="post-metadata">

**Author:** ![jborean](https://sea1.discourse-cdn.com/ansible/user_avatar/forum.ansible.com/jborean/32/1525_2.png) [@jborean](https://forum.ansible.com/u/jborean)\
**Post date:** [August 21, 2023, 12:01am UTC](https://forum.ansible.com/t/privilege-escalation-by-rsa-key/38344/8 "2023-08-21T00:01:40Z")

</div>

What I’m trying to say is that sudo is still writing the password is required message which then causes Ansible to say the password is required. If sudo doesn’t write this line then Ansible won’t say it needs a password ansible\_become\_pass.

Going backwards from the error we can see “Missing sudo password” is raised in the ssh connection plugin [https://github.com/ansible/ansible/blob/390e508d27db7a51eece36bb6d9698b63a5b638a/lib/ansible/plugins/connection/ssh.py#L1146-L1150](https://github.com/ansible/ansible/blob/390e508d27db7a51eece36bb6d9698b63a5b638a/lib/ansible/plugins/connection/ssh.py#L1146-L1150) when the ‘become\_nopasswd\_error’ flag has been set.

The ‘become\_nopasswd\_error’ flag is set when the output line being processed is validated as missing through the become plugin’s check\_missing\_password function [https://github.com/ansible/ansible/blob/390e508d27db7a51eece36bb6d9698b63a5b638a/lib/ansible/plugins/connection/ssh.py#L908-L910\*\*.](https://github.com/ansible/ansible/blob/390e508d27db7a51eece36bb6d9698b63a5b638a/lib/ansible/plugins/connection/ssh.py#L908-L910**.)\*\*

The become plugins check\_missing\_password function checks whether the processed line contains one of the known “missing password” responses [https://github.com/ansible/ansible/blob/390e508d27db7a51eece36bb6d9698b63a5b638a/lib/ansible/plugins/become/\_\_init\_\_.py#L104-L108](https://github.com/ansible/ansible/blob/390e508d27db7a51eece36bb6d9698b63a5b638a/lib/ansible/plugins/become/ __init__.py#L104-L108).

These known “missing password” lines are “Sorry, a password is required to run sudo” or “sudo: a pasword is required” [https://github.com/ansible/ansible/blob/390e508d27db7a51eece36bb6d9698b63a5b638a/lib/ansible/plugins/become/sudo.py#L90](https://github.com/ansible/ansible/blob/390e508d27db7a51eece36bb6d9698b63a5b638a/lib/ansible/plugins/become/sudo.py#L90).

So ultimately the reason why you are seeing this error is because sudo is writing one of those 2 responses to the stdout/stderr of the ssh process and the become plugin is flagging that as the password needs to be set. What should be investigated is why the sudo invocations done without the password is causing sudo to display this error vs why it accepts a dummy password. Also knowing why it’s working for an interactive command outside of Ansible vs the non-interactive command being run by Ansible when there is no password.

If you run with ‘-vvv’ you can see the exact commands Ansible is running for each task which will show both the ssh arguments as well as the sudo arguments being run on the ssh target. When you run with a set sudo password the ‘-p “[sudo via ansible, key=random] password:”’ argument is going to be added to the sudo prompt but I cannot see any other changes. Playing around with these commands can give you a way to try and replicate how Ansible runs things outside of Ansible itself giving you more things to try yourself.

---

<div class="post-metadata">

**Author:** ![system](https://us1.discourse-cdn.com/ansible/original/1X/1882d9a01da5d8996a862359b0913cc568a39b84.svg) [@system](https://forum.ansible.com/u/system)\
**Post date:** [August 21, 2023, 3:19pm UTC](https://forum.ansible.com/t/privilege-escalation-by-rsa-key/38344/9 "2023-08-21T15:19:38Z")

</div>

The Ansible engine does not really handle this directly, this is  
mostly up to the sudo become plugin.

While the connection plugins are the ones listening to output, they  
have hooks for the become plugins to match, in this case the output  
from sudo (prompting for a password) is matched by the sudo become  
plugin. Which when prompted, if it has a password, it passes it as  
input, if not .. then raises an error that requires a password.

The default options we pass to sudo are -H -S -n (only the last 2  
matter for this issue), while -S handles where sudo sends  
output/expects input (stdin) the -n tells it not to prompt .. EXCEPT  
if sudo itself determines the command needs a password. How does sudo  
determine this? by using `NOPASSWORD` on the command, it then prompts  
the user and sends the info to PAM for it to authenticate .. but PAM  
in this case does not require the password, as it finds the ssh key to  
be sufficient (but sudo has no idea about this) and that is how we get  
to the current behavior.

So if you have this setup you have a few workarounds:  
&nbsp;&nbsp;- Configure sudo to not attemp using passwords (passwd\_tries = 0),  
this might be an issue if this user tries to do any manual escalation  
w/o sshing in.  
&nbsp;&nbsp;- The already mentioned junk become password  
&nbsp;&nbsp;- Modify/create a custom sudo become plugin to take a new option  
(ignore\_password\_prompt=false|true) to avoid raising the error.
