Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

6.2.6 ignores nonexistent directory in root's PATH #68

Open
arronax opened this issue Sep 1, 2019 · 6 comments
Open

6.2.6 ignores nonexistent directory in root's PATH #68

arronax opened this issue Sep 1, 2019 · 6 comments
Assignees
Labels
bug InProgress Issues that are actively being worked on

Comments

@arronax
Copy link
Contributor

arronax commented Sep 1, 2019

Root's PATH in Amazon Linux (and CentOS, and likely other similar distributions) by default has /root/bin in it, which doesn't exist:

[root@ip-192-168-3-209 ~]# env | grep PATH
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin
[root@ip-192-168-3-209 ~]# ls -ld /root/bin
ls: cannot access /root/bin: No such file or directory

That should trigger an action in item 6.2.6, but it skips over. Looks like ansible's script module doesn't set environment as it's expected in the role.

PLAY [ip-192-168-3-209] ***************************************************************************

TASK [6.2.6 - Audit root PATH Integrity] **********************************************************
ok: [ip-192-168-3-209]

TASK [6.2.6 - Ensure root PATH Integrity] *********************************************************
skipping: [ip-192-168-3-209]

TASK [6.2.6 - Ensure root PATH Integrity] *********************************************************
skipping: [ip-192-168-3-209]

PLAY RECAP ****************************************************************************************
ip-192-168-3-209           : ok=1    changed=0    unreachable=0    failed=0    skipped=2    rescued=0    ignored=0

Running audit_6.2.6.sh directly on the hosts provides expected results.

[root@ip-192-168-3-209 ~]# /tmp/audit_6.2.6.sh
/root/bin is not a directory
@chandanchowdhury
Copy link
Collaborator

chandanchowdhury commented Sep 2, 2019

Hi Sergey (@arronax),
thanks a lot for creating the issue and submitting the pull request.

This is a tricky situation.

Quick question, have you thought about trying to run the script as sudo and see if that works?

@arronax
Copy link
Contributor Author

arronax commented Sep 3, 2019

I think, the reason for all of this is the different invocation of bash. I'll check this, but it appears that ansible's script gets interactive non-login shell, while we need login shell in order to get full env present.

Quoting man bash

When bash is invoked as an interactive login shell, or as a non-interactive shell with the --login option, it first reads and executes commands from the file /etc/profile, if that file exists. After reading that file, it looks for ~/.bash_profile, ~/.bash_login, and ~/.profile, in that order, and reads and executes commands from the first one that exists and is readable. The --noprofile option may be used when the shell is started to inhibit this behavior.

Behavior can be shown using ssh or sudo.

$ sudo /tmp/audit_6.2.6.sh
$ sudo bash /tmp/audit_6.2.6.sh
$ sudo bash -l /tmp/audit_6.2.6.sh
/root/bin is not a directory
$ ssh -q ip-192-168-3-209 "/tmp/audit_6.2.6.sh"
$ ssh -q ip-192-168-3-209 "bash /tmp/audit_6.2.6.sh"
$ ssh -q ip-192-168-3-209 "bash -l /tmp/audit_6.2.6.sh"
/home/ec2-user/.local/bin is not a directory
/home/ec2-user/bin is not a directory

Better yet, it can be shown directly through PATH (script has single env | grep PATH line)

$ sudo /tmp/env-path.sh
PATH=/sbin:/bin:/usr/sbin:/usr/bin
$ sudo bash /tmp/env-path.sh
PATH=/sbin:/bin:/usr/sbin:/usr/bin
$ sudo bash -l /tmp/env-path.sh
PATH=/usr/local/sbin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin

@arronax
Copy link
Contributor Author

arronax commented Sep 3, 2019

Some trivial testing through ansible.

$ cat env.sh
#!/bin/bash
env | grep PATH
  tasks:
    - name: Copy test script to the remote machine
      copy:
        src: env.sh
        dest: /tmp/env.sh
        mode: 0700

    - name: Get environment using `script`
      script: env.sh
      register: script_out

    - name: debug print output
      debug:
        msg: "{{ script_out.stdout }}"

    - name: Get environment using `script` and do become
      script: env.sh
      become: yes
      register: script_become_out

    - name: debug print output
      debug:
        msg: "{{ script_become_out.stdout }}"

    - name: Get environment using `command`
      command: /tmp/env.sh
      register: command_out

    - name: debug print output
      debug:
        msg: "{{ command_out.stdout }}"

    - name: Get environment using `command` and do become
      command: /tmp/env.sh
      become: yes
      register: command_become_out

    - name: debug print output
      debug:
        msg: "{{ command_become_out.stdout }}"

    - name: Get environment using `shell`
      shell: /tmp/env.sh
      register: shell_out

    - name: debug print output
      debug:
        msg: "{{ shell_out.stdout }}"

    - name: Get environment using `shell` and do become
      shell: /tmp/env.sh
      become: yes
      register: shell_become_out

    - name: debug print output
      debug:
        msg: "{{ shell_become_out.stdout }}"

    - name: Get environment using `command` with bash invocation
      command: bash /tmp/env.sh
      register: command_bash_out

    - name: debug print output
      debug:
        msg: "{{ command_bash_out.stdout }}"

    - name: Get environment using `command` with bash invocation and do become
      command: /tmp/env.sh
      become: yes
      register: command_become_bash_out

    - name: debug print output
      debug:
        msg: "{{ command_become_bash_out.stdout }}"

    - name: Get environment using `command` with bash login invocation
      command: bash -l /tmp/env.sh
      register: command_bash_login_out

    - name: debug print output
      debug:
        msg: "{{ command_bash_login_out.stdout }}"

    - name: Get environment using `command` with bash login invocation and do become
      command: bash -l /tmp/env.sh
      become: yes
      register: command_become_bash_login_out

    - name: debug print output
      debug:
        msg: "{{ command_become_bash_login_out.stdout }}"
