Skip to main content

Raymii.org Raymii.org Logo

Quis custodiet ipsos custodes?
Home | About | All pages | Cluster Status | RSS Feed | Gopher

Clear Uncluttered SSH client config with Ansible

Published: 21-12-2014 | Author: Remy van Elst | Text only version of this article


❗ This post is over six years old. It may no longer be up to date. Opinions may have changed.

Openssh allows you to configure parameters like username, port, proxycommand, key and more in the ~/.ssh/config file. If you have many servers this file can become cluttered and maintaining it can become a not so nice task. This simple guide shows you how you can use a conf.d directory with seperate smaller files which gets converted to the big config file by Ansible.

I need to manage a lot of linux servers. With a lot I mean almost a thousand servers. Some of those servers require VPN, some of those servers are clusters and some of those servers require a seperate key, username, port or configuration. I don't like the big ~/.ssh/config file which, in my case, is extremely large.

Consider sponsoring me on Github. It means the world to me if you show your appreciation and you'll help pay the server costs.

You can also sponsor me by getting a Digital Ocean VPS. With this referral link you'll get $100 credit for 60 days.

I much rather prefer the conf.d type structure with a lot of small files. OpenSSH does not support this, however, Ansible has the assemble module which, given a set of files or a folder, assembles a configuration file based on all the given files.

Using this Ansible module together with a local connection we can assemble the configuration file on our own machine.

Create the ~/.ssh/conf.d folder:

mkdir ~/.ssh/conf.d/ 

Split your configuration up in smaller parts, like below:

$ ls -larth ~/.ssh/conf.d
total 36M
-rw-r--r-- 1 user user  396 Sep 27 14:07 defaults
-rw-r--r-- 1 user user  216 Sep 27 14:07 client1
-rw-r--r-- 1 user user 4812 Dec 10 04:03 client2
-rw-r--r-- 1 user user  216 oct  5 08:37 client3

Copy the following Ansible playbook locally:

- name: SSH config assembler
  hosts: 127.0.0.1
  connection: local

  tasks:

  - assemble: src=/home/user/.ssh/conf.d dest=/home/user/.ssh/config

Don't forget to change the username to yours.

And run it:

ansible local_ssh.yml

You now have the big ~/.ssh/config file generated out of the small files.

My defaults file contains the following:

###################################
# Start Defaults                  #
###################################

ForwardX11 yes
GSSAPIAuthentication no
HashKnownHosts yes

Host *
  ConnectTimeout 90
  ServerAliveInterval 10
  ControlMaster auto
  ControlPersist yes
  ControlPath ~/.ssh/socket-%r@%h:%p
  RemoteForward 8022 localhost:22

The clientX files contain specific client configuration:

Host web-jumphost
  Hostname 10.39.179.2
  User remy
  IdentityFile ~/.ssh/id_rsa_clientX
  Port 22

Host web22 web22.example.org
  Hostname 10.39.100.5
  ProxyCommand ssh -W %h:%p -i ~/.ssh/id_rsa web-jumphost
  User remy
  IdentityFile ~/.ssh/id_rsa_clientX
  Port 22

To read more about the ssh client config file, see the manual page: http://linux.die.net/man/5/ssh_config

Tags: ansible , bash , blog , openssh , ssh , ubuntu