Categorygithub.com/jasonhancock/autosignr
repositorypackage
0.0.0-20200527213112-b0d3b851ac2c
Repository: https://github.com/jasonhancock/autosignr.git
Documentation: pkg.go.dev

# Packages

No description provided by the author

# README

autosignr

Build Status Go Report Card

A Custom Policy Executable or a daemon (depending on your desired mode of operation) that watches for new Puppet CSRs from instances in AWS (or other clouds), validates the instances belong to you via the cloud provider's API, then signs the cert. Currently only supports AWS, Azure, GPC, but looking to add support for Openstack, Cloudstack, and generic REST APIs.

Autosignr can optionally be configured to validate pre-shared-keys embedded within the CSR. See the blurb in the Puppet Client Configuration section below for more details on how to embed a PSK into your CSRs.

This is a work-in-progress and is far from complete. Use at your own risk

Puppet Client Configuration (optional)

The Puppet client can use the instance ID as the certname in puppet.conf.

# Configures an AWS instance to use the instance ID as the certname. Use something like this to set it before the puppet client starts for the first time:

CONF=/etc/puppetlabs/puppet/puppet.conf

INSTANCE_ID=`wget -q -O - http://169.254.169.254/latest/meta-data/instance-id`

grep certname $CONF > /dev/null 2>&1
if [ $? -ne 0 ]; then
    echo "certname = $INSTANCE_ID" >> $CONF
else
    sed -i "s/certname =.*/certname = $INSTANCE_ID/" $CONF
fi

Optionally embedding a pre-shared key in the CSR

To embed a PSK in your CSR, create the csr_attributes.yaml file in Puppet's $confdir. The file looks something like this:

extension_requests:
    pp_preshared_key: my_preshared_key

For the full list of possible extensions and options that can be put into that file, see the Puppet documentation.

Modes of operation

Autosignr can function as either a custom policy executable (a process run by the Puppetmaster when a new CSR arrives) or as a standalone daemon that watches for new CSR's and signs them.

Configuring to run as a custom policy executable

To run as a custom policy executable, add the following to your Puppetmaster's puppet.conf in the [master] section:

autosign = /path/to/autosignr

Running as a daemon

To run as a daemon, simply start the executable. It doesn't fork itself. The redhat packaging includes a systemd unit file which should allow you to start the service as:

service autosignr start

Or more correctly:

systemctl start autosignr.service

If you're on el6 or older, you'll have to craft an init script, run under a process supervisor, etc.

Configuration Options

The configuration file lives at /etc/autosignr/config.yaml.

NameTypeDescription
dirstringThe path to the directory storing CSR files on the Puppetmaster
cmd_signstringThe command to execute to sign valid certificates. Should contain %s that will be replaced with the cert name
logfilestringOptional. If specified, log to this file instead of STDOUT
accounts_awsarray of AWS account hashesSee AWS Account details below. Accounts are searched in the order specified.
accounts_azurearray of Azure account hashesSee Azure Account details below. Accounts are searched in the order specified.
accounts_gcparray of GCP account hashesSee GPC Account details below. Accounts are searched in the order specified.
preshared_keysarray of stringsOptional. Array of valid preshared keys embedded within the certificate's extension fields. See the Puppetlab's documentation on SSL cert extensions for more details on how to embed a PSK into your CSR's. If PSKs are defined in the configuration, then all CSR's will be required to have valid PSK's to be automatically signed

Example Configuration:

dir: /etc/puppetlabs/puppet/ssl/ca/requests
cmd_sign: /opt/puppetlabs/bin/puppet cert sign %s
logfile: /var/log/autosignr/autosignr.log
accounts_aws:
  - name: jhancock aws packer
    key: AWS_KEY_ID
    secret: AWS_SECRET_KEY
    regions:
      - us-west-2
      - us-east-1
preshared_keys:
  - abc123
  - defghi

Account Configuration

Each account must have a name specified. In addition, each type of account may require its own set of attributes.

NameTypeDescription
namestringA short, descriptive name for this account.

Account Type: aws

NameTypeDescription
keystringAWS Key Id
secretstringAWS Secret Key
regionsarray of stringsA list of regions to check for each instance. Regions are searched in the order specified
attributestringOptional. Defaults to instance-id. The name of the attribute to compare the certname against. Useful for using a tag to compare against instead of the instance id...set to tag:Name to compare against the Name tag

Account Type: azure

NameTypeDescription
client_idstringAzure Client Id
client_secretstringAzure Secret Key
subscription_idstringSubscription Id
tenant_idstringTenant Id
attributestringOptional. Defaults comparing the certname with Tags Name. If you want to use another Tag specify the key value here
dns_zonestringOptional. This will compare the certname with the computer name plus the Tag dns_zone. This option is useful for Scale Sets

Account Type: gcp

NameTypeDescription
project_idstringproject_id
credential_filestringThe path to the key json

GCP checks the hostnames on instances with the cert name. Other attributes not supported at this time.


autocleanr

Monitor the PuppetDB for inactive nodes (report_timestamp < X hours) then use the cloud provider's API to verify the certname no longer exists. Then runs custom commands to deactivate and clean the cert name.

Run as a CronJob

Example

15 */4 * * * /usr/sbin/autocleanr > /dev/null 2>&1

Configuration Options

The configuration file lives at /etc/autosignr/autocleanr.yaml.

NameTypeDescription
logfilestringOptional. If specified, log to this file instead of STDOUT
clean_commandsarray of stringThe command sto execute to deactivate and clean node from puppet. Should contain %s that will be replaced with the cert name
include_filtersarray of stringsOptional. Additional PQL filters to add to the query to find inactive nodes. More information in below setting
inactive_hoursintNumber of hours before the node is considered inactive.
puppetdb_hoststringThe Hostname for the PuppetDB node
puppetdb_protocolstringThe protocol to connect to puppetdb (http
uppetdb_ignore_cert_errorsbooleanSet to true if you want to ignore any cert errors. Should only be set to true in development environments
puppetdb_nodes_uristringThe Root endpoint for the PuppetDB.

Example Configuration:

logfile: /var/log/autosignr/autocleanr.log
clean_commands:
  - /opt/puppetlabs/bin/puppet node deactivate %s
  - /opt/puppetlabs/bin/puppet node clean %s
include_filters:
  - and facts{name = \"locations\" and value in [\"aws\"]}
inactive_hours: 4
puppetdb_host: puppetdb.example.com
puppetdb_protocol: https
puppetdb_ignore_cert_errors: false
puppetdb_nodes_uri: /api/pdb/query/v4

include_filters

Optional setting to include additional queries to the API call to PuppetDB.

This setting currently supports PQL

If include_filters is omitted:

curl -XPOST -H 'Content-Type:application/json' "http://localhost:8080/pdb/query/v4" \
-d '{ "query": "nodes[certname]{ report_timestamp < \"2019-01-26T04:02:27Z\" }" }'

If you add the following to the config file

include_filters:
   - and facts{name = \"location\" and value in [\"aws\"]}

Adding the filter above results:

curl -XPOST -H 'Content-Type:application/json' "http://localhost:8080/pdb/query/v4" \
-d '{ "query": "nodes[certname]{ report_timestamp < \"2019-01-28T04:02:27Z\" and facts{name = \"role\" and value in [\"nomad-client\"]} }" }'