{"id":2755,"date":"2024-07-26T14:19:25","date_gmt":"2024-07-26T14:19:25","guid":{"rendered":"https:\/\/blog.samarthya.me\/wps\/?p=2755"},"modified":"2024-07-26T18:55:21","modified_gmt":"2024-07-26T18:55:21","slug":"ansible-privilege-escalation","status":"publish","type":"post","link":"https:\/\/blog.samarthya.me\/wps\/2024\/07\/26\/ansible-privilege-escalation\/","title":{"rendered":"Privilege Escalation: How a `remote_user` and a `become_user` works"},"content":{"rendered":"\n<figure class=\"wp-block-image size-large is-style-rounded\"><img fetchpriority=\"high\" decoding=\"async\" width=\"1024\" height=\"1024\" src=\"https:\/\/blog.samarthya.me\/wps\/wp-content\/uploads\/2024\/07\/image-ansible-1024x1024.jpeg\" alt=\"\" class=\"wp-image-2757\" srcset=\"https:\/\/blog.samarthya.me\/wps\/wp-content\/uploads\/2024\/07\/image-ansible-1024x1024.jpeg 1024w, https:\/\/blog.samarthya.me\/wps\/wp-content\/uploads\/2024\/07\/image-ansible-150x150@2x.jpeg 300w, https:\/\/blog.samarthya.me\/wps\/wp-content\/uploads\/2024\/07\/image-ansible-150x150.jpeg 150w, https:\/\/blog.samarthya.me\/wps\/wp-content\/uploads\/2024\/07\/image-ansible.jpeg 1536w, https:\/\/blog.samarthya.me\/wps\/wp-content\/uploads\/2024\/07\/image-ansible-300x300@2x.jpeg 600w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>One of its Ansible&#8217;s features is the ability to execute tasks with elevated privileges, often necessary for managing system configurations. This process is known as privilege escalation. <\/p>\n\n\n\n<p>Let&#8217;s dive into the details of how privilege escalation works in <code>Ansible<\/code>, how to configure it using different variables, and the best practices for secure and effective use.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Understanding Privilege Escalation <\/h2>\n\n\n\n<p>Privilege escalation in <code>Ansible<\/code> refers to the ability to run tasks with higher permissions than the user who initially connects to the remote system. This is crucial for operations that require root or administrator access, such as installing packages, modifying system configurations, or managing services.<\/p>\n\n\n\n<figure class=\"wp-block-pullquote has-black-color has-pale-cyan-blue-background-color has-text-color has-background has-link-color has-small-font-size wp-elements-f51d74ec5f7839ddc735556e7dd76cd2\" style=\"border-width:4px;border-radius:23px\"><blockquote><p>To see all configuration possibilities you can use the following command<br><code>ansible-config init --disabled -t all > ansible.cfg<\/code><\/p><cite>Ansible documentation<\/cite><\/blockquote><\/figure>\n\n\n\n<h3 class=\"wp-block-heading\">Users in <code>Ansible<\/code> Context<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><code>user<\/code>: This is the user account on the control machine running Ansible.<\/li>\n\n\n\n<li><code>remote_user<\/code>: This is the user account on the managed nodes that Ansible connects to via SSH.<\/li>\n\n\n\n<li><code>become_user<\/code>: This is the user account on the managed nodes to which Ansible escalates privileges.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Key Variables for Privilege Escalation<\/h3>\n\n\n\n<p>Ansible uses several variables to control privilege escalation. Let&#8217;s explore each one:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><code>become<\/code>: This boolean variable enables or disables privilege escalation.<\/li>\n\n\n\n<li><code>become_method<\/code>: Specifies the privilege escalation method (e.g., sudo, su, pbrun).<\/li>\n\n\n\n<li><code>become_user<\/code>: Defines the user to become for privilege escalation.<\/li>\n\n\n\n<li><code>become_ask_pass<\/code>: Determines whether <code>Ansible<\/code> should prompt for a password.<\/li>\n\n\n\n<li><code>become_pass<\/code>: This defines the password for privilege escalation.<\/li>\n\n\n\n<li><code>become_pass_file<\/code>: This specifies a file containing the password for privilege escalation.<\/li>\n\n\n\n<li><code>become_flags<\/code>: This sets the flags to pass to the privilege escalation command.<\/li>\n<\/ol>\n\n\n\n<p>Let&#8217;s look at how to configure each of these variables with examples.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">1. become<\/h4>\n\n\n\n<p>The <code>become<\/code> variable is the master switch for privilege escalation. When set to <code>true<\/code>, Ansible will attempt to escalate privileges for the specified tasks.<\/p>\n\n\n\n<h5 class=\"wp-block-heading\">Example:<\/h5>\n\n\n\n<pre class=\"wp-block-code has-black-color has-light-green-cyan-background-color has-text-color has-background has-link-color wp-elements-9420bdf2f5c3c5de6abf7a0377a108b6\"><code>- name: Install nginx\n  apt:\n    name: nginx\n    state: present\n  become: true<\/code><\/pre>\n\n\n\n<h4 class=\"wp-block-heading\">2. become_method<\/h4>\n\n\n\n<p>The <code>become_method<\/code> variable specifies how Ansible should escalate privileges. Common values include:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>sudo<\/li>\n\n\n\n<li>su<\/li>\n\n\n\n<li>pbrun<\/li>\n\n\n\n<li>pfexec<\/li>\n\n\n\n<li>doas<\/li>\n\n\n\n<li>dzdo<\/li>\n\n\n\n<li>ksu<\/li>\n\n\n\n<li>runas<\/li>\n\n\n\n<li>pmrun<\/li>\n<\/ul>\n\n\n\n<h5 class=\"wp-block-heading\">Example:<\/h5>\n\n\n\n<pre class=\"wp-block-code has-black-color has-light-green-cyan-background-color has-text-color has-background has-link-color wp-elements-6c3260941abea029839834409af2587d\"><code>- name: Restart nginx service\n  service:\n    name: nginx\n    state: restarted\n  become: true\n  become_method: sudo<\/code><\/pre>\n\n\n\n<h4 class=\"wp-block-heading\">3. become_user<\/h4>\n\n\n\n<p>The <code>become_user<\/code> variable allows you to specify which user Ansible should become when escalating privileges. This is particularly useful when you need to perform actions as a specific system user.<\/p>\n\n\n\n<h5 class=\"wp-block-heading\">Example:<\/h5>\n\n\n\n<pre class=\"wp-block-code has-black-color has-light-green-cyan-background-color has-text-color has-background has-link-color wp-elements-ee1f31062d8c76236d56f65fe35b394c\"><code>- name: Create a directory as www-data\n  file:\n    path: \/var\/www\/new_site\n    state: directory\n  become: true\n  become_user: www-data<\/code><\/pre>\n\n\n\n<h4 class=\"wp-block-heading\">4. become_ask_pass<\/h4>\n\n\n\n<p>When set to <code>true<\/code>, <code>become_ask_pass<\/code> prompts for a password for privilege escalation. This is useful when you can&#8217;t store the sudo password in plain text or when you need to enter it interactively.<\/p>\n\n\n\n<h5 class=\"wp-block-heading\">Example:<\/h5>\n\n\n\n<pre class=\"wp-block-code has-black-color has-light-green-cyan-background-color has-text-color has-background has-link-color wp-elements-ed4817d4c484fa571d773ba906a11b5e\"><code>&#91;privilege_escalation]\n# (boolean) Toggle to prompt for privilege escalation password.\nbecome_ask_pass=True<\/code><\/pre>\n\n\n\n<p>Once it is set and when you execute a playbook you should expect a prompt<\/p>\n\n\n\n<pre class=\"wp-block-code has-black-color has-light-green-cyan-background-color has-text-color has-background has-link-color wp-elements-898c8d9b85b49a0f716db15f6077f66a\"><code>> ansible-playbook play-one.yml \nBECOME password: <\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Combining Variables: Password and Password File Examples<\/h3>\n\n\n\n<p>Let&#8217;s look at two common scenarios for handling passwords:<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">1. Interactive Password Prompt for the login user (SSH User, remote_user)<\/h4>\n\n\n\n<p>Let&#8217;s configure <code>ansible.cfg<\/code> with the required properties<\/p>\n\n\n\n<pre class=\"wp-block-code has-black-color has-light-green-cyan-background-color has-text-color has-background has-link-color wp-elements-a091a9543c4281c605d328e8ea39c144\"><code># (boolean) This controls whether an Ansible playbook should prompt for a login password. If using SSH keys for authentication, you probably do not need to change this setting.\nask_pass=True\n\n# (string) Sets the login user for the target machines\n# When blank it uses the connection plugin's default, normally the user currently executing Ansible.\nremote_user=ruser<\/code><\/pre>\n\n\n\n<pre class=\"wp-block-code has-black-color has-light-green-cyan-background-color has-text-color has-background has-link-color wp-elements-6c76f77844be571c3c02af76e78b1f6c\"><code>- hosts: all\n  tasks:\n    - name: Run a command as root\n      command: whoami\n      register: who\n    - debug:\n        var: who.stdout<\/code><\/pre>\n\n\n\n<p>Now when you run the playbook you should expect a password prompt<\/p>\n\n\n\n<pre class=\"wp-block-code has-black-color has-luminous-vivid-amber-background-color has-text-color has-background has-link-color wp-elements-2be511b5c7fdd1c916975c25f65ad782\"><code>> ansible-playbook play-two.yml\nSSH password: \n\nPLAY &#91;all] ***************************************************************************************************************************************************************************************************************************************************************************************************************************************************************\n\nTASK &#91;Gathering Facts] ***************************************************************************************************************************************************************************************************************************************************************************************************************************************************\nok: &#91;localhost]\n\nTASK &#91;Run a command as root] *********************************************************************************************************************************************************************************************************************************************************************************************************************************************\nchanged: &#91;localhost]\n\nTASK &#91;debug] *************************************************************************************************************************************************************************************************************************************************************************************************************************************************************\nok: &#91;localhost] => {\n    \"who.stdout\": \"ruser\"\n}\n\nPLAY RECAP ***************************************************************************************************************************************************************************************************************************************************************************************************************************************************************\nlocalhost                  : ok=3    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   \n<\/code><\/pre>\n\n\n\n<p>You can configure the password file as well<\/p>\n\n\n\n<pre class=\"wp-block-code has-black-color has-light-green-cyan-background-color has-text-color has-background has-link-color wp-elements-1982e8903625999a86edffae02406802\"><code># (boolean) This controls whether an Ansible playbook should prompt for a login password. If using SSH keys for authentication, you probably do not need to change this setting.\nask_pass=False\n\n# (path) The password file to use for the connection plugin. --connection-password-file.\nconnection_password_file=.\/connection.yml<\/code><\/pre>\n\n\n\n<p>I added the password information in the local directory and now if you run you should be prompted for password<\/p>\n\n\n\n<pre class=\"wp-block-code has-black-color has-light-green-cyan-background-color has-text-color has-background has-link-color wp-elements-3cfe11d4b0df58b22e9081a407219900\"><code>> ansible-playbook play-two.yml\n\nPLAY &#91;all] ***************************************************************************************************************************************************************************************************************************************************************************************************************************************************************\n\nTASK &#91;Gathering Facts] ***************************************************************************************************************************************************************************************************************************************************************************************************************************************************\nok: &#91;localhost]\n\nTASK &#91;Run a command as root] *********************************************************************************************************************************************************************************************************************************************************************************************************************************************\nchanged: &#91;localhost]\n\nTASK &#91;debug] *************************************************************************************************************************************************************************************************************************************************************************************************************************************************************\nok: &#91;localhost] => {\n    \"who.stdout\": \"ruser\"\n}\n\nPLAY RECAP ***************************************************************************************************************************************************************************************************************************************************************************************************************************************************************\nlocalhost                  : ok=3    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   <\/code><\/pre>\n\n\n\n<p>Combining with become user now.<\/p>\n\n\n\n<pre class=\"wp-block-code has-black-color has-luminous-vivid-amber-background-color has-text-color has-background has-link-color wp-elements-d613064f23988537628536fb8678bc76\"><code>- hosts: all\n  become: true\n  become_method: sudo\n  tasks:\n    - name: Run a command as root\n      command: whoami\n      register: who\n    - debug:\n        var: who.stdout<\/code><\/pre>\n\n\n\n<p>Now when I run with the configuration already defined in sections above.<\/p>\n\n\n\n<pre class=\"wp-block-code has-black-color has-light-green-cyan-background-color has-text-color has-background has-link-color wp-elements-2d3adf6fa4bbeeff19d366d0c3729847\"><code>TASK &#91;debug] *************************************************************************************************************************************************************************************************************************************************************************************************************************************************************\nok: &#91;localhost] => {\n    \"who.stdout\": \"root\"\n}<\/code><\/pre>\n\n\n\n<p>Who is the ssh login user can be defined in two ways<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><code>remote_user<\/code>: Property in the ansible.cfg<\/li>\n\n\n\n<li><code>ansible_user<\/code>: Property in the inventory for each host.<\/li>\n<\/ul>\n","protected":false},"excerpt":{"rendered":"<p>One of its Ansible&#8217;s features is the ability to execute tasks with elevated privileges, often necessary for managing system configurations. This process is known as privilege escalation. Let&#8217;s dive into the details of how privilege escalation works in Ansible, how to configure it using different variables, and the best practices for secure and effective use. [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":2760,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_exactmetrics_skip_tracking":false,"_exactmetrics_sitenote_active":false,"_exactmetrics_sitenote_note":"","_exactmetrics_sitenote_category":0,"footnotes":""},"categories":[299,34],"tags":[],"class_list":["post-2755","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-ansible","category-technical"],"_links":{"self":[{"href":"https:\/\/blog.samarthya.me\/wps\/wp-json\/wp\/v2\/posts\/2755","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blog.samarthya.me\/wps\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.samarthya.me\/wps\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.samarthya.me\/wps\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.samarthya.me\/wps\/wp-json\/wp\/v2\/comments?post=2755"}],"version-history":[{"count":12,"href":"https:\/\/blog.samarthya.me\/wps\/wp-json\/wp\/v2\/posts\/2755\/revisions"}],"predecessor-version":[{"id":2778,"href":"https:\/\/blog.samarthya.me\/wps\/wp-json\/wp\/v2\/posts\/2755\/revisions\/2778"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/blog.samarthya.me\/wps\/wp-json\/wp\/v2\/media\/2760"}],"wp:attachment":[{"href":"https:\/\/blog.samarthya.me\/wps\/wp-json\/wp\/v2\/media?parent=2755"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.samarthya.me\/wps\/wp-json\/wp\/v2\/categories?post=2755"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.samarthya.me\/wps\/wp-json\/wp\/v2\/tags?post=2755"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}