Chapter 11. MCollective Security

At this point your MCollective setup is a simple security model. You either have rights to issue requests, or you do not. You may want a security model with more granularity than that. Following are some reasons to evaluate alternative security plugins:

Security (Authentication) Plugin
The current setup uses a single Pre-Shared key to create an MD5 hash of the contents, which the servers use to ensure that the plain text request was not changed in flight. You may want cryptographic validation stronger than that.
Authorization Plugin
You either have rights to issue requests, or you do not. You may want a security model with granularity to limit some clients to specific hosts or to specific requests.
Auditing Plugin
The basic log files aren’t very informative about who issued a given request. You may want a detailed log of accepted and denied requests, and who submitted them.

As MCollective has a plugin architecture for security, you’ll find considerable flexibility in how to improve that situation. There is no singular right way to do security for MCollective, instead you are provided with tools to make security work exactly as you need. In this chapter we’re going on a tour of options for improving security to meet your needs.

This section describes authentication and authorization between clients (sending requests) and servers (validating the requests). This does not affect security of the Middleware transport, which was described in Chapter 9.

As the security is provided by plugins, each organization or even each collective of hosts can use a different security model that meets their needs. We’ll compare and contrast the security plugins available for MCollective, and document how to enable and use each one of these.

Note

MCollective documentation refers to the Authentication plugin as the Security plugin. I don’t prefer this term, as there are distinct Authorization and Auditing plugins which are part of most people’s concept of security. So I refer to it as the Authentication plugin in this section for clarity, but generally use the security plugin terminology matching the MCollective documentation.

How Authentication Works

When sending a command to a collective, the client embeds a caller identification in the request.

  1. A user invokes an MCollective client request like mco puppet runonce
  2. The client authentication/security plugin sets caller and adds it as metadata with the command
  3. The client publishes the message to the middleware
  4. The server authentication/security plugin validates the digest on the message
  5. The server authorization plugin validates that the caller is authorized to make this request
  6. The server processes the request

The Pre-Shared-Key plugin we have used thus far simply embeds the unix uid or gid in the request as the caller. Unless every client system is known to have the exact same uid/gid mappings, and no user has local root (e.g. desktops or laptops) the caller information cannot be trusted in this scenario. All you know for certain was that the client had the correct pre-shared-key. Is this good enough for your environment?

For more granular access control you may want to use the SSL, AES, or SSHKey security plugins we describe below. Each of these plugins use public keys to cryptographically validate the identity of the caller.

Pre-Shared Key Authentication

The Pre-Shared-Key authentication plugin signs an md5 hash of each request’s data with the pre-shared key appended. This hash is verified by the server who receives it to ensure that the request was sent from a client with the same key, and that the payload had not been modified.

Here’s an example configuration that would be put in both the client and server configuration files:

# Security provider
securityprovider = psk
plugin.psk = super secret
plugin.psk.callertype = uid

With this configuration the client will insert:

  1. A caller field comprised of the unix uid into the request
  2. A hash field that is an md5 digest of the message contents plus the pre-shared key

The server which receives this request will perform a hash of the message contents and their configured key information. If the md5 hash matches the hash in the request, the server will know the message was sent by an authorized person, e.g. someone who has the same pre-shared key. The caller information will be passed to the Authorization plugin, if enabled.

Warning

A common misconception is that the pre-shared key is used for encryption of the request. Read the previous paragraph carefully. Examine the packets using Wireshark and you will see the user name and password in the clear. The only cryptographic data is the md5 hash.

The PSK value is used as salt added to the request data before creating the hash. As such, PSK is an authentication mechanism which confirms only that the client has the same secret as the server does, and that the payload data has not been changed. It provides no encryption of the request contents.

The pre-shared-key plugin is very useful for several environments where:

  1. Small team environments share common passwords.
  2. All clients are controlled hosts and the uid/gid information is synchronized consistently.
  3. Security may not be important, and you wish to allow everyone to make changes.

Here’s a quick determination for whether this model works well for you: Do all of you share the same root password among yourselves? If so, this plugin may provide all the security you need.

The PSK plugin has only two options: key and callertype. The callertype can be only one of the following:

CallertypeInformation Included in the Request

uid

The UID of the user running client program (default)

gid

The GID of the group running client program

user

The username matching the UID running the client program.

group

