module:authkey - OpenSSH authorized_keys management

Configuration | Public Key Repository | Problems

The module:authkey script provides Secure Shell (SSH) public key management, associating user accounts with public keys and CFEngine class information. This simplifies configuration of SSH trust relationships, for example those used by role accounts. Currently, the module only supports OpenSSH authorized_keys files.

The global ssh_known_hosts file can be managed under CFEngine.

The module:users module can install users before module:authkey runs, and module:groups manage groups for use in keymap.ini statements.

Code running as root must not edit user authorized_keys files. A malicious user could link their file to some other critical system file. module:authkey avoids this problem via a fork and a POSIX module setuid change to the user before touching the authorized_keys file.

With the no_modify class set in the CFALLCLASSES environment variable, module:authkey will only display what changes would be made to the system. This simplifies rollouts to previously unmanaged systems.

The source code for module:authkey is only available by request.

Configuration

The main.ini, keymap.ini, and rules contain all configuration for module:authkey. Public keys must be saved into files under a different directory structure. module:authkey uses the mapping information in keymap.ini to associate particular public keys with various user accounts on systems belonging to particular CFEngine classes. The public key directories and preferences files should be saved under a version control repository.

main.ini

Contains global options for module:authkey. The module can optionally disable deprecated ~/.ssh/authorized_keys2 files, and optionally disable authorized_keys files it knows nothing about.

[defaults]
# only OpenSSH supported (required)
implementations = app_openssh

# where to read public keys from (required)
key_source = /var/cfengine/etc/ssh/pubkeys/%{keylist}/%{keyname}.pub

# disable unknown authorized_keys files (recommended)
manage_all = true

# auto-create ~/.ssh directories if needed
openssh_create_dotssh = true

# disable deprecated ~/.ssh/authorized_keys2 files (recommended)
openssh_ak2_disable = true

Keep the *.ini options files used by module:authkey tidy with the initidy script.

keymap.ini

Details the mappings between public keys (referenced by key_source in main.ini) and what accounts on which classes of systems.

# SiteScope public key for monitoring access
[sitescope-monitor]
classes = role_sitescope_client
keylist = roles
keyname = sitescope

account = healthcheck

# enforce sshd(8) access limitation to the key to restrict usage
options = from="monitor01.example.org,monitor02.example.org"

# Ensure sysadmins can login even if LDAP dead
# 1:1 map between accounts in the wheel group (minus root) and the
# public key for the user under the users keylist directory
[admins]
classes = any
keylist = users

account = @wheel -root

rules

Rulesets allow customization of the from="" and similar options detailed in sshd(8). For example, systems administrators could have access to all systems, except that production systems must be accessed through a particular bastion host:

test: name eq admins
{
test: cf.classes contains realm_prod
actions: options=from="gateway.example.org"
}

With the above from="" limitation, keys in authorized_keys will be created with the following prefix:

from="gateway.example.org" ssh-rsa AAAAB…

keygen.ini

The keygen.ini contains rules to generate passphrase-free public keys, for use by role accounts. Use passphrase-free keys should be restricted on the remote servers via from="" and command="" option limitations, if possible. The following entry would ensure all systems have id_rsa and identity key pairs generated under the home directory for the root user.

[default-root-keys]
classes = any
account = root

type = rsa rsa1

Public Key Repository

The public keys must be stored under a directory tree, broken down into different trees: users to store user-specific public keys, and roles for role based public keys. These files must contain one or more public keys, copied from where the key pair was generated (usually ~/.ssh/id_rsa.pub for a rsa key pair under OpenSSH).

$ ls
CVS roles users
$ ls roles
CVS sitescope.pub
$ ls users
CVS jmates.pub

module:authkey references these files via the key_source entry in the main.ini configuration file. CFEngine must copy the module preferences and public keys down to each client system.

Problems

Problems encountered writing this module: