Chapter 22: certmonger Mastery
Set It and Forget It: certmonger is RHELβs built-in certificate automation tool. Master it and youβll never manually renew a certificate again.
22.1 What is certmonger?
certmonger is a certificate tracking and automatic renewal daemon for RHEL.
Think of it as:
- π Certificate tracker - Monitors expiration dates
- π Auto-renewer - Renews before expiry
- π CA integrator - Works with FreeIPA, local/internal CAs, and custom external CA helpers
- βοΈ Service integration - Runs commands after renewal
Why certmonger?
Without certmonger:
β Manual tracking of expiration dates
β Calendar reminders to renew
β Manual CSR generation
β Manual service restart after renewal
β Risk of missing renewals β outages
With certmonger:
β
Automatic tracking
β
Automatic renewal
β
Automatic service reload
β
Centralized monitoring
β
No manual intervention!
22.2 Installation and Setup
Installation by RHEL Version
#============================================#
# INSTALL CERTMONGER
#============================================#
# RHEL 8/9/10
sudo dnf install certmonger -y
# RHEL 7
# sudo yum install certmonger -y
# Enable and start
sudo systemctl enable certmonger
sudo systemctl start certmonger
# Verify
systemctl status certmonger
sudo getcert list # Should show empty list initially
22.3 Basic Usage
Requesting a Certificate
#============================================#
# BASIC CERTIFICATE REQUEST
#============================================#
# Self-signed (for testing)
sudo getcert request \
-f /etc/pki/tls/certs/test.crt \
-k /etc/pki/tls/private/test.key
# From FreeIPA / IdM
sudo ipa-getcert request \
-f /etc/pki/tls/certs/web.crt \
-k /etc/pki/tls/private/web.key \
-K HTTP/$(hostname -f)@REALM \
-D $(hostname -f)
# For public Let's Encrypt certificates, use certbot (Chapter 24).
# certmonger is the native choice for IPA, local CA, and helper-based workflows.
Checking Status
#============================================#
# CHECK CERTIFICATE STATUS
#============================================#
# List all tracked certificates
sudo getcert list
# Check specific certificate by file
sudo getcert list -f /etc/pki/tls/certs/web.crt
# Check by request ID
sudo getcert list -i 20240101000000
# Verbose output
sudo getcert list -v
Status Values:
MONITORING: β Certificate issued, tracking expirationSUBMITTING: π Submitting request to CACA_UNREACHABLE: β Canβt reach CA serverCA_REJECTED: β CA rejected requestNEED_KEY_GEN_PIN: βΈοΈ Waiting for PIN (HSM/token)PRE_SAVE_COMMAND: π Running pre-save scriptPOST_SAVE_COMMAND: π Running post-save script
22.4 Advanced Options
Complete Request with All Options
#============================================#
# COMPLETE CERTMONGER REQUEST
#============================================#
sudo ipa-getcert request \
-f /etc/pki/tls/certs/web.example.com.crt \ # Certificate file
-k /etc/pki/tls/private/web.example.com.key \ # Private key file
-K HTTP/web.example.com@EXAMPLE.COM \ # Kerberos principal
-D web.example.com \ # DNS name (SAN)
-D www.example.com \ # Additional SAN
-D api.example.com \ # Another SAN
-U id-kp-serverAuth \ # Extended key usage
-N CN=web.example.com,O=Example,C=US \ # Subject DN
-g 2048 \ # Key size
-G rsa \ # Key type
-T caIPAserviceCert \ # IPA profile
-C "systemctl reload httpd" \ # Post-save command
-B "systemctl stop httpd" \ # Pre-save command
-v \ # Verbose
-w # Wait for completion
# Check status
sudo getcert list -f /etc/pki/tls/certs/web.example.com.crt
Key Options Explained:
| Option | Purpose | Example |
|---|---|---|
-f | Certificate file path | /etc/pki/tls/certs/web.crt |
-k | Private key file path | /etc/pki/tls/private/web.key |
-K | Kerberos principal | HTTP/web.example.com@REALM |
-D | DNS SAN | web.example.com |
-N | Subject DN | CN=web,O=Example |
-C | Post-save command | systemctl reload httpd |
-B | Pre-save command | systemctl stop httpd |
-c | CA name | IPA or external-ca |
-T | Certificate profile | caIPAserviceCert |
-g | Key size | 2048 or 4096 |
-G | Key type | rsa or ec |
22.5 Working with Different CAs
FreeIPA (Recommended for Internal)
#============================================#
# CERTMONGER + FREEIPA
#============================================#
# Prerequisites: System enrolled to IPA
ipa-client-install
# Request certificate
sudo ipa-getcert request \
-f /etc/pki/tls/certs/internal.crt \
-k /etc/pki/tls/private/internal.key \
-K HTTP/$(hostname -f)@REALM \
-D $(hostname -f) \
-C "systemctl reload httpd"
# certmonger automatically:
# β
Submits request to IPA CA
# β
Obtains certificate
# β
Saves to file
# β
Runs reload command
# β
Tracks expiration
# β
Renews ~28 days before expiry
Public ACME Requires certbot
#============================================#
# PUBLIC ACME VS NATIVE CERTMONGER WORKFLOWS
#============================================#
# Public Let's Encrypt certificate:
# Use certbot, not a fake certmonger CA profile.
sudo certbot certonly --apache -d public.example.com
# Native FreeIPA / IdM certificate:
sudo ipa-getcert request \
-f /etc/pki/tls/certs/internal.crt \
-k /etc/pki/tls/private/internal.key \
-K HTTP/$(hostname -f)@REALM \
-D $(hostname -f) \
-C "systemctl reload httpd"
External CA (Manual Submission)
#============================================#
# CERTMONGER WITH EXTERNAL CA
#============================================#
# Configure external CA helper
sudo getcert add-ca -c external-ca \
-e '/usr/local/bin/external-ca-submit.sh'
# Request certificate
sudo getcert request \
-c external-ca \
-f /etc/pki/tls/certs/external.crt \
-k /etc/pki/tls/private/external.key
# Helper script must:
# 1. Read CSR from stdin
# 2. Submit to external CA
# 3. Return certificate on stdout
22.6 Managing Tracked Certificates
Modify Tracking
#============================================#
# MODIFY EXISTING CERTIFICATE TRACKING
#============================================#
# Update post-save command without rekeying
sudo getcert stop-tracking -f /etc/pki/tls/certs/web.crt
sudo getcert start-tracking \
-f /etc/pki/tls/certs/web.crt \
-k /etc/pki/tls/private/web.key \
-C "systemctl reload httpd"
# Re-add -c, -K, -D, etc. if your original tracking entry used them
# Add additional SAN
sudo getcert resubmit -f /etc/pki/tls/certs/web.crt \
-D additional.example.com
# Stop tracking (keep certificate)
sudo getcert stop-tracking -f /etc/pki/tls/certs/web.crt
# Remove completely
sudo getcert stop-tracking -f /etc/pki/tls/certs/web.crt -r
# Start tracking existing certificate
sudo getcert start-tracking \
-f /etc/pki/tls/certs/existing.crt \
-k /etc/pki/tls/private/existing.key
Force Renewal
#============================================#
# FORCE IMMEDIATE RENEWAL
#============================================#
# By file path
sudo ipa-getcert resubmit -f /etc/pki/tls/certs/web.crt
# By request ID
sudo getcert resubmit -i 20240101000000
# Wait for renewal
sudo getcert list -f /etc/pki/tls/certs/web.crt
# Wait for status: MONITORING
22.7 Renewal Timing
Understanding Renewal Windows
Certificate Lifecycle (365 days):
Day 0: Certificate issued
β
β [Normal operation]
β
Day 243: Renewal window starts (certmonger attempts renewal)
β (2/3 of cert lifetime: 365 Γ 2/3 β 243 days)
β
β [Renewal attempts every 8 hours if CA available]
β
Day 335: Warning if not yet renewed (30 days left)
β
Day 350: Critical if not yet renewed (15 days left)
β
Day 365: Certificate expires β SERVICE OUTAGE if not renewed!
Default Behavior:
- Renewal starts at 2/3 of certificate lifetime
- 365-day cert β Renews at day 243 (122 days remaining)
- 90-day cert β Renews at day 60 (30 days remaining)
22.8 Post-Save Commands
Reload vs Restart
#============================================#
# POST-SAVE COMMAND STRATEGIES
#============================================#
# PREFER: reload (no downtime)
-C "systemctl reload httpd"
-C "systemctl reload nginx"
-C "postfix reload"
# SOMETIMES NEEDED: restart
-C "systemctl restart slapd" # OpenLDAP requires restart
-C "systemctl restart postgresql" # PostgreSQL requires restart
# MULTIPLE COMMANDS: Use script
-C "/usr/local/bin/after-cert-renewal.sh"
# Script example:
#!/bin/bash
# /usr/local/bin/after-cert-renewal.sh
systemctl reload httpd
systemctl reload nginx
systemctl reload postfix
logger "Certificates renewed via certmonger"
22.9 Troubleshooting certmonger
Common Issues
Issue 1: CA_UNREACHABLE
# Symptom
sudo getcert list
# status: CA_UNREACHABLE
# Diagnosis
# For FreeIPA:
ipa ping # Check IPA connectivity
klist # Check Kerberos ticket
# Fix
kinit -k host/$(hostname -f)@REALM # Renew host ticket
sudo ipa-getcert resubmit -f /etc/pki/tls/certs/web.crt
# Check IPA server
ssh ipa-server "sudo ipactl status"
Issue 2: CA_REJECTED
# Symptom
sudo getcert list
# status: CA_REJECTED
# ca-error: Server at https://ipa.example.com/ipa/xml unwilling to issue certificate
# Common causes:
# 1. Service principal doesn't exist
ipa service-show HTTP/$(hostname -f)
# If not found:
ipa service-add HTTP/$(hostname -f)
# 2. Host not enrolled
ipa host-show $(hostname -f)
# 3. Permission issue
# Check IPA permissions
# Retry
sudo ipa-getcert resubmit -f /etc/pki/tls/certs/web.crt
Issue 3: Renewal Not Happening
# Check certmonger is running
systemctl status certmonger
# Check certificate status
sudo getcert list -f /etc/pki/tls/certs/web.crt
# Check certmonger logs
sudo journalctl -u certmonger -f
# Force renewal
sudo ipa-getcert resubmit -f /etc/pki/tls/certs/web.crt
# Check renewal window
# Certificate renews at 2/3 of lifetime
# Check "expires" date in getcert list output
22.10 IdM ACME vs Public Letβs Encrypt
Keep the Workflows Separate
#============================================#
# CHOOSE THE RIGHT TOOL FOR THE RIGHT CA
#============================================#
# Public Let's Encrypt certificate:
# Use certbot (see Chapter 24).
sudo certbot certonly --apache -d public.example.com -d www.public.example.com
# Native FreeIPA / IdM certificate:
# Use certmonger + ipa-getcert.
sudo ipa-getcert request \
-f /etc/pki/tls/certs/internal.example.com.crt \
-k /etc/pki/tls/private/internal.example.com.key \
-K HTTP/internal.example.com@REALM \
-D internal.example.com \
-C "systemctl reload httpd"
# If IdM ACME is enabled, its ACME directory is your IPA server,
# not Let's Encrypt:
sudo certbot certonly \
--server https://ipa.example.com/acme/directory \
-d host.example.com
Important distinction:
- Letβs Encrypt = public internet ACME CA
- IdM/FreeIPA ACME = your internal IPA CA exposing an ACME endpoint
- certmonger = native RHEL tracker/renewer for IPA and helper-based workflows
22.11 Monitoring certmonger
Status Monitoring
#============================================#
# MONITOR CERTMONGER
#============================================#
# Overview of all certificates
sudo getcert list
# Count certificates by status
sudo getcert list | grep "status:" | sort | uniq -c
# Find certificates expiring soon (30 days)
for cert in $(sudo getcert list | grep "certificate:" | sed -n "s/.*location='\\([^']*\\)'.*/\\1/p"); do
if ! openssl x509 -in "$cert" -noout -checkend $((86400*30)) 2>/dev/null; then
echo "β οΈ Expires soon: $cert"
fi
done
# Check certmonger logs
sudo journalctl -u certmonger --since today
# Watch for renewal activity
sudo journalctl -u certmonger -f
# Check next renewal time
sudo getcert list | grep -A15 "Request ID" | grep "expires"
Health Check Script
#!/bin/bash
# certmonger-health-check.sh
echo "=== certmonger Health Check ==="
# certmonger running?
if systemctl is-active --quiet certmonger; then
echo "β
certmonger is running"
else
echo "β certmonger is NOT running!"
exit 1
fi
# Count tracked certificates
TOTAL=$(sudo getcert list | grep -c "Request ID")
echo "π Tracking $TOTAL certificates"
# Check status breakdown
echo ""
echo "Status breakdown:"
sudo getcert list | grep "status:" | sort | uniq -c
# Check for problems
PROBLEMS=$(sudo getcert list | grep "status:" | grep -v "MONITORING" | wc -l)
if [ $PROBLEMS -gt 0 ]; then
echo ""
echo "β οΈ $PROBLEMS certificates need attention:"
sudo getcert list | grep -B5 "status:" | grep -E "(Request ID|status:)" | grep -v "MONITORING"
fi
# Check expiration warnings
echo ""
echo "Certificates expiring in 30 days:"
sudo getcert list | grep -A10 "Request ID" | grep "expires:" | \
while read line; do
# Parse and check expiry
# (simplified - production script would parse dates properly)
echo "$line"
done
22.12 certmonger Configuration
Main Configuration File
#============================================#
# CERTMONGER CONFIGURATION
#============================================#
# Config location
/etc/certmonger/certmonger.conf
# Database location (tracked certificates)
/var/lib/certmonger/
# List configured CAs
sudo getcert list-cas
# Add custom CA
sudo getcert add-ca -c my-ca \
-e '/usr/local/bin/my-ca-submit.sh'
# Remove CA
sudo getcert remove-ca -c my-ca
22.13 Best Practices
certmonger Best Practices
β
**Always use post-save commands** (-C flag) to reload services
β
**Track all production certificates** with certmonger
β
**Monitor status weekly** with `getcert list`
β
**Test renewal** before expiry with `resubmit`
β
**Use verbose mode** (-v) when troubleshooting
β
**Set up monitoring** for CA_UNREACHABLE status
β
**Document request IDs** in your certificate inventory
β
**Use IPA/certmonger for internal** certs, certbot for public Let's Encrypt
β
**Keep certmonger logs** for audit trail
β
**Test post-save commands** independently before use
What to Track with certmonger
# β
TRACK with certmonger:
- Web server certificates (Apache, NGINX)
- Mail server certificates (Postfix, Dovecot)
- LDAP server certificates (OpenLDAP)
- Application certificates (APIs, microservices)
- Service certificates (any TLS-enabled service)
# β DON'T track with certmonger:
- CA root certificates (managed separately)
- Client certificates for users (different lifecycle)
- Test/temporary certificates
- Certificates you manage with other tools (certbot)
22.14 certmonger vs certbot
When to Use Which?
| Feature | certmonger | certbot |
|---|---|---|
| RHEL Native | β Yes (included) | β No (EPEL required) |
| FreeIPA Support | β Native | β No |
| Public Letβs Encrypt ACME | β Use certbot instead | β Yes (all versions) |
| Internal CA | β Excellent | β No |
| Apache/NGINX Config | βΈοΈ Manual | β Automatic |
| Service Integration | β Post-save commands | βΈοΈ Limited |
| Renewal Timing | 2/3 of lifetime | 30 days before |
| Red Hat Support | β Yes | β No (EPEL) |
Recommendation:
- Internal/Enterprise: Use certmonger + FreeIPA
- Public/Simple: Use certbot (but know it requires EPEL)
- Public certificates on any RHEL version: Use certbot for Letβs Encrypt
22.15 Advanced Scenarios
Scenario 1: High Availability Certificate Renewal
# Multiple servers with same service
# Server 1:
sudo ipa-getcert request \
-f /etc/pki/tls/certs/shared-service.crt \
-k /etc/pki/tls/private/shared-service.key \
-K HTTP/service.example.com@REALM \
-D service.example.com \
-C "systemctl reload httpd"
# Server 2: Same configuration
# Result: Each server manages its own cert independently
# Or: Use shared cert (copy files, not recommended)
Scenario 2: Wildcard Certificate
# Request wildcard from FreeIPA
sudo ipa-getcert request \
-f /etc/pki/tls/certs/wildcard.crt \
-k /etc/pki/tls/private/wildcard.key \
-K HTTP/*.example.com@REALM \
-D *.example.com \
-D example.com \
-C "/usr/local/bin/reload-all-services.sh"
Scenario 3: EC Keys (Elliptic Curve)
# Request with EC key
sudo ipa-getcert request \
-f /etc/pki/tls/certs/ec-cert.crt \
-k /etc/pki/tls/private/ec-cert.key \
-K HTTP/$(hostname -f)@REALM \
-G ec \
-g nistp256 # or nistp384, nistp521
22.16 Key Takeaways
- certmonger is RHELβs certificate automation
- Set it and forget it - Automatic renewal
- Works best with FreeIPA, internal CAs, and helper-based renewals
- Post-save commands reload services automatically
- Tracks expiration and renews at 2/3 of lifetime
- MONITORING status means all is well
- getcert list is your main monitoring tool
Quick Reference Card
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β CERTMONGER MASTERY QUICK REFERENCE β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β Install: dnf install certmonger (yum on RHEL 7) β
β Start: systemctl enable --now certmonger β
β β
β Request: ipa-getcert request -f cert -k key -K principalβ
β List: getcert list β
β Status: getcert list -f /path/to/cert.crt β
β Resubmit: ipa-getcert resubmit -f /path/to/cert.crt β
β Stop track: getcert stop-tracking -f /path/to/cert.crt β
β β
β Status: MONITORING = β
Good β
β CA_UNREACHABLE = β Check IPA/CA β
β CA_REJECTED = β Check principal/permissions β
β β
β Logs: journalctl -u certmonger -f β
β Renewal: Automatic at 2/3 of cert lifetime β
β Post-save: -C "systemctl reload <service>" β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β
Native RHEL tool (Red Hat supported)
β
Perfect for FreeIPA integration
β
Best fit for FreeIPA and tracked renewal workflows
π§ͺ Hands-On Lab
Lab 11: certmonger Basics
Automate certificate renewal with certmonger
- π Location:
labs/en_US/11-certmonger-basics/ - β±οΈ Time: 30-35 minutes
- π― Level: Intermediate
Chapter Navigation