How to Build a Puppet Master‑Client Environment and Automate SSH Port Changes
This guide walks through Puppet's architecture, sets up a four‑node master‑client environment, configures NTP and certificates, creates an SSH module to change the SSH port, and demonstrates both client‑pull and server‑push synchronization methods for automated Linux configuration.
Puppet Working Principle
Administrators focus on the desired state while Puppet handles implementation details. Puppet can run on a single machine or in a client‑server (C/S) model; large deployments typically use the C/S model where the client runs
puppet agentand the server runs
puppetmaster. The workflow is illustrated below.
Environment
A four‑server topology is used to simulate the Puppet environment.
Server inventory is shown below.
Experiment Steps
1. Set Up Puppet Master
(1) Configure hostnames and /etc/hosts:
<code>[root@localhost ~]# vim /etc/hostname
master.test.cn
[root@localhost ~]# vim /etc/hosts
192.168.126.138 master.test.cn
192.168.126.148 client01.test.cn
192.168.126.158 client02.test.cn</code>(2) Synchronize time using NTP (required for SSL certificates).
Install NTP server:
<code>[root@localhost ~]# yum install ntp -y
[root@localhost ~]# vim /etc/ntp.conf
server 127.127.1.0 # local time source
fudge 127.127.1.0 stratum 8</code>Start and enable NTP service:
<code>[root@localhost ~]# systemctl stop firewalld.service
[root@localhost ~]# systemctl disable firewalld.service
[root@localhost ~]# setenforce 0
[root@localhost ~]# systemctl start ntpd.service
[root@localhost ~]# systemctl enable ntpd.service
[root@localhost ~]# ntpstat</code>Configure the master as an NTP client:
<code>[root@master ~]# yum install ntpdate -y
[root@master ~]# ntpdate 192.168.126.159</code>Install Puppet server and its dependencies:
<code>[root@master ~]# yum install epel-release -y
[root@master ~]# yum install puppet-server -y</code>Start and enable the Puppet master service:
<code>[root@master ~]# systemctl stop firewalld.service
[root@master ~]# systemctl disable firewalld.service
[root@master ~]# setenforce 0
[root@master ~]# systemctl start puppetmaster.service
[root@master ~]# systemctl enable puppetmaster.service</code>2. Set Up Puppet Clients (client01 and client02)
Verify DNS resolution to the master:
<code>[root@client01 ~]# ping master.test.cn</code>Synchronize time on each client (same NTP steps as the master).
Install Puppet client:
<code>[root@client01 ~]# yum install epel-release -y
[root@client01 ~]# yum install puppet -y</code>Edit
/etc/puppet/puppet.confto point to the master:
<code>[root@client01 ~]# vim /etc/puppet/puppet.conf
[main]
logdir = /var/log/puppet
rundir = /var/run/puppet
ssldir = $vardir/ssl
server = master.test.cn</code>Register the clients with the master:
<code>[root@client01 ~]# puppet agent --server=master.test.cn --no-daemonize --verbose</code>On the master, list pending certificates and sign them:
<code>[root@master ~]# puppet cert --list
[root@master ~]# puppet cert sign --all</code>3. Configuration Example – Changing SSH Port
Create an
sshmodule with
manifests,
templates, and
filesdirectories.
<code>[root@master ~]# cd /etc/puppet/
[root@master puppet]# mkdir -p modules/ssh/{manifests,templates,files}
[root@master puppet]# mkdir manifests/nodes
[root@master puppet]# mkdir modules/ssh/files/ssh
[root@master puppet]# chown -R puppet modules/</code>Define module classes:
install.ppinstalls the
opensshpackage.
config.ppmanages
/etc/ssh/sshd_configvia
puppet://$puppetserver/modules/ssh/ssh/sshd_config.
service.ppensures the
sshdservice is running and enabled.
init.ppincludes the three classes.
<code># install.pp
class ssh::install {
package { "openssh": ensure => present }
}
# config.pp
class ssh::config {
file { "/etc/ssh/sshd_config":
ensure => present,
owner => "root",
group => "root",
mode => "0600",
source => "puppet://$puppetserver/modules/ssh/ssh/sshd_config",
require => Class["ssh::install"],
notify => Class["ssh::service"]
}
}
# service.pp
class ssh::service {
service { "sshd":
ensure => running,
hasstatus => true,
hasrestart => true,
enable => true,
require => Class["ssh::config"]
}
}
# init.pp
class ssh {
include ssh::install, ssh::config, ssh::service
}
</code>Place the desired
sshd_config(changing
Port 22to
Port 9922) in
modules/ssh/files/ssh/sshd_configand set proper ownership.
<code>[root@master puppet]# vim /etc/puppet/modules/ssh/files/ssh/sshd_config
Port 9922</code>Define node manifests to include the
sshclass:
<code>[root@master puppet]# vim /etc/puppet/manifests/nodes/ssh.pp
node 'client01.test.cn' { include ssh }
node 'client02.test.cn' { include ssh }
</code>Import the node file in
site.pp:
<code>[root@master puppet]# vim /etc/puppet/manifests/site.pp
import "nodes/ssh.pp"
</code>Restart the Puppet master to apply changes:
<code>[root@master puppet]# systemctl restart puppetmaster.service</code>4. Apply Changes
Client‑pull method: run
puppet agent -ton each client; the modified
sshd_configis deployed and the SSH service restarts on port 9922.
Server‑push method (large scale): enable listening on the client (
listen = truein
/etc/puppet/puppet.conf) and allow pushes in
/etc/puppet/auth.conf. Then trigger a push from the master:
<code>[root@master puppet]# puppet kick client02.test.cn</code>Verify the new port on both clients with
netstatand by checking the configuration file.
Author: 何以重见 Source: https://blog.51cto.com/13642258/2155525
Efficient Ops
This public account is maintained by Xiaotianguo and friends, regularly publishing widely-read original technical articles. We focus on operations transformation and accompany you throughout your operations career, growing together happily.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.