Mar 192011
 

puppetArticle wrote by

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

[amazon_enhanced asin=”1430210591″ price=”All” background_color=”332610″ link_color=”FFFFFF” text_color=”D4CE99″ /]
[amazon_enhanced asin=”B001FOPV90″ price=”All” background_color=”332610″ link_color=”FFFFFF” text_color=”D4CE99″ /]

Popular Posts:

Flattr this!

  3 Responses to “Automating virtual server administration using Puppet”

  1. 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.

  2. The Foreman is a good puppet “management” project:

    http://theforeman.org/projects/foreman/wiki/Features

 Leave a Reply

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

(required)

(required)

*