The group matching the GID running the client program.

identity

The identity configuration parameter of the client (configurable, defaults to the hostname)

Which callertype to use depends upon your needs. Your choice will control:

  1. What value you can compare in the Authorization Policy
  2. What information is shown in the Audit log

Puppet Setup

If you are using the Puppet module provided with this book the following Hiera options will enable the Pre-Shared Key authentication plugin in your server and client configuration files:

mcollective::security_provider: 'psk'
mcollective::psk_key          : 'super secret'
mcollective::psk_callertype   : [ uid | gid | group | user | identity ]

You could of course pass them into the module as parameters if you really dig the old-school methods:

class { 'mcollective':
  security_provider => 'psk',
  psk_key           => 'super secret',
  psk_callertype    => 'uid',
}

SSL Authentication

When using the SSL security plugin each user issuing commands must have a unique private and public key. All servers will share the same public and private key. This allows for cryptographic assurance of each client request. For this security module to work, the following must be true:

  1. All servers share a single public/private keypair.
  2. Each client (host) must have the server public key.
  3. Each user (person) must have their own public/private keypair.
  4. Each server must have the public key for any user allowed to send commands to it.

With this configuration the client will:

  1. Insert a caller field comprised of the client certificate’s filename into the request
  2. Serialize the message body, the message time, and the time-to-live
  3. Insert a hash field containing a cryptographic signature of the serialized data

When the message is received by the server, it will use the client’s public key to validate the signature and confirm that the message is from a valid caller, and that the message time and time-to-live haven’t been altered.

If you combine this with TLS Encryption on the Middleware, then you have both an encrypted tunnel (provided by the TLS Security) and cryptographic authentication of the client’s request. This is Puppet Lab’s recommended solution.

Server Configuration

The server private and public key is common and shared among every server. You can create them like so:

$ mkdir server
$ cd server
$ openssl genrsa -out private.pem 2048
Generating RSA private key, 2048 bit long modulus
.............................................................+++
..........................................+++
e is 65537 (0x10001)
$ openssl rsa -in private.pem -out public.pem -outform PEM -pubout
writing RSA key
$ cd ..

Move these files to mcollective’s directory and safeguard them:

$ chmod 400 server/private.pem
$ sudo chown -R root:root server/
$ sudo mkdir -p /etc/mcollective/ssl/clients
$ sudo mv server /etc/mcollective/ssl/

To use these keys you would remove the two lines referencing the PSK plugin from server.cfg and add the following lines:

mcollective/server.cfg

securityprovider           = ssl
plugin.ssl_server_private  = /etc/mcollective/ssl/server/private.pem
plugin.ssl_server_public   = /etc/mcollective/ssl/server/public.pem
plugin.ssl_client_cert_dir = /etc/mcollective/ssl/clients

Installing and Synchronizing with Puppet

If you are using the Puppet module provided with this book, you would run the following commands to move those keys and files into the Puppet module directory. The puppet module will distribute the key pair out to all servers automatically.

