A few days I configured a new server to be an Ansible node. This will allow my Ansible configuration tool to configure and install software.
Installing Ansible and getting it running is not covered by the post. All I show here is how I got a remote server ready to be configured by Ansible.
The server in question was running FreeBSD 9.2 with ZFSRoot.
Preparing the client for configuration by Ansible
Key to how Ansible works is ssh. Ansible also needs root access. Rather than allowing root to ssh in, which is never a good idea, I created a user specifically for running Ansible. This user will be the same on all hosts and it will have sudo access. The sudo authentication will be via ssh-agent. I got my start on this path by talking with the highly respected and knowledgable Michael W. Lucas.
Here are the steps I am about to describe:
- create the ansible user
- add ~/.ssh/authorized_keys file for that user
- install tools required by ansible
- configure ssh-agent auth for sudo
Allow only ssh-key logins, no passwords
I will allow only ssh-key logins on this host. I specify that by adding this to /etc/ssh/sshd_config
PasswordAuthentication no ChallengeResponseAuthentication no
After making that change, you need to restart sshd:
service sshd restart
You can test the login, without a key, and it should look like this:
$ ssh yourhost.example.com Permission denied (publickey).
Now that we allow only ssh-key logins, let’s create our special user.
Create the ansible user
It does not matter what user you create. The actual login name is not important. I picked ansible and created it with this command:
pw useradd -n ansible -s /bin/sh -m -d /usr/home/ansible -G wheel
The user is in the wheel group, so it can use sudo based on the criteria I specify later.
Add ~/.ssh/authorized_keys
Next, I create the .ssh directory:
mkdir /usr/home/ansible/.ssh chown ansible:ansible /usr/home/ansible/.ssh chmod 0700 /usr/home/ansible/.ssh
I had already created a set of ssh-keys for this user. The public key was then copied to this file:
/usr/home/ansible/.ssh/authorized_keys
The permissions were set accordingly:
chown ansible:ansible /usr/home/ansible/.ssh/authorized_keys chmod 0600 /usr/home/ansible/.ssh/authorized_keys
At this point, the ansible user should be able to login via ssh.
But before you login for the first time!
The safe approach is always to know your server’s ssh fingerprint before connecting. Make sure the output of this command, issued on the server in question:
# ssh-keygen -lf /etc/ssh/ssh_host_ecdsa_key.pub 256 bf:f1:ad:8d:0f:99:fb:fb:49:f6:5c:e9:70:0b:87:ae /etc/ssh/ssh_host_ecdsa_key.pub (ECDSA)
… matches what you see here when you first connect:
# ssh -A ansible@10.1.1.10 The authenticity of host '10.1.1.10 (10.1.1.10)' can't be established. ECDSA key fingerprint is bf:f1:ad:8d:0f:99:fb:fb:49:f6:5c:e9:70:0b:87:ae. Are you sure you want to continue connecting (yes/no)? yes
Install tools required by Ansible
There are a few tools required by Ansible. Let’s get them installed. These commands are suitable for unattended installs (i.e. you will not be prompted):
env ASSUME_ALWAYS_YES=YES pkg bootstrap pkg install -y sudo pkg install -y python pkg install -y security/pam_ssh_agent_auth pkg install -y ca_root_nss
Next, run visudo to allow wheel to run sudo, by making sure this line is uncommented:
%wheel ALL=(ALL) ALL
FYI, I install ca_root_nss because it helps with certificate authentication when fetching patches over https.
Configure ssh agent auth for sudo
In this step, I relied heavily upon Mr Lucas’ blog post on sudo auth via ssh-agent.
The only major difference between his setup and mine is this line at the head of /usr/local/etc/sudoers. Run visudo to add this line:
Defaults env_keep += "SSH_CLIENT SSH_CONNECTION SSH_TTY SSH_AUTH_SOCK",timestamp_timeout=0
In this section, I will tell sudo how to authenticate commands it is given.
My /usr/local/etc/pam.d/sudo file contains this:
auth sufficient /usr/local/lib/pam_ssh_agent_auth.so file=~/.ssh/authorized_keys auth required pam_deny.so account include system session required pam_permit.so
Any user in the wheel group should now be able to use sudo without typing their password, provided they are logged in with an ssh-key contained in ~/.ssh/authorized_keys. The authentication process will consult their ssh-agent.
That’s all folks!
Now your chosen Ansible user should allow you to connect and configure!
Thanks for this article, I ended up changing this line
auth sufficient /usr/local/lib/pam_ssh_agent_auth.so file=~/.ssh/authorized_keys
to use a separate file:
auth sufficient /usr/local/lib/pam_ssh_agent_auth.so file=/root/.ssh/sudo_authorized_keys
Since the ed25519 keys in ~/.ssh/authorized_keys for ssh authentication do not work with this pam module,
as it only supports the older rsa and dsa keys.
I opted have dsa keys in the root owned file for sudo auth, which also allows for a different passphrase to be used.
Perhaps this worked for me because I have older types of keys?
Hi Dan,
Great post. Based on what you’ve posted and whats in the new version of ansible I’ve put this together as a rough cut. I didnt create a different user but it could be easily extended to do that as well.
Thanks
I have not read it fully, but I’m guessing your script does what I just did manually?
Yep basically, I just ported your script into the more recent ansible features to run them raw with su more easily.
Thanks again!
If you encounter this message, you are probably using ED25519 keys
pam_ssh_agent_auth: error: key_from_blob: remaining bytes in key blob 36
See https://sourceforge.net/p/pamsshagentauth/discussion/903801/thread/784a4a5c/