Saturday 29 June 2019

Running salt-ssh as a non-root user



Introduction

Security is of the essence in every enterprise infrastructure but so is automation. One of the requirements to maintain a healthy balance among the two is to not use root directly while working with automation tools. In this article I'll be setting up salt-ssh, the agentless version of salt and work with it as a non-root user.

This is by no means a comprehensive write up on how Salt or Salt-ssh works and is rather more of a let's get started.

First let's install the tool using yum.

[root@sahil-lab ~]# yum install salt salt-ssh -y
Loaded plugins: fastestmirror
Loading mirror speeds from cached hostfile
 * base: mirror.aktkn.sg
 * epel: d2lzkl7pfhq30w.cloudfront.net
 * extras: mirror.aktkn.sg
 * nux-dextop: li.nux.ro
 * updates: mirror.aktkn.sg
Resolving Dependencies
--> Running transaction check
---> Package salt.noarch 0:2015.5.10-2.el7 will be installed
--> Processing Dependency: m2crypto for package: salt-2015.5.10-2.el7.noarch
--> Processing Dependency: python-crypto for package: salt-2015.5.10-2.el7.noarch
--> Processing Dependency: python-msgpack for package: salt-2015.5.10-2.el7.noarch
--> Processing Dependency: python-zmq for package: salt-2015.5.10-2.el7.noarch
--> Processing Dependency: systemd-python for package: salt-2015.5.10-2.el7.noarch
---> Package salt-ssh.noarch 0:2015.5.10-2.el7 will be installed
 ------------------------------output truncated for brevity


Now let's create the required directory structure.

[sahil@sahil-lab ~]$ mkdir salt_setup
[sahil@sahil-lab ~]$ cd salt_setup/
[sahil@sahil-lab salt_setup]$ mkdir -p {config,salt/{files,templates,states,pillar,formulas,pki/master,logs}}
[sahil@sahil-lab salt_setup]$ mkdir cache
[sahil@sahil-lab salt_setup]$ touch ssh.log


We would also need to copy the contents of /etc/salt directory to the salt_setup directory under the user's home directory.

[root@sahil-lab ~]# cp -rp /etc/salt/* /home/sahil/salt_setup/
[root@sahil-lab ~]# chown sahil:sahil -R /home/sahil/salt_setup/*


The master config file:
The master config file has the same declarations that you would define when using Salt in master mode. Create a master config file with the following contents that points Salt SSH to the location of the previously created directories.

[sahil@sahil-lab salt_setup]$ cat master
root_dir: "/home/sahil/salt_setup"
pki_dir: "pki"
cachedir: "cache"
log_file: "salt-ssh.log"
[sahil@sahil-lab salt_setup]$


The Saltfile:
The Saltfile allows you to set command line configuration option in a file instead of declaring them at runtime. Create a Saltfile with the following contents.

[sahil@sahil-lab salt_setup]$ cat Saltfile
salt-ssh:
  config_dir: "/home/sahil/salt_setup/"
  log_file: "/home/sahil/salt_setup/ssh.log"
  pki_dir: "/home/sahil/salt_setup/pki"
  cachedir: "/home/sahil/salt_setup/cache"
  roster_file: "/home/sahil/salt_setup/roster"
  ssh_wipe: True
[sahil@sahil-lab salt_setup]$


The roster file:
The roster file is used to define remote minions and their connection parameters. The default roster file has some commented out examples that you could use. I've set up a fairly simple one as shown below:

[sahil@sahilsuri0082c salt_setup]$ cat roster
# Sample salt-ssh config file
#web1:
#  host: 192.168.42.1 # The IP addr or DNS hostname
#  user: fred         # Remote executions will be executed as user fred
#  passwd: foobarbaz  # The password to use for login, if omitted, keys are used
#  sudo: True         # Whether to sudo to root, not enabled by default
#web2:
#  host: 192.168.42.2

my-salt-vm: 172.40.36.36

In the above example, my-salt-vm is the salt id of the host I wish to connect to followed by its IP address. I could've also used the server's hostname instead of the IP address.


Testing the setup


Let's use the cmd.run module to get the uptime of our host.

[sahil@sahil-lab salt_setup]$ salt-ssh  '*'  cmd.run 'uptime' --user sahil --priv /home/sahil/.ssh/id_dsa
my-salt-vm:
     05:19:32 up  2:17,  1 user,  load average: 0.15, 0.07, 0.10
[sahil@sahil-lab salt_setup]$


You might be wondering the reason for specifying the user name and key file path explicitly. If you don't salt-ssh defaults to the root user and the following happens:

sahil@sahil-lab salt_setup]$ salt-ssh  '*'  cmd.run 'uptime'
Permission denied for host my-salt-vm, do you want to deploy the salt-ssh key? (password required):
[Y/n] y
Password for root@my-salt-vm:
my-salt-vm:
    Permission denied (publickey,gssapi-keyex,gssapi-with-mic,password).
[sahil@sahil-lab salt_setup]$

The '*' implies run the command on all hosts defined in the roster.
If you do not wan to specify the user name and key file path every time you connect then you could also specify them in the roster file. 
Here is an example:

cat roster | grep -v '#'

lab-node1:
  host: 172.40.36.36
  user: sahil
  priv: /home/sahil/.ssh/id_dsa
  sudo: True

With this in place you could invoke salt-ssh as shown below:

[sahil@sahil-lab salt_setup]$ salt-ssh lab-node1 cmd.run 'uptime'
lab-node1:
     06:51:28 up  3:49,  2 users,  load average: 0.00, 0.01, 0.05
[sahil@sahil-lab salt_setup]$


Salt-ssh requires Python 2.7 or 3.x to be available on the target machines. But what if you are connecting to a system that has Python version 2.6 or what if it doesn't even Python installed?
In that case you could use -r option to execute a raw shell command.

[sahil@sahil-lab salt_setup]$ salt-ssh  '*'  -r 'uptime' --user sahil --priv /home/sahil/.ssh/id_dsa
my-salt-vm:
    ----------
    retcode:
        0
    stderr:
    stdout:
         06:47:10 up  3:45,  2 users,  load average: 0.00, 0.01, 0.05
[sahil@sahil-lab salt_setup]$


Note: For invoking all salt-ssh commands being executed as non-root user, you must be in the directory where the salt configuration, roster, Saltfile and master configuration file are located.


Last words..

Salt-ssh is a nice agentless extension to the Salt tool but having worked with Ansible I find the inventory file system in Ansible coupled with the ease of setup as a whole to be much more flexible. As a result, given the option to work with salt-ssh or Ansible, I would choose Ansible. If you've worked with both tools, I'd love to hear your experience.

No comments:

Post a Comment

Using capture groups in grep in Linux

Introduction Let me start by saying that this article isn't about capture groups in grep per se. What we are going to do here with gr...