Puppet security centers on PKI trust management, strict node enrollment, code integrity, secrets protection in Hiera data, and securing the Puppet Server/Agent communication channel. As an agent-based system with certificate-based authentication, protecting the PKI infrastructure is paramount.
# Protect Puppet CA private key
# /etc/puppetlabs/puppet/ssl/ca/ca_private_key.pem
chmod 600 /etc/puppetlabs/puppet/ssl/ca/ca_private_key.pem
chown puppet:puppet /etc/puppetlabs/puppet/ssl/ca/ca_private_key.pem
# Backup CA key securely (encrypted)
openssl rsa -in ca_private_key.pem -aes256 -out ca_private_key.enc.pem
# /etc/puppetlabs/puppet/puppet.conf - SECURE configuration
[main]
autosign = false # Disable autosign by default
# If autosign required, use restrictive patterns only
# [master]
# autosign = /etc/puppetlabs/puppet/autosign.conf
# /etc/puppetlabs/puppet/autosign.conf - Example (use with caution)
# *.dev.example.com
# web[0-9].prod.example.com
autosign = true in production# List certificates
puppet cert list
puppet cert list --all
# Sign certificate manually
puppet cert sign web-server-01.example.com
# Revoke compromised certificate
puppet cert clean compromised-node.example.com
# Check certificate details
puppet cert fingerprint --certname web-server-01.example.com
# Verify node certificate
openssl x509 -in /etc/puppetlabs/puppet/ssl/certs/$(hostname).pem -text -noout
# Check SSL configuration
puppet config print ssl_server
puppet config print ca_server
# Git configuration for control repository
# .gitignore
*.pem
*.key
secrets/
hiera-eyaml/**/*.key
# .gitattributes
*.pp text eol=lf
*.erb text eol=lf
*.yaml text eol=lf
# Pre-commit hooks for Puppet code
# .git/hooks/pre-commit
#!/bin/bash
puppet parser validate --color *.pp
puppet-lint --fail-on-warnings *.pp
# CI pipeline checks
puppet syntax check
puppet-lint check
rspec-puppet test
puppet parser validate before commit# Puppet environments structure
/etc/puppetlabs/code/environments/
├── production/
│ ├── manifests/
│ ├── modules/
│ └── hiera.yaml
├── staging/
│ ├── manifests/
│ └── modules/
└── development/
└── manifests/
# Install hiera-eyaml gem
gem install hiera-eyaml
# Generate keys
eyaml createkeys
# Encrypt a value
eyaml encrypt -s 'my_secret_password'
# Use in Hiera YAML
# hiera/data/common.yaml
myapp::password: >
ENC[PKCS7,MIIB...encrypted-data...]
# Puppet lookup with Hiera
$database_password = lookup('myapp::database_password')
# Hiera configuration with Vault backend
# hiera.yaml
hierarchy:
- name: "Vault Secrets"
lookup_key: vault_lookupup::lookup
options:
address: 'https://vault.example.com:8200'
token: '/etc/puppetlabs/puppet/vault_token'
# NEVER include secrets in manifests
# Bad example - DO NOT DO THIS:
# file { '/etc/myapp/config':
# content => "password=supersecret123", # DANGEROUS!
# }
# Good example - Use lookup:
file { '/etc/myapp/config':
content => template('myapp/config.erb'),
}
# In template, use lookup:
# <%= @database_password || lookup('myapp::database_password') %>
# Check Puppet versions
puppet --version
puppetserver --version
# Update Puppet (Debian/Ubuntu)
apt update && apt install puppet-agent puppet-server
# Update Puppet (RHEL/CentOS)
yum update puppet-agent puppet-server
# /etc/puppetlabs/puppet/puppet.conf - Enable reports
[main]
reports = store,http
reporturl = https://puppet-reporting.example.com
# Firewall rules for Puppet
# Allow Puppet Server port (8140) from managed nodes only
iptables -A INPUT -p tcp --dport 8140 -s 10.0.0.0/8 -j ACCEPT
iptables -A INPUT -p tcp --dport 8140 -j DROP
# Verify listening
ss -tulpn | grep 8140
# Check last Puppet run
puppet agent --test --noop
last_run_summary.yaml
# Query PuppetDB for failed runs
puppet query 'nodes[certname] { latest_report_status = "failed" }'
# Check for stale nodes
puppet query 'nodes[certname] { latest_report_noop < "2026-03-01" }'
# Puppet Server logs
tail -f /var/log/puppetlabs/puppetserver/puppetserver.log
# Audit log configuration
# /etc/puppetlabs/puppetserver/conf.d/puppetserver.conf
authorization:
rules:
- path: "/"
allow:
- admin
log: true
# Generate compliance report
puppet report generate --type compliance
# InSpec integration
inspec exec profiles/cis-puppet -t puppet://localhost
# Puppet Compliance (Enterprise)
# Configure compliance profiles in Puppet Enterprise Console
# Check Puppet version
puppet --version
puppetserver --version
# List certificates
puppet cert list
puppet cert list --all
# Check SSL configuration
sudo grep -E "ssl|cert|ca" /etc/puppetlabs/puppet/puppet.conf
# Verify autosign setting
grep "autosign" /etc/puppetlabs/puppet/puppet.conf
# Check listening ports
sudo ss -tulpn | grep -E ':8140|:8139'
# Review recent runs
tail -100 /var/log/puppetlabs/puppet/puppet.log | grep -E "applied|failed|error"
# Check certificate expiry
openssl x509 -in /etc/puppetlabs/puppet/ssl/certs/$(hostname).pem -enddate -noout
# Query PuppetDB
puppet query 'nodes[certname] { }' | jq '.[].certname'
# Verify Hiera eyaml keys
ls -la /etc/puppetlabs/puppet/eyaml/