I've worked as a systems administrator for the last 15 years with most of that time focused on Linux and web-layer administration. I began using SaltStack professionally five years ago while working for EMC. About a year ago my passion for SaltStack brought me, serendipitously, to work at SaltStack as a site reliability engineer (we used to just call this sysadmin).
In light of the recent Salt CVE I wanted to share some best practices that have served me well in the implementation and maintenance of a Salt environment. To loosely quote Voltaire (or Spiderman...depending on your orientation), "With great power comes great responsibility."
I have long believed and passionately debated that network connectivity is the largest piece of the security pie. While a computer disconnected from the internet can be compromised, it sure makes things a lot more difficult for a would-be hacker.
I prefer the Salt Master run in a private network, unaccessible to the internet, with no public IP address. The Salt Master is the most critical piece of your Salt implementation as it has the ability to reach every part of your infrastructure. The same is true of any configuration management or remote execution tool you may use.
There are few scenarios where the Salt Master reasonably needs to be accessible to the internet. In those scenarios, strict firewall rules should be used. Avoid allowing large ranges in your firewall rules and instead restrict access to specific /32 addresses. Allow only 4505/4506 in from those /32 IPs.
Here are Linux examples.
Allow specific ips to access 4505/4506:
iptables -I INPUT -s $minionIP/32 -p tcp -m multiport --dports 4505,4506 -j ACCEPT
iptables -A INPUT -i lo -p tcp --dports 4505:4506 -j ACCEPT # allow loopback
Reject everything else to these ports:
iptables -A INPUT -p tcp -m multiport --dports 4505,4506 -j REJECT
Add those rules into:
And enable them:
ufw allow salt
For more information about how to tune your Linux distribution to use iptables, read:
Here are FreeBSD examples.
Add following rules into /etc/pf.conf:
pass in on $ext_if proto tcp from $minionIP/32 to $ext_if port 4505:4506
For more information about how to tune FreeBSD pf rules, read:
Running a Salt API
If you are running a Salt API server, restrict access to the nodes that specifically need it. Consider using a proxy in front of the Salt API server, and hardening the server.
Avoid allowing access to the Salt Master from just any private network ranges. It may be tempting to allow 10.0.0.0/8 to access your Salt Masters over 4505/4506, 443, and even ssh. Prefer allowing the specific subnets to the transport ports that need it.
Consider implementing a VPN to restrict access to your internal resources and limit connectivity to the Salt Masters over ssh to certain groups. Utilizing a bastion host is another great way of restricting access and adds an additional layer an attacker would have to circumvent to access your Salt Master.
Restricting access to your Salt Master is the most impactful step you can take to secure your Salt infrastructure. Please also take note of the best practices found in this Salt hardening guide. I hope you found these thoughts and suggestions helpful.
Special thanks to Kirill Ponomarev, SaltStack SRE based in Austria, for providing links and specific commands.