PLAY [ip-192-168-3-209] ******************************************************************************************

TASK [Copy test script to the remote machine] ********************************************************************
ok: [ip-192-168-3-209]

TASK [Get environment using `script`] ****************************************************************************
changed: [ip-192-168-3-209]

TASK [debug print output] ****************************************************************************************
ok: [ip-192-168-3-209] => {
    "msg": "PATH=/usr/local/bin:/usr/bin\r\n"
}

TASK [Get environment using `script` and do become] **************************************************************
changed: [ip-192-168-3-209]

TASK [debug print output] ****************************************************************************************
ok: [ip-192-168-3-209] => {
    "msg": "PATH=/sbin:/bin:/usr/sbin:/usr/bin\r\n"
}

TASK [Get environment using `command`] ***************************************************************************
changed: [ip-192-168-3-209]

TASK [debug print output] ****************************************************************************************
ok: [ip-192-168-3-209] => {
    "msg": "PATH=/usr/local/bin:/usr/bin"
}

TASK [Get environment using `command` and do become] *************************************************************
changed: [ip-192-168-3-209]

TASK [debug print output] ****************************************************************************************
ok: [ip-192-168-3-209] => {
    "msg": "PATH=/sbin:/bin:/usr/sbin:/usr/bin"
}

TASK [Get environment using `shell`] *****************************************************************************
changed: [ip-192-168-3-209]

TASK [debug print output] ****************************************************************************************
ok: [ip-192-168-3-209] => {
    "msg": "PATH=/usr/local/bin:/usr/bin"
}

TASK [Get environment using `shell` and do become] ***************************************************************
changed: [ip-192-168-3-209]

TASK [debug print output] ****************************************************************************************
ok: [ip-192-168-3-209] => {
    "msg": "PATH=/sbin:/bin:/usr/sbin:/usr/bin"
}

TASK [Get environment using `command` with bash invocation] ******************************************************
changed: [ip-192-168-3-209]

TASK [debug print output] ****************************************************************************************
ok: [ip-192-168-3-209] => {
    "msg": "PATH=/usr/local/bin:/usr/bin"
}

TASK [Get environment using `command` with bash invocation and do become] ****************************************
changed: [ip-192-168-3-209]

TASK [debug print output] ****************************************************************************************
ok: [ip-192-168-3-209] => {
    "msg": "PATH=/sbin:/bin:/usr/sbin:/usr/bin"
}

TASK [Get environment using `command` with bash login invocation] ************************************************
changed: [ip-192-168-3-209]

TASK [debug print output] ****************************************************************************************
ok: [ip-192-168-3-209] => {
    "msg": "PATH=/usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/home/ec2-user/.local/bin:/home/ec2-user/bin"
}

TASK [Get environment using `command` with bash login invocation and do become] **********************************
changed: [ip-192-168-3-209]

TASK [debug print output] ****************************************************************************************
ok: [ip-192-168-3-209] => {
    "msg": "PATH=/usr/local/sbin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin"
}

PLAY RECAP *******************************************************************************************************
ip-192-168-3-209           : ok=21   changed=10   unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

@arronax
Copy link
Contributor Author

arronax commented Sep 3, 2019

I do not think that ansible will support login shells any time soon, and I am personally not sure that's required, as there are workarounds available. Environment variables and scripts are sometimes tricky, and can break whatever ansible is running.

Some ansible team answers to the related issues.

ansible/ansible#4854 (comment)
ansible/ansible#29637 (comment)

@chandanchowdhury
Copy link
Collaborator

Thanks again @arronax for doing all the research and hardwork.

One tiny request. Could you please send the pull request to build instead of master.
We are trying to follow this approach so to allow others to test run build and report any bugs they find before we merge the changes in master which will become prodcuction version.

@chandanchowdhury
Copy link
Collaborator

@arronax Please ignore the request, was able to modify the PR to pull into build

@chandanchowdhury chandanchowdhury added bug implement for changes that will be implemented InProgress Issues that are actively being worked on and removed implement for changes that will be implemented labels Sep 4, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug InProgress Issues that are actively being worked on
Projects
None yet
Development

No branches or pull requests

2 participants