$ chmod 440 server/private.pem
$ sudo mv server/* /etc/puppet/modules]/mcollective/files/ssl/server/
$ sudo chown -R root:puppet /etc/puppet/modules]/mcollective/files/ssl/server

The following Hiera options will enable the appropriate configuration in your server.cfg:

mcollective::server::security_provider : ssl

# The following are defaults which can be overridden
mcollective::ssl_server_private        : /etc/mcollective/ssl/server/private.pem
mcollective::plugin.ssl_server_public  : /etc/mcollective/ssl/server/public.pem
mcollective::plugin.ssl_client_cert_dir: /etc/mcollective/ssl/clients/

Client Configuration

Each client requires their own certificate in order to connect. A common way would be to make each user have their own certificate. A perhaps less cumbersome way is to create certificates for each team, and ensure that only that team has access to the private key. You can likely think of other ways of breaking this out. Either way, you will need to create an SSL certificates for each unique entity you wish to validate.

Each client needs a public and private key. The private key should be kept secure and not shared beyond the people authorized to use it. Every public key must be distributed to every mcollective server.

Create a Client Identity

Start out by creating the appropriate directory structure for your keys. You may have done this already, in which case simply perform the last command:

$ mkdir ~/.mcollective.d
$ cd ~/.mcollective.d
$ mkdir certs private_keys public_keys

If you already generated Puppet keys for a Trusted TLS connector, you can easily re-use those same keys:

$ cd private_keys
$ ln -s ~/.puppet/ssl/private_keys/username.pem
$ cd ../public_keys
$ ln -s ~/.puppet/ssl/public_keys/username.pem
$ sudo cp username.pem /etc/mcollective/ssl/clients/

If you created a new identity with a different CA, you may have everything except the public key. Create that now using these steps:

$ mkdir public_keys
$ openssl rsa -in private_keys/username.pem -out public_keys/username.pem -outform PEM -pubout
writing RSA key

If none of these directories exist, you can create a new keypair from scratch. You can generate a client keypair using Puppet as described in Trusted TLS Clients, or you can create a new keypair using openssl:

$ openssl genrsa -out private_keys/username.pem 2048
Generating RSA private key, 2048 bit long modulus
.............................................................+++
..........................................+++
e is 65537 (0x10001)
$ chmod 0400 private_keys/username.pem
$ openssl rsa -in private_keys/username.pem -out public_keys/username.pem -outform PEM -pubout
writing RSA key
$ sudo cp public_keys/username.pem /etc/mcollective/ssl/clients/

The MCollective client configuration needs to reference the server’s shared public key. To enable SSL authentication you would remove the lines referencing the PSK plugin from client.cfg and add the following lines:

mcollective/client.cfg

securityprovider = ssl
plugin.ssl_server_public = /etc/mcollective/ssl/server/public.pem

If a system is used by only one person (personal desktop or laptop), you could add the following lines to the client configuration:

plugin.ssl_client_private = /home/username/.mcollective.d/private_keys/username.pem
plugin.ssl_client_public = /home/username/.mcollective.d/public_keys/username.pem

For multi-user systems, it is best for users to add something like the following to their preferred shell profile.

export MCOLLECTIVE_SSL_PRIVATE=/home/username/.mcollective.d/private_keys/username.pem
export MCOLLECTIVE_SSL_PUBLIC=/home/username/.mcollective.d/public_keys/username.pem

Key Synchronization

2SSL Authentication requires three different synchronization issues be solved:

  1. Every server must have the same public and private key
  2. Every server must have the public key of every client who will make requests of it.
  3. Every client must have the public key of every server it will make requests to.

The Puppet module handles all three of these synchronization problems for you. Just store the files as follows, then go grab a beer.

TypePath on the Puppet Server

Server Private Key

<replaceable>modulepath</replaceable>/mcollective/files/ssl/server/private.pem

Server Public Key

<replaceable>modulepath</replaceable>/mcollective/files/ssl/server/public.pem

Client Public Keys

<replaceable>modulepath</replaceable>/mcollective/files/ssl/clients

$ sudo cp public_keys/username.pem /etc/puppet/modules/mcollective/files/ssl/clients/
$ sudo echo "Get me a Beer"

If you aren’t using the Puppet module, you will need to synchronize the following:

  1. The client public keys to each server’s /etc/mcollective/ssl/clients/ folder.
  2. The server public key to each client as /etc/mcollective/ssl/server/public.pem.
$ sudo cp public_keys/username.pem /etc/mcollective/ssl/clients/
$ rsync -av public_keys/* serverX:/etc/mcollective/ssl/clients/
$ rsync -av public_keys/* serverY:/etc/mcollective/ssl/clients/
...start thinking about how to script this...

RSA Authentication AES Encryption

When using the AES security plugin each user issuing commands must have a private and public key. Each server will also have a unique public/private keypair. This allows for cryptographic assurance of each client request, as well as cryptographic assurance of both replies from servers as well as data delivery from server to server, such as registration information.

For this security module to work, the following must be true:

  1. Each server must have a unique public/private keypair.
  2. Each client must have their own public/private keypair.
  3. Each server must have the public key for any client allowed to send requests to it.

Each request is encrypted with the client’s private key. Only servers with the client’s public key can decrypt and process them.

Each reply is encrypted with the client’s public key. Only the client with that private key can decrypt and read the replies.

Registration data and other requests from servers are encrypted with the server’s private key. Only client’s with the server’s public key can view the data.

Server Configuration

This complex configuration is made nearly trivial by using the existing Puppet Certificate Authority.

Puppet Module

If you are using the Puppet module provided with this book, you don’t need to generate keys for each server. Every puppet host already has a unique public/private key pair which the server will reuse.

The following Hiera options will enable the appropriate configuration in your server.cfg:

mcollective::server::securityprovider: aes_security

Manual Config

Create a keypair for the server:

$ cd /etc/ssl
$ openssl genrsa -out private_keys/username.pem 2048
Generating RSA private key, 2048 bit long modulus
.............................................................+++
..........................................+++
e is 65537 (0x10001)
$ chmod 0400 private_keys/username.pem
$ openssl rsa -in private_keys/username.pem -out public_keys/username.pem -outform PEM -pubout
writing RSA key

Modify the server configuration to use the newly generated keys. Remove the lines referencing the PSK or SSL plugin from server.cfg and add the following lines to /etc/mcollective/server.cfg:

securityprovider           = aes_security
plugin.aes.server_public   = /etc/ssl/public_keys/certname.pem
plugin.aes.server_private  = /etc/ssl/private_keys/certname.pem
plugin.aes.client_cert_dir = /etc/mcollective/ssl/clients
plugin.aes.enforce_ttl     = true

Client Configuration

Start out by creating the appropriate directory structure for the client keys. This may be done already, in which case simply perform the last command:

$ mkdir ~/.mcollective.d
$ cd ~/.mcollective.d
$ mkdir certs private_keys public_keys

If you already generated Puppet keys for a Trusted TLS connector, you can easily re-use those same keys:

$ cd private_keys
$ ln -s ~/.puppet/ssl/private_keys/username.pem
$ cd ../public_keys
$ ln -s ~/.puppet/ssl/public_keys/username.pem
$ sudo cp username.pem /etc/mcollective/ssl/clients/

If you created a new identity with a different CA, you may have everything except the public key. Create that now using these steps:

$ mkdir public_keys
$ openssl rsa -in private_keys/username.pem -out public_keys/username.pem -outform PEM -pubout
writing RSA key

If none of these directories exist, you can create a new keypair from scratch. You can generate a client keypair using Puppet as described in Trusted TLS Clients, or you can create a new keypair using openssl:

$ openssl genrsa -out private_keys/username.pem 2048
Generating RSA private key, 2048 bit long modulus
.............................................................+++
..........................................+++
e is 65537 (0x10001)
$ chmod 0400 private_keys/username.pem
$ openssl rsa -in private_keys/username.pem -out public_keys/username.pem -outform PEM -pubout
writing RSA key
$ sudo cp public_keys/username.pem /etc/mcollective/ssl/clients/

To use these keys you would remove the lines referencing the PSK or SSL plugin from client.cfg and add the following line:

mcollective/client.cfg

securityprovider = aes_security

If a system is used by only one person (personal desktop or laptop), you could add the following lines to the client configuration:

plugin.aes.client_private = /home/username/.mcollective.d/private_keys/username.pem
plugin.aes.client_public = /home/username/.mcollective.d/public_keys/username.pem

For multi-user systems, it is best for users to add something like the following to their preferred shell profile.

export MCOLLECTIVE_SSL_PRIVATE=/home/username/.mcollective.d/private_keys/username.pem
export MCOLLECTIVE_SSL_PUBLIC=/home/username/.mcollective.d/public_keys/username.pem

Key Synchronization

RSA/AES Authentication requires three different synchronization issues be solved:

  1. Every server must have the same public and private key
  2. Every server must have the public key of every client who will make requests of it.
  3. Every client must have the public key of every server it will make requests to.

The Puppet module handles all three of these synchronization problems for you. Just store the files as follows, then go grab a beer.

TypePath on the Puppet Server

Server Private Key

<replaceable>modulepath</replaceable>/mcollective/files/ssl/server/private.pem

Server Public Key

<replaceable>modulepath</replaceable>/mcollective/files/ssl/server/public.pem

Client Public Keys

<replaceable>modulepath</replaceable>/mcollective/files/ssl/clients

$ sudo cp public_keys/username.pem /etc/puppet/modules/mcollective/files/ssl/clients/
$ sudo echo "Get me a Beer"

If you aren’t using the Puppet module, you will need to synchronize the following:

  1. The client public keys to each server’s /etc/mcollective/ssl/clients/ folder.
  2. The server public key to each client as /etc/mcollective/ssl/server/public.pem.
$ sudo cp public_keys/username.pem /etc/mcollective/ssl/clients/
$ rsync -av public_keys/* serverX:/etc/mcollective/ssl/clients/
$ rsync -av public_keys/* serverY:/etc/mcollective/ssl/clients/
...start thinking about how to script this...

You will also need to synchronize the public keys out to each mcollective server.

Tip

If you read the documentation for this module, you will find that there are options to auto-distribute public keys between the systems. It is the opinion of the author that this provides equivalent or less security than the SSL Security module, and therefore it is extra overhead with a net security loss.

SSHKey Authentication

The SSHKey security plugin utilizes a pre-existing structure of SSH host and user keys. This allows unique identification of each user based on their private SSH key, and validation of the reply from the server against their known public key.

For this to work, the following must be true:

  1. Each user has every host’s public SSH key in ~/.ssh/known_hosts or an alternate file specified in the configuration.
  2. Each host having each user’s SSH public key in ~/.ssh/authorized_keys or an alternate file specified in the configuration
  3. Every client and server needs to have the sshkeyauth Gem installed.

This is not uncommon in a small environment where every user logs into every host, or where configuration management ensures that known hosts and authorized key files are kept in sync.

Here’s an example configuration that would be put in both the client and server configuration files:

mcollective/server.cfg

# Security provider
securityprovider = sshkey
plugin.sshkey.server.authorized_keys = /etc/ssh/authorized_keys   # instead of ~/.ssh/authorized_keys

mcollective/client.cfg

# Security provider
securityprovider = sshkey
plugin.sshkey.client.known_hosts = /etc/ssh/known_hosts  # instead of ~/.ssh/known_hosts

With this configuration the client will sign the command using the user’s private SSH key from ~/.ssh/id_pub_rsa as expected. The server will validate the command against public keys stored in /etc/ssh/authorized_keys. It will sign its reply with its own private key from /etc/ssh/ssh_host_rsa_key, and the client will validate the reply by checking the signature against /etc/ssh/known_hosts.

Puppet

If you are using the Puppet module provided with this book the following Hiera options will enable the appropriate configuration in your server and client configuration files:

mcollective::security_provider                : sshkey
mcollective::server::sshkey_authorized_keys   : /etc/ssh/authorized_keys
mcollective::client::sshkey_client_known_hosts: /etc/ssh/known_hosts

Warning

If you read the documentation for this module, you will find that there are options to auto-distribute public keys between the systems. It is the opinion of the author that this provides significantly less security, and depending on the configuration of the server, it actually would open the server up to breach via SSH protocol.

This is the security equivalent of showing up with a badge and handing the security guard the rules for how to validate the badge. And the guard will keep the new key around, and possibly even replace the existing keys for a user. Shudder

I do not recommend the use of these options.

Authorization

Authorization is a topic distinct and yet dependent on our choice of authentication. The Authorization plugin takes the caller and request information validated by the security (authentication) plugin and decides whether or not the request is allowed to proceed.

The deployment we have created so far allows any user who can read the client configuration file to execute any action on any server. This is reasonable and works well for many smaller environments where a small group of users are the only ones allow to act. If you have a larger team and a diverse variety of agent plugins, you may wish to limit who can act upon which resources. An authorization plugin allows the server to authorize requests on a per-client and per-action basis.

Warning

Be careful when pushing out an Authorization policy. You should ensure you have another method to login to each server to fix any mistake.

For any large-scale or production deployment, we recommend that you deploy the ActionPolicy authorization plugin to all servers. ActionPolicy uses policy rules for each agent, which can restrict the users able to request a given action.

The format of an ActionPolicy rule is tab-separated with the following fields:

Field #NameValues

1

Policy

allow or deny

2

Caller

The caller string provided in the request. Values are: * (always matches) one Caller string (discussed on the next page)

3

Action

An action provided by the agent the policy rule is for. Values: * (always matches) a space-separated list of actions

4

Facts

Facts which must be true about the target server. Values: * (always matches) a space-separated list of fact=value pairs (matches if every listed fact matches) any valid compound filter string

5

Classes

Puppet classes which apply to the target server. Values: absent (always matches) * (always matches) a space-separated list of class names (matches if every listed class is present) any valid compound filter string

You can of course create an authorization policy that uses a different file format, and a custom agent could do authorization based on its own criteria. We cover those possibilities in Chapter 13.

Caller IDs

No matter what authorization plugin you use, one of the fields available for matching is the caller field from the request. This field is set differently based on which security provider plugin you are using.

  1. The PSK security plugin set the caller ID to uid=uid of the user running the client app.

    This can be modified by setting plugin.psk.callertype in the configuration to gid, user, group, or identity. As uids and usernames are not consistent across hosts, these are not considered trustworthy.

  2. The TLS security plugins set the caller ID to cert=client’s public key filename without the .pem extension.

    The server looks in the ssl_client_cert_dir or aes.client_cert_dir to find a public key with the same name to validate the request.

  3. The SSH security plugin set the caller ID to sshkey=username invoking the client.

    The server looks in the user’s authorized_keys file to find an SSH public key to validate the request.

Defining ActionPolicy with Puppet

The Puppet module provided with this book will install the ActionPolicy module and configure it for you. There are two ways to define policies in Puppet:

  1. Creating rules dynamically from Hiera data
  2. Distributing static policy files

You can mix and match these two approaches, defining some policies in static files and others through Hiera.

Creating Policy in Hiera

Here is a simple ActionPolicy setup that denies all other requests, but allows anyone to run puppet to update the policy. This is a good catch-all in case a mistake is made in the configuration.

mcollective::server::authorization_enable: true
mcollective::server::authorization_default_policy: default_deny
mcollective::plugin::actionpolicies:
  default_deny:
    default: 'deny'
    rules: {}
  puppet:
    default: 'deny'
    rules:
      'allow puppet to fix policies':
        policy : 'allow'
        caller : '*'
        actions: 'runonce runall'
        facts  : '*'
        classes: '*'

This specifies that the default rules will be found in a file named default_deny.policy. The default attribute defines the default policy for each agent. The title must be unique for each rule, and is stored in the file as a comment above the rule defined in it.

If you enable authorization but do not specify a default policy, then authorization will be enabled on your server with allow_unconfigured enabled, which effectively enables a default allow policy.

Start from this basis to create a distinct policy for each agent. For example, this policy allows most commands but prevents anyone but admins from interacting with files, or disabling the puppet agent. This callerid assumes the PSK security provider with callertype set to group.

mcollective::plugin::actionpolicies:
  puppet:
    default: allow
        rules:
      'admins can disable the puppet agent':
        policy : 'allow'
        caller : 'group=admins'
        actions: 'disable'
        facts  : '*'
        classes: '*'
      'nobody else can':
        policy : 'deny'
        caller : '*'
        actions: 'disable'
        facts  : '*'
        classes: '*'

Here is another policy which allows any developer with the SSL key devel to interact with services on development boxes. This callerid assumes the SSL or AES security provider.

  service:
    default: deny
    rules:
      'developers':
        policy : 'allow'
        caller : 'cert=developers'
        actions: 'start stop restart status'
        facts  : 'hostgroup=development'
        classes: '*'

To allow or deny all requests for a specific agent without any specific rules, put an empty hash in the rules parameter. For example, to allow anyone to control packages on the server:

package:
    default: 'allow'
    rules: {}

You can use the same approach to deny all requests for an agent when the global default would allow it.

Distributing Policy Files

If you are not using Hiera, or wish to generate the policy files using another manner, the Puppet module can still provide value.

To configure a policy for an agent, place the file in the Puppet module’s files/policies/ directory. You will find example policies in this directory to guide you. This directory will be synchronized to every server.

Each file should be named agentname.policy except for the default policy which could be named anything ending with .policy. The default policy should be specified with the authorization_default_policy class or Hiera parameter, like so:

class { 'mcollective::server':
  authorization_enable         => true,
  authorization_default_policy => 'default_deny',
}

This specifies that the default rules will be found in a file named default_deny.policy. If you enable authorization but do not specify a default policy, then authorization will be enabled on your server with allow_unconfigured enabled, which effectively enables a default allow policy.

The allow_psk_root.policy_example demonstrates a basic default policy. It denies requests from anyone other than root on the client system. It is inherently insecure since most anyone can be root on their own desktop, but it demonstrates the functionality. There are several other example files included in the files/policies directory of the Puppet module.

Warning

Since you will need Puppet to fix any problems created by a new policy, we recommend that you include the first rule listed in the files/policies/puppet.policy_example file. This places a puppet policy that allows any client to run puppet to fix your authorization setup. Disable this at your own risk and after extensive testing.

Defining ActionPolicy Manually

Download the ActionPolicy agent from https://github.com/puppetlabs/mcollective-actionpolicy-auth and install it as documented in Installing from Source. Then add the following changes to each server.cfg file.

rpcauthorization = 1
rpcauthprovider = action_policy
plugin.actionpolicy.allow_unconfigured = 0
plugin.actionpolicy.enable_default = 1
plugin.actionpolicy.default_name = default

Create a default policy file and a policy for each agent, as documented at the plugin’s URL. Install the policy file in /etc/mcollective/policies/ on each server.

Here is an example service policy file:

# /etc/mcollective/policies/service.policy
# Admins can do anything
policy default deny
allow   cert=admin      *               *               *
# devs can do anything to devel boxes
allow   cert=devs       *               customer=startup        startup::devsystems
# devs can only do status on production systems
allow   cert=devs       status  customer=startup        *

You can also create a distinct policy for each agent. The file would be named agentname.policy and placed in the same directory. This directory must be synchronized to every server.

If you enable a default policy then it will apply to any agent for which a specific policy is not available. If you do not have a default policy and allow_unconfigured is enabled, then all requests for that agent will be denied.

Auditing

At this point in the book you have come to realize that MCollective is a very powerful tool capable of making massive changes to thousands of systems in seconds. Hopefully you’re asking yourself how to create logs of the requests processed by a server.

You can of course write your own plugin for auditing requests (which we’ll discuss in Creating Other Types of Plugins) but MCollective includes a basic audit plugin that may suit your needs. This audit plugin writes out each request that the server receives, and whether it was allowed or denied, to a logfile on disk.

Enable this with the following settings in the server configuration file:

/etc/mcollective/server.cfg to enable MCollective::Audit::Logfile

rpcaudit = 1
rpcauditprovider = Logfile
plugin.rpcaudit.logfile = /var/log/mcollective-audit.log

Note

Unlike the main mcollective log, this plugin doesn’t do any rotation of the logfile. You’ll need to setup logrotate or something similar to handle this.

If you are using the Puppet module included with this book, you need only set the following class parameters and both the logfile and a logrotate script will be set up for you.

# Hiera
mcollective::server::audit_logfile: /var/log/mcollective-audit.log

# manifests/site.pp
class { 'mcollective::server':
  audit_logfile => '/var/log/mcollective-audit.log',
}

The value logged for who sent the request differs based on which security provider is enabled, as discussed in Authorization. Here are some examples of how your logs might look with each of the security providers we discussed in the book and a client identity of geode.

securityprovider = psk, psk.callertype = uid
[2014-02-18 08:10:25 UTC] reqid=addb20797321590db29231f7c782b30f: reqtime=1392711027
caller=uid=1011@geode agent=service action=status data={:process_results=>true, :service=>"mcollective"}

securityprovider = psk, psk.callertype = user
[2014-02-18 08:11:26 UTC] reqid=cc3e1168916e5678b78c70ef337afa08: reqtime=1392711088
caller=user=jrhett@geode agent=service action=status data={:process_results=>true, :service=>"mcollective"}

securityprovider = ssl or aes, public key file = jorhett.pem
[2014-02-18 08:27:37 UTC] reqid=199d2a3cc16951bab84edba21a75fe71: reqtime=1392712059
caller=cert=jorhett@geode agent=service action=status data={:service=>"mcollective", :process_results=>true}

securityprovider = sshkey, username = jrhett
[2014-02-18 08:11:26 UTC] reqid=cc3e1168916e5678b78c70ef337afa08: reqtime=1392711088
caller=user=jrhett@geode agent=service action=status data={:process_results=>true, :service=>"mcollective"}

Conclusion

In this section we have discussed the three types of security plugins you may want to enable or customize for your environment.

Security (Authentication) Plugin
A choice of PSK, SSL, AES, or SSHKey security plugins provides a variety of ways to authenticate the source of requests received by the server.
Authorization Plugin
The ActionPolicy plugin can be used to limit which users may submit which requests to which servers.
Auditing Plugin
The LogFile plugin can be use to write details of every request processed to disk.

MCollective’s plugin architecture provides flexibility to tune your MCollective environment to your exact needs.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.139.86.18