By Ikuya Yamada and Yoshiyasu Takefuji
Introduction
When a server environment is created using virtualization software or a cloud service, the number of servers tends to increase rapidly. Software installation and configuration are required every time a server is created. Further, synchronizing server configurations requires additional effort such as writing shell scripts.
In this article, we will describe how to build a server environment automatically using a relatively new software tool called Puppet. Although this tool is typically used to manage large-scale server infrastructure (such as a data center or a Web service with a large number of users), it can also be used to manage a small number of servers. However, Puppet is a newly developed tool, and the existing documentation and the articles on Puppet are still somewhat cursory.
Here, we will show you simple examples that you can use to configure common server settings using Puppet without any difficulty. Using Puppet, you can create a new server instantaneously by entering only a few commands. Puppet will also periodically synchronize the configurations of the created servers.
Note that it will be especially useful for configuring and maintaining common security settings including sudo, sshd, and iptables. In this article, we have also described some of our original and simple but powerful common security settings that have actually been used in our server environment.
We have tested all the examples using the CentOS 5 operating system. However, you can apply the described techniques to other Linux distro and other operating systems.
Installing Puppet
Puppet adopts a server-client architecture. Each client periodically communicates with one (or more) master servers and synchronizes the configuration (every half hour by default). So, first you need to prepare at least two server instances; one would be the Puppet master server and the others would be the Puppet client servers.
Now, let us proceed to install Puppet. Fedora EPEL provides the Puppet Yum package. If your servers do not have EPEL, please install it before proceeding:
$ sudo rpm -Uvh http://download.fedora.redhat.com/pub/epel/5/i386/epel-release-5-4.noarch.rpm
Then, install the puppet-server package on the master server that manages the other servers and puppet on the client servers:
On the master server:
$ sudo yum -y install puppet-server $ sudo chkconfig puppetmaster on $ sudo service puppetmaster start |
On the client servers:
$ sudo yum -y install puppet $ sudo chkconfig puppet on $ sudo service puppet start |
In addition, if your master server is placed behind a firewall and you want to use Puppet on servers that are outside the firewall, you need to open TCP port 8140.
A very brief introduction to Puppet
In Puppet, all configurations are described as resources. Resources can be files, software packages, server services, etc. For example, the following file resource represents a very basic /etc/passwd file that is owned by root and has permission settings of ‘644’:
file { '/etc/passwd': owner => root, mode => 644, }
The following configuration installs the openssh-server package, enables the sshd service by default, and ensures that sshd is running:
package { 'openssh-server': ensure => installed, } service { 'sshd': enable => true, ensure => running, require => Package['openssh-server'], }
Now, let’s apply these configurations to your servers. In Puppet, site.pp is a special file that is included by default. If the server configuration is not complex, it might be advantageous to write all the configuration settings in this file. To do so, please paste the above code into your /etc/puppet/manifests/site.pp.
file { '/etc/passwd': owner => root, mode => 644, } package { 'openssh-server': ensure => installed, } service { 'sshd': enable => true, ensure => running, require => Package['openssh-server'], }
Next, you need to register and sign the client servers to the master server.
Please execute the following command on the client servers:
$ sudo puppetd --test --waitforcert 30 --server MASTER_SERVER_ADDRESS |
and run the following command on the master server.
$ sudo puppetca --list (YOUR CLIENT_SERVER_ADDRESS IS DISPLAYED HERE) $ sudo puppetca --sign CLIENT_SERVER_ADDRESS |
Then, back on the client server’s console, you will notice that all the above configuration entries have been applied automatically by Puppet.
Further, you will need to add the following parameter to /etc/puppet/puppet.conf in order to specify the address of the master server to the clients.
[main] server = MASTER_SERVER_ADDRESS
Now, Puppet will automatically synchronize the server configurations every 30 minutes. You can confirm this in /var/log/messages:
$ sudo tail /var/log/messages |
Configuration examples
In this section, we will provide several basic configuration examples. If you want to use them, please paste them into your site.pp.
Add administrative user
Puppet provides a user resource that enables us to manage user accounts. The following configuration adds user admin to your server:
# Add "admin" account user { 'admin': home => '/home/admin', # home directory is /home/admin managehome => true, # manage the home directory by Puppet groups => ['wheel'], # the user belongs to wheel group password => 'PASSWORD_HASH', # hashed password text }
PASSWORD_HASH is a basic password hash, similar to those used in /etc/shadow. You can generate it manually using the following commands:
$ sudo yum -y install ircd-ratbox-mkpasswd $ /usr/bin/ircd-mkpasswd -m -s 'SALT' -p 'PASSWORD' |
[ Standard crypt(3)
password creation is also available without installing any additional software; running, e.g. perl -wle ‘print crypt “PASSWORD”, “SALT”‘ or python -c ‘import crypt; print(crypt.crypt(“PASSWORD”, “SALT”))’ will generate one. — Ben ]
sudo
The following configuration installs the sudo package and modifies sudoers by using augeas to allow users belonging to the wheel group to use sudo:
# Install sudo package package { 'sudo': ensure => installed, # ensure sudo package installed } # Allow users belonging wheel group to use sudo augeas { 'sudowheel': context => '/files/etc/sudoers', # target file is /etc/sudoers changes => [ # allow wheel users to use sudo 'set spec[user = "%wheel"]/user %wheel', 'set spec[user = "%wheel"]/host_group/host ALL', 'set spec[user = "%wheel"]/host_group/command ALL', 'set spec[user = "%wheel"]/host_group/command/runas_user ALL', ] }
SSH
This configuration enables you to install and use sshd on your server. It also changes sshd_config to deny root logins and logins with empty passwords.
# Install openssh-server package package { 'openssh-server': ensure => installed, } # Enable sshd service service { 'sshd': enable => true, # execute sshd on startup ensure => running, # ensure sshd running require => Package['openssh-server'], # require openssh-server before applying this config } # Change sshd configuration augeas { 'sshd_config': context => '/files/etc/ssh/sshd_config', # target file is /etc/ssh/sshd_config notify => Service['sshd'], # restart sshd after applying this config changes => [ # deny root logins and logins with empty passwords 'set PermitRootLogin no', 'set PermitEmptyPasswords no', ], }
iptables
To configure iptables using Puppet, you’ll need to install an external module called puppet-iptables . You need to download and install it from GitHub.
$ cd /tmp $ wget --no-check-certificate "https://github.com/kbarber/puppet-iptables/tarball/master" $ tar xvzf kbarber-puppet-iptables-1.2.0-2-g9deddbb.tar.gz $ sudo mkdir -p /etc/puppet/modules $ sudo mv kbarber-puppet-iptables-9deddbb /etc/puppet/modules/ |
Also, you need to add the following parameters to your /etc/puppet/puppet.conf in both the master server and the client servers:
[main] libdir = /var/lib/puppet/lib [puppetd] pluginsync=true plugindest=/var/lib/puppet/lib
Now, you can use iptables resources. The following is a basic firewall configuration that only accepts packets over existing connections, those from the localhost and the LAN, and those that come in via SSH.
# Allow packets that belong to or related to an existing connection iptables { 'allow established, related': state => ['ESTABLISHED', 'RELATED'], proto => 'all', jump => 'ACCEPT', } # Allow all packets from localhost iptables { 'allow localhost': source => '127.0.0.1', proto => 'all', jump => 'ACCEPT', } # Allow all packets from LAN iptables { 'allow LAN': source => '192.168.0.0/16', proto => 'all', jump => 'ACCEPT', } # Allow all packets to SSH iptables { 'allow ssh': proto => 'tcp', dport => 22, jump => 'ACCEPT', } # Drop all incoming packets by default iptables { 'drop incoming packets': chain => 'INPUT', proto => 'all', jump => 'DROP', }
Further information
If you are interested in Puppet and want to learn further about it, please refer to the official documentation; introduction to Puppet would be a good starting point.
Copyright © 2011, Ikuya Yamada and Yoshiyasu Takefuji. Released under the Open Publication License unless otherwise noted in the body of the article.
Published in Issue 183 of Linux Gazette
Popular Posts:
- None Found
Most of this could be done with cobbler. I try to do as much as possible on cobbler then everything else falls on puppet and func…just an opinion.
Thanks! very good articles
http://linuxbasiccommand.blogspot.com
The Foreman is a good puppet “management” project:
http://theforeman.org/projects/foreman/wiki/Features