2018-04-22

Ansible Week - Part 1

Let's get the bad news out of the way right now: Ansible is built on Python.

I know, I know. We'll get through it, guys... somehow.

I found that a number of other things I like have Python as a pre-requisite, including but not limited to the Microsoft-blessed WALinuxAgent you need on non-OpenBSD/LibreSSL Azure VM images. I have also found that I am, like, the only guy on the planet who hates Python with a bright, firey passion. So adopting Ansible is probably going to be easier for you than it was for me.

Back to mailcom for a sec. mailcom was very much a sysadmin's tool, written by a sysadmin for sysadmins. It was sharp, unbalanced, and unapologetic. You needed to learn how to "read" mailcom's logs to see if your plan worked as expected and there was zero chance it would hold your hand or ask you for clarification before obliterating your service like it was so much your hopes and dreams. There was a skill in "seeing" the mailcom activity in your mailcom logs.

When I started looking at kinder, gentler mailcom tools, I started with Puppet. Puppet does really interesting things, but Puppet's design requires an agent be present on the host. As I recall from years back when I last worked with Puppet, you needed to install Puppet, run it as root, and have it phone home regularly. From a security perspective, this could be A Bad Idea if you don't do it right and, as a neophyte Puppeteer, that was very likely.

Ansible's one big advantage, in my opinion, is that it is totally agentless. You still need a superuser account with sudo or doas permissions, but the remote access is managed entirely through SSH. (Ansible apparently also supports Windows via WinRM. Whatever.)

So maintaining your Ansible army is an exercise in SSH key management. Modern security experts wring their hands panicking over what they call "lateral movement", where an attacker on your network who has compromised one machine can access more machines with the same set of credentials. This is why people tell you not to use the same password on multiple accounts, but when it comes to your SSH keys, it's unbelievably easy to create one key on your base image and that's the key you use on every host cloned from that image.

In general, you want to avoid doing as much as root as you can. So to prep your target machine(s), you would want to create the following:

groupadd ansible
useradd -g ansible -m ansible

You may need to add your new local service account to the root or wheel group on your host. Add it to your /etc/sudoers file or, on OpenBSD, your doas.conf:

cp -p /etc/doas.conf /etc/doas.conf.bak
cp -p /etc/doas.conf /etc/doas.conf.new
echo permit nopass ansible as root >> /etc/doas.conf.new
mv /etc/doas.conf.new /etc/doas.conf

Once you have your service account, configure an SSH key to use to authenticate into that host.

# su -l ansible
$ ssh-keygen -t ed25519 -N '' -q -f ~/.ssh/id_ed25519
$ cd ~/.ssh
$ cat ./id_ed25519 >> ./authorized_keys
$ exit

You may need to fix permissions on your authorized keys file (chmod 0600) if it is not correct. Ensure that your sshd service is running and get ready to hook up this new SSH key to your ansible machine.

Next time: Verifying your distance to the target. One ping only.

No comments: