Remote management with reverse SSH purely, is not very functional in terms of scalability. Therefore, it’s not good enough for production purposes. Understandably, we’re are just prototyping, but it doesn’t hurt to think long-term here. With Salt, we get both the basic remote management functionalities, like running basic shell commands for troubleshooting, but also the centralized management capabilities. Configuring our SSH-based remote management for multiple devices is not practical, whereas Salt was made exactly for that.
Salt is one of the main centralized management tools alongside Puppet, Chef and Ansible. If you’re interested in any of those, I’d suggest taking a look at a project by another group on the same course: https://github.com/joonaleppalahti/CCM. I personally found their material very useful when configuring Salt for our project. Jori Laine, a member of theirs, personally gave us some input after we had some initial problems with Salt’s installation: https://jorilaine.wordpress.com/.
The basic idea
Our Raspberry Pi -based sensor device is operating in a mobile network behind NAT. Thus, we can’t reach it directly from the internet. This is not a problem with Salt, which works with a Master-Minion principle.
Salt-Master gives commands to it’s minions but it does not need to know where they’re located at. It identifies them with their unique salt-keys, not their IP-addresses. Salt-Minions are the ones maintaining the connection between themselves and the master. This is why it does not matter whether they’re behind NAT or not, as long as the Salt-Master is accessible to them.
Installing the Salt-Master
For the master’s installation to work, we had to get a server with more memory since our original one with 1GB of RAM was not cutting it. In the end we ended up with 3GB of RAM, 1 CPU and a 20GB SSD Disk from DigitalOcean.
First step of the installation process was to download the Salt Bootstrap installation script. I downloaded it with Curl and installed a specific release version based on the Git tag.
curl -L https://bootstrap.saltstack.com -o install_salt.sh
sudo sh install_salt.sh -P -M git v2017.7.2
-M flag was used to install a Salt-Master. After the installation was successful, I changed the master’s config file in /etc/salt/master.
# Set and ID for your master:
# The address of the interface to bind to:
The address above is the server’s own. After the changes, I restarted the salt-master service. Also I had to make sure the server’s firewall is allowing incoming connections from ports 4505 and 4506:
Logging: on (low)
Default: deny (incoming), allow (outgoing), disabled (routed)
New profiles: skip
To Action From
-- ------ ----
22/tcp ALLOW IN Anywhere
4505 ALLOW IN Anywhere
4506 ALLOW IN Anywhere
22/tcp (v6) ALLOW IN Anywhere (v6)
4505 (v6) ALLOW IN Anywhere (v6)
Salt-Master was now configured to allow connections from the minions.
Installing the Salt-Minion
Salt Bootstrap installation script did not work for the Raspberry Pi. It was complaining about missing dependencies etc. This is why I installed Salt-Minion by importing the SaltStack repository key with wget:
wget -O - https://repo.saltstack.com/apt/debian/8/armhf/latest/SALTSTACK-GPG-KEY.pub | sudo apt-key add -
After that, I edited /etc/apt/sources.list.d/salt-stack.list and added the following line:
deb http://repo.saltstack.com/apt/debian/8/armhf/latest jessie main
Then I updated the apt-get package repos and installed salt-minion through apt-get.
sudo apt-get update
sudo apt-get install salt-minion
The installation completed and I added the Salt-Master’s IP-address to the minion configuration file in /etc/salt/minion.
# Set the location of the salt master server. If the master server cannot be
# resolved, then the minion will fail to start
Finally, I restarted salt-minion and it started to look for it’s master. That’s everything for the minion.
Testing the connection between Master and Minion
Now, all that’s left to do, is to accept the minion’s key on master and we’re good. I listed all keys with the command “sudo salt-key –list all“. Raspberrypi was listed under “unaccepted keys”. I accepted all unaccepted keys with “sudo salt-key -A“. The Pi was now listed under “accepted keys”:
It lists master as a minion too because I originally tested both Salt-Master and the Minion locally on the server.
Now, I could test the connection between our Raspberry Pi and the server with “sudo salt raspberrypi test.ping“. The minion responded:
This meant, that we could now run shell commands on the Pi from our server! The syntax is “sudo salt raspberrypi cmd.run ’command’” where ”raspberrypi” is the name of the minion and ”command” is the shell command I wish to run on the Pi. If I had more minions, I could run the commands to all of them simultaniously by calling the minion’s name with ‘*’ in the previous example.
Let’s test it out with checking the results of ifconfig on the Pi:
sudo salt raspberrypi cmd.run ’ifconfig’
We could now use Salt for restarting the sensor device or for running basic troubleshooting commands. Salt is way more powerful that this, but for now, this is all we need.