Automating virtual server administration using Puppet
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 coniguration 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 Linux 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 https://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 ssh 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.
Share |
Talkback: Discuss this article with The Answer Gang
Ikuya Yamada
Ikuya Yamada is an entrepreneur and an experienced software engineer. Currently, he is the founder and the CTO of Studio Ousia Inc., a software R&D company founded in 2007 in Tokyo. He is also a senior visiting researcher at the Keio Research Institute at SFC from 2010. Prior to Studio Ousia, he was the CTO of a listed Japanese software company named Fractalist Inc. and previously the founder and the CEO of a software R&D company called Newrong Inc., which was acquired by Fractalist Inc. in 2005. He obtained his B.S. (2006) and M.S. (2010) from Keio University.
Yoshiyasu Takefuji
Yoshiyasu Takefuji was heavily involved in developing a unix based color workstation in 1983 at University of South Florida. Recently he has been monitoring three Linux servers to see the behavior of DOS attacks. He is a chair of SecurityExpo in Japan since 2004 and also a chair of OECD TrustE security product evaluation committee chair in Japan, and advisor of Japan Network Security Association and CMU in Japan.