StackStorm-Exchange / stackstorm-ansible

st2 content pack containing ansible integrations
https://exchange.stackstorm.org/
Apache License 2.0
36 stars 28 forks source link

`become` privilege escalation issues #16

Open LindsayHill opened 7 years ago

LindsayHill commented 7 years ago

(Copied from https://github.com/StackStorm/st2contrib/issues/330)

Running Ansible via StackStorm pack with privilege escalation options like become doesn't work (?).

When running Ansible pack with command equivalent:

Executed command "/opt/stackstorm/virtualenvs/ansible/bin/ansible-playbook --become-user=ubuntu --inventory-file=/home/ubuntu/configurations/ansible/hosts --become --become-method=su /home/ubuntu/configurations/ansible/staging.yml"

Ansible can't read ~/.ssh/config of ubuntu user.

Reported by @vikrantpogula:

Ansible playbook is not able to resolve the hostnames because my playbook uses hostnames from the ~/.ssh/config Basically instead of saying in my playbook i just use a Hostname which is then pointed to the actual servers ip address (using the config file)

cognifloyd commented 7 years ago

I don't think this is an issue with become.

Ansible doesn't use ~/.ssh/config, so I don't think it should work as described here. Could @vikrantpogula test running the playbook with the custom inventory setup (something that uses ~/.ssh/config?) outside stackstorm. If that works, then the config settings would need to be added to the root user's ~/.ssh/config file, because the ansible pack runs ansible as root currently.

paulquack commented 7 years ago

@cognifloyd I'm having issues along these lines as well which I'm trying to track down. Ansible is having all sorts of issues due to $HOME not being set. I'm not sure why privilege escalation is different when executing via st2, but here we are.

Here are some scenarios I've tested. Let me know if I can run any further tests to narrow down where the issue is...

root@d1893ee1c644:/home/stanley# su stanley -c "/opt/stackstorm/virtualenvs/ansible/bin/ansible localhost -a env -s" | grep HOME
 [WARNING]: provided hosts list is empty, only localhost is available
HOME=/root
root@d1893ee1c644:/home/stanley# su stanley -c "/opt/stackstorm/virtualenvs/ansible/bin/ansible localhost -a env" | grep HOME
 [WARNING]: provided hosts list is empty, only localhost is available
HOME=/home/stanley
root@d1893ee1c644:/home/stanley# /opt/stackstorm/virtualenvs/ansible/bin/ansible localhost -a env | grep HOME
 [WARNING]: provided hosts list is empty, only localhost is available
HOME=/root
root@d1893ee1c644:/home/stanley# /opt/stackstorm/virtualenvs/ansible/bin/ansible localhost -a env -s | grep HOME
 [WARNING]: provided hosts list is empty, only localhost is available
HOME=/root
root@d1893ee1c644:/home/stanley# st2 run ansible.command hosts=localhost args=env become=false sudo=false | grep HOME
    HOME=/home/stanley
root@d1893ee1c644:/home/stanley# st2 run ansible.command hosts=localhost args=env become=false sudo=true | grep HOME
root@d1893ee1c644:/home/stanley# st2 run ansible.command hosts=localhost args=env become=false | grep HOME
paulquack commented 7 years ago

Found that adding "Defaults always_set_home" in sudoers config seems to have had the desired effect. I'm at a loss to how this condition is triggered.

MorningLightMountain713 commented 5 years ago

Hi there, this is definetely still an issue.

Ansible can and does use ~/.ssh/config as per ansible docs

see netconf_ssh_config parameter.

I use ssh keys with a bastion host. I can get the stackstorm ansible pack to run only with the following:

stanley@stackstormtest-1 ansible]$ /opt/stackstorm/virtualenvs/ansible/bin/ansible-playbook -vvvv /home/stanley/ansible/scp_file.yml -i /home/stanley/ansible/hosts

So being able to run stackstorm as a user instead of root would be great. I've tried putting the ssh config under root but then start getting ssh protocol banner errors.

Here is the config I'm using:

{ "verbose": "vvvv", "inventory_file": "/home/stanley/ansible/hosts", "playbook": "/home/stanley/ansible/scp_file.yml", "user": "stanley", "become_user": "stanley", "become_method": "su" }

Here you can see that become_user is being passed to the playbook whereas it should run the playbook as the specified user - not root.

