Chef security depends on node identity management, key lifecycle, cookbook integrity, RBAC on Chef Server, and protecting secrets in recipes and data bags. As a agent-based configuration management system, compromising Chef can lead to fleet-wide compromise.
# Chef Server configuration
# /etc/opscode/chef-server.rb
nginx['ssl_certificate'] '/var/opt/opscode/certs/chef-server.example.com.crt'
nginx['ssl_certificate_key'] '/var/opt/opscode/certs/chef-server.example.com.key'
nginx['listen_port'] 443
nginx['listen_https_port'] 443
# Disable HTTP redirect
nginx['enable_http_redirect'] = false
# Restrict API access
nginx['allow_list'] = ['10.0.0.0/8', '192.168.0.0/16']
# Create organization with RBAC
knife organization create myorg --association-user admin
# Create roles with least privilege
knife role create webserver
# Limit to specific cookbook versions and attributes
# Assign users to groups
knife acl add group web-admins users alice bob
# Review permissions
knife acl show /organizations/myorg
# List all users and clients
knife user list
knife client list
# Rotate user keys
knife user reregister admin
# Rotate client keys
knife client reregister web-server-01
# Delete unused clients
knife client delete old-server-01
# Secure key storage
# ~/.chef/admin.pem - User key (chmod 600)
# /etc/chef/client.pem - Client key (chmod 600)
# /etc/opscode/webui_priv.pem - Server webui key (chmod 600)
# Verify permissions
ls -la ~/.chef/*.pem
ls -la /etc/chef/*.pem
ls -la /etc/opscode/*_priv.pem
.pem files.pem files to .gitignore# NEVER store secrets in cookbooks
# Bad example - DO NOT DO THIS:
# template '/etc/myapp/config.yml' do
# variables(
# password: 'supersecret123' # DANGEROUS!
# )
# end
# Good example - Use Chef Vault or external secrets:
chef_vault_item('myapp', 'credentials') do |secret|
secret.value('password')
end
# Or use AWS Secrets Manager
aws_secretsmanager_get_secret('myapp/prod')
# Create encrypted data bag
knife data bag create myapp credentials --secret-file /path/to/secret_key
# View encrypted data bag
knife data bag show myapp credentials
# Rotate secret key
# Re-encrypt all data bags with new key
--secret-file for encryption# metadata.rb - Pin cookbook dependencies
name 'myapp'
maintainer 'Infrastructure Team'
license 'Apache-2.0'
version '2.1.0'
depends 'nginx', '~> 12.0'
depends 'postgresql', '~> 9.0'
# Use Berksfile for workspace dependencies
# Berksfile
source 'https://supermarket.chef.io'
cookbook 'nginx', '~> 12.0'
cookbook 'postgresql', '~> 9.0'
# Run cookbook tests
kitchen test # Test Kitchen
chefspec # Unit tests
foodcritic # Linting
cookstyle # Style checking
# In CI pipeline
kitchen verify --parallel
# Upload cookbooks securely
knife cookbook upload myapp --freeze
# List uploaded cookbooks
knife cookbook list
# Show cookbook versions
knife cookbook show myapp
--freeze to prevent accidental changes# /etc/chef/client.rb
log_level :info
log_location '/var/log/chef/client.log'
chef_server_url 'https://chef-server.example.com/organizations/myorg'
ssl_verify_mode :verify_peer
ssl_ca_file '/var/opt/opscode/certs/chef-server.example.com.crt'
# Verify SSL
ssl_verify_mode :verify_peer # Never use :verify_none in production
:verify_peer in production# First-time client run (generates client.pem)
sudo chef-client
# Validate node registration
knife node list
knife node show web-server-01
# Re-register compromised node
knife client delete web-server-01
sudo rm /etc/chef/client.pem
sudo chef-client
knife bootstrap with SSH keys# /etc/opscode/chef-server.rb - Autosign (use with caution)
nginx['ssl_adhoc_clients'] = true
# Better: Use explicit node approval
# knife node bulk delete # Remove all nodes
# Then approve individually
# Check client run status
knife search node 'last_client_run:*' -a name -a last_client_run
# Review convergence failures
knife search node 'chef_run_failed:true' -a name -a run_list
# Check for stale nodes
knife search node 'ohai_time:<threshold>' -a name
# Enable audit logging (Chef Automate)
# /etc/opscode/chef-server.rb
audit_logging['enabled'] = true
audit_logging['log_path'] = '/var/log/opscode/audit'
# Review audit logs
tail -f /var/log/opscode/audit/audit.log
# Run InSpec compliance scans
inspec exec profiles/cis-ubuntu-20.04 -t ssh://user@host
# Chef Compliance (Automate)
# Configure compliance profiles in Chef Automate UI
# Report compliance status
knife compliance profile list
# Check Chef version
chef --version
knife --version
# Verify client configuration
cat /etc/chef/client.rb | grep -E "chef_server_url|ssl_verify"
# Check key permissions
ls -la ~/.chef/*.pem /etc/chef/*.pem 2>/dev/null
# List nodes
knife node list
# Check node details
knife node show $(hostname) -l
# Review run history
tail -100 /var/log/chef/client.log | grep -E "started|completed|failed"
# Verify SSL connection
openssl s_client -connect chef-server.example.com:443 -tls1_2 </dev/null 2>/dev/null | head -10
# Check cookbook versions
knife cookbook list
# Search for nodes with failures
knife search node 'chef_run_failed:true' -a name
:verify_peer