When working with Puppet in NAT environments, a common frustration occurs when the reverse DNS resolution doesn't match the desired hostname configuration. The client machine reports its FQDN as office.mydomain.com
due to network topology, but we need it to identify as ns2.mydomain.com
for proper Puppet classification.
Puppet uses several methods to determine a node's identity:
- SSL certificate common name (certname)
- Reverse DNS resolution
- System hostname configuration
- Explicit configuration in puppet.conf
# Typical identification flow:
1. Client initiates connection with current hostname
2. Server checks certname first if configured
3. Falls back to FQDN from system/DNS
4. Matches against node definitions in manifests
The key is to properly configure the certname
setting while ensuring fact collection works correctly. Here's the optimal puppet.conf configuration:
[main]
certname = ns2.mydomain.com
node_name = cert
dns_alt_names = ns2,ns2.mydomain.com
use_cached_catalog = false
[agent]
report = true
pluginsync = true
The missing facts ($fqdn
, $operatingsystem
) suggest deeper configuration problems. Implement these fixes:
# On the client machine:
# Ensure proper hostname configuration
hostnamectl set-hostname ns2.mydomain.com
# In /etc/hosts
127.0.0.1 ns2.mydomain.com ns2 localhost
# Then clean and regenerate certs
sudo rm -rf /etc/puppetlabs/puppet/ssl
sudo puppet agent -t --noop
For complex environments, consider implementing an ENC to override node classification:
#!/bin/bash
# Example ENC script for hostname override
CERTNAME=$(puppet config print certname)
case $CERTNAME in
"ns2.mydomain.com")
echo "classes:"
echo " - role::dns::secondary"
echo "environment: production"
;;
*)
echo "classes:"
echo " - role::generic"
echo "environment: development"
;;
esac
When working behind NAT, ensure proper network configuration:
- Enable
report=true
in puppet.conf - Check firewall rules for Puppet port (8140)
- Verify time synchronization (NTP)
- Ensure consistent DNS resolution between client and server
For complete verification, run these diagnostic commands:
puppet config print all | grep -E 'certname|node_name'
facter | grep -E 'fqdn|hostname|ipaddress'
openssl x509 -in /etc/puppetlabs/puppet/ssl/certs/$(hostname).pem -text | grep DNS
When working with Puppet in NAT environments, many administrators encounter node naming conflicts where reverse DNS resolution doesn't match desired Puppet configurations. The fundamental issue manifests when a server's reverse DNS (like office.mydomain.com) differs from its intended Puppet node name (ns2.mydomain.com).
By default, Puppet determines the node name through these steps:
- Checks the
node_name
fact (usuallyfqdn
) - Falls back to reverse DNS resolution
- Uses the
certname
setting as final fallback
The current configuration attempts to force the node name using these puppet.conf
settings:
[main]
certname=ns2.mydomain.com
node_name=cert
While this should work in theory, the syslog output shows the master still processes the node as office.mydomain.com:
Sep 16 22:59:12 support puppetmasterd[2800]: Compiled catalog for office.mydomain.com
Sep 16 22:59:12 support puppetmasterd[2800]: Caching catalog for ns2.mydomain.com
To reliably override reverse DNS naming in NAT environments:
1. Client-Side Configuration
[main]
certname = ns2.mydomain.com
node_name = cert
use_srv_records = false
[agent]
node_name_value = ns2.mydomain.com
2. Server-Side Precedence Rules
In puppet.conf
on the master:
[master]
node_terminus = plain
strict_hostname_checking = false
3. Alternative DNS Configuration
For environments where you control DNS:
# /etc/hosts on the Puppet master
192.168.1.100 ns2.mydomain.com ns2
The reported missing facts ($fqdn, $operatingsystem) typically indicate:
- Facter not running properly
- Network connectivity issues preventing fact collection
- Time synchronization problems
Debug with:
puppet facts find ns2.mydomain.com --render-as json
facter -p
For complex environments, consider an ENC (External Node Classifier) that overrides naming:
#!/bin/bash
# /etc/puppetlabs/code/environments/production/scripts/enc.sh
CERTNAME=$1
REALNAME=$(echo $CERTNAME | sed 's/office./ns2./g')
cat <
Configure in puppet.conf
:
[master]
node_terminus = exec
external_nodes = /etc/puppetlabs/scripts/enc.sh
After making changes:
- Clean certificates:
puppet cert clean office.mydomain.com
- Regenerate facts:
rm -rf /opt/puppetlabs/puppet/cache/facts
- Run test:
puppet agent -t --noop