{
  "succeeded": false,
  "failed": true,
  "return_code": 2,
  "stderr": "Executed command \"/opt/stackstorm/virtualenvs/ansible/bin/ansible-playbook --become-method=su --become-user=stanley --become --inventory-file=/home/stanley/ansible/hosts -vvvv /home/stanley/ansible/scp_file.yml\"",
  "stdout": "ansible-playbook 2.8.3
  config file = None
  configured module search path = [u'/root/.ansible/plugins/modules', u'/usr/share/ansible/plugins/modules']
  ansible python module location = /opt/stackstorm/virtualenvs/ansible/lib/python2.7/site-packages/ansible
  executable location = /opt/stackstorm/virtualenvs/ansible/bin/ansible-playbook
  python version = 2.7.5 (default, Jun 20 2019, 20:27:34) [GCC 4.8.5 20150623 (Red Hat 4.8.5-36)]
No config file found; using defaults
setting up inventory plugins
host_list declined parsing /home/stanley/ansible/hosts as it did not pass it's verify_file() method
script declined parsing /home/stanley/ansible/hosts as it did not pass it's verify_file() method
auto declined parsing /home/stanley/ansible/hosts as it did not pass it's verify_file() method
Parsed /home/stanley/ansible/hosts inventory source with ini plugin
Loading callback plugin default of type stdout, v2.0 from /opt/stackstorm/virtualenvs/ansible/lib/python2.7/site-packages/ansible/plugins/callback/default.pyc

PLAYBOOK: scp_file.yml *********************************************************
Positional arguments: /home/stanley/ansible/scp_file.yml
become_user: stanley
become_method: su
inventory: (u'/home/stanley/ansible/hosts',)
forks: 5
tags: (u'all',)
verbosity: 4
connection: smart
timeout: 10
become: True
1 plays in /home/stanley/ansible/scp_file.yml

PLAY [SCP file to Juniper device] **********************************************
META: ran handlers

TASK [upload local file to home directory on remote device] ********************
task path: /home/stanley/ansible/scp_file.yml:9
<test-router-1> attempting to start connection
<test-router-1> using connection plugin netconf
<test-router-1> local domain socket does not exist, starting it
<test-router-1> control socket path is /root/.ansible/pc/ba23247efa
<test-router-1> ESTABLISH NETCONF SSH CONNECTION FOR USER: stanley on PORT 22 TO test-router-1
<test-router-1> 
The full traceback is:
Traceback (most recent call last):
  File \"/opt/stackstorm/virtualenvs/ansible/bin/ansible-connection\", line 104, in start
    self.connection._connect()
  File \"/opt/stackstorm/virtualenvs/ansible/lib/python2.7/site-packages/ansible/plugins/connection/netconf.py\", line 322, in _connect
    ssh_config=ssh_config
  File \"/opt/stackstorm/virtualenvs/ansible/lib/python2.7/site-packages/ncclient/manager.py\", line 177, in connect
    return connect_ssh(*args, **kwds)
  File \"/opt/stackstorm/virtualenvs/ansible/lib/python2.7/site-packages/ncclient/manager.py\", line 143, in connect_ssh
    session.connect(*args, **kwds)
  File \"/opt/stackstorm/virtualenvs/ansible/lib/python2.7/site-packages/ncclient/transport/ssh.py\", line 355, in connect
    with open(os.path.expanduser(ssh_config)) as ssh_config_file_obj:
IOError: [Errno 2] No such file or directory: '/root/.ssh/config'
fatal: [test-router-1]: FAILED! => {
    \"msg\": \"[Errno 2] No such file or directory: '/root/.ssh/config'\"
}

PLAY RECAP *********************************************************************
test-router-1                   : ok=0    changed=0    unreachable=0    failed=1    skipped=0    rescued=0    ignored=0   
"
}
MorningLightMountain713 commented 5 years ago

Okay, so yup, I didn't have the config file correct. Got this working by putting ssh config under /root/.ssh/config. Not ideal running as root. I had to modify the proxy command to pass the user.

The "become user" setting is not necessary.

Host !bastion *
  User stanley
  IdentityFile /home/stanley/.ssh/stanley_rsa
  ProxyCommand ssh -W %h:%p %r@bastion -i /home/stanley/.ssh/stanley_rsa

Host bastion
  HostName 192.168.1.1
  ForwardAgent yes
  ControlPath /tmp/sshcontrol-%h-%p-%r
  ControlMaster auto