Puppet

Managing iptables using puppet

fw

The PuppetLabs firewall is awesome. I implemented it in one of our vCloud Director environments, however I also implemented in a previous company but I totally messed up the implementation until I did it again in the vCloud Director environment. Now I completely see how you should do it, and you should.

The basic crux of it is you should install the PuppetLabs module and have a pre and post firewall module; pre should look like this…

class fw::pre {
  Firewall {
    require => undef,
  }

  # Default firewall rules
  firewall { '000 accept all icmp':
    proto   => 'icmp',
    action  => 'accept',
  }
  firewall { '001 accept all to lo interface':
    proto   => 'all',
    iniface => 'lo',
    action  => 'accept',
  }
  firewall { '002 accept related established rules':
    proto   => 'all',
    state   => ['RELATED', 'ESTABLISHED'],
    action  => 'accept',
  }
  firewall { '003 ssh 22':
    port    => '22',
    proto   => 'tcp',
    action  => 'accept',
  }
}

…. and post should look like this

class fw::post {
  firewall { '999 drop all':
    proto   => 'all',
    action  => 'drop',
    before  => undef,
  }
}

What this does is set your default rules so that you can apply the pre and post fw modules in your site.pp, or other manifest file, as follows:

class { ['server_fw::pre', 'server_fw::post']: }

Now here is the clever bit. When you create say an apache module, within the module, you then assign the applicable iptables firewall rules required when the apache module gets installed. For example:

class apache (
  ...
  firewall { '100 allow http and https access':
    port   => [80, 443],
    proto  => tcp,
    action => accept,
  ...
  }

What this does is applies by default all the rules in fw::pre and fw::post and any specific rules which are contained within the module. Notice I have used rule number 100 for the apache firewall config. This means the iptables rules for apache get applied in between the pre (000 – 003) and the post (999) rules. Perfect! Never have to administer the firewall again 🙂

For further info, read up on the PuppetLabs firewall module – https://forge.puppetlabs.com/puppetlabs/firewall – that’s what I should have done in the first place.

Advertisements

Cloudstack deploying cloudstack

Image

I was talking at the Cloudstack European Meet up the other day about getting Cloudstack to deploy Cloudstack.

Well its more than that – I was talking about the concepts rather than what I was doing, as really, Cloudstack deploying Cloudstack is a bit of a gimick.

Here is my github link to the project
https://github.com/oliverleach/cloudstack-puppet

However, I thought I would include some scribble on how the project works in case anyone is interested:

Cloudstack 4.0.1 deploy

This project enables a running Cloudstack instance 3.x and above to deploy Cloudstack 4.0.1 instances. This could be to demo Cloudstack 4.0.1 or used for testing purposes, by easily spinning up Cloudstack 4.0.1 instances. It could also be used to provision private clouds using Cloudstack.

How to use this project

The python script and puppet manifests in this repo deploys cloudstack 4.0.1 using Puppet and the Cloudstack API. For this to work, you need to use the python scripts and 2 puppet templates. One template is the puppet-master, and one template is the puppet-agent.

You need to configure the python parameters in the puppet-deploy.py script as per your environment. This includes:

1 – your API key
2 – your secret key
3 – your service offering
4 – your Cloudstack zone ID
5 – your network ID of your user account
6 – The Cloudstack provisioning host IP and port
7 – The Cloudstack protocol used (http or https)

You will also need your 2 template IDs for the puppet master and puppet agent

These templates can be downloaded using the following link:

Puppet Agent

https://dl.dropbox.com/u/79905244/puppet-agent.7z

Puppet Master

https://dl.dropbox.com/u/79905244/puppet-master.7z

Both templates are running CentOS 6.4 64-bit. The puppet master is configured as a puppet-ca, a puppet server and a puppet agent. The puppet agent has the puppet agent installed and runs a userdata.rb script on startup. See the rc.local file for further information.

Once the templates are unzipped and uploaded in to your provisioning Cloudstack instance, update the puppet-deploy.py script with the template IDs.

To run the python scripts, use an interpreter like idle, open and run the puppet-deploy.py file, or simply run from the command line where an instance of python is installed; e.g. python puppet-deploy.py. This has been tested against python 2.7.3.

The git repo holds the puppet manifests which are included in the puppet-master template.
They are just for reference.

This project is just for fun, could be better written and I hold no responsibility if you use the project. You are allowed to do so.

Puppet manifests for cloudstack and co.

Here are some of my puppet manifests for Cloudstack and co. You can also find more information here:

https://github.com/oliverleach/cloudstack-puppet

I also recently did a presentation at the Cloudstack European meetup in London on the 11th April about deploying applications using puppet and Cloudstack. The talk was well received so I thought I would jot down the manifests that I wrote as part of the talk.

Here is the Cloudstack manifest:


# Class cloudstack
#
# This class installs cloudstack
#
# Author: Oliver Leach
# Date : 18th March 2013
#
# Actions:
# Installs the cloudstakc package
#
# This includes, the cloudstack-client, mysql-server and any install commands
#
# Currently the clodustack class is monlithic for demo purposes.
#
# Requires:
# Centos - other operating systems are not supported by this manifest
#
# Sample Usage:
# include cloudstack
#

class cloudstack ($mysql_password) {

case $::operatingsystem {

'centos': {
$supported = true
}
}

if ($supported == true) {

yumrepo { 'cloudstack':
baseurl  => "http://cloudstack.apt-get.eu/rhel/4.0/",
descr    => "Cloudstack 4.0.1 yum repo",
enabled  => 1,
gpgcheck => 0,
}

package { "cloud-client":
ensure   => "installed",
require  => Yumrepo["cloudstack"],
}

exec { "cloud-setup" :
command  => "/usr/bin/cloud-setup-databases cloud:cloud@localhost --deploy-as=root:${mysql_password}; /bin/sleep 3 ; /usr/bin/cloud-setup-management ; /bin/sleep 3 ;
/usr/bin/cloud-setup-databases cloud:cloud@localhost --deploy-as=root:${mysql_password} ; /bin/sleep 3 ; /usr/bin/cloud-setup-management",

creates  => '/var/lib/mysql/cloud',
require  => Package["cloud-client"],
}

service { "cloud-management":
ensure   => "running",
enable   => "true",
require  => Exec["cloud-setup"],
}
}
}

MySQL server manifest


# Class myslqserver
#
# This class installs cloudstack
#
# Author: Oliver Leach
# Date : 20th March 2013
#
# Actions:
# Installs the mysql server package
#
# This includes, the mysql-server package
#
# Requires:
# Centos - other operating systems are not supported by this manifest
#
# Sample Usage:
# include mysql::server
#

class mysql::server ($mysql_password) {

case $::operatingsystem {
"centos": {
$supported = true
}
}

if ($supported == true) {

file { "flag-files" :

ensure     => directory,
path       => "/var/lib/puppet/flags/",
owner      => root,
group      => root,
mode       => "0644",
}

package { "mysql-server":
ensure     => installed,
require    => File["flag-files"],
}

file { "/etc/my.cnf" :
owner      => "root",
group      => "root",
source     => "puppet:///modules/mysql/my.cnf",
require    => Package["mysql-server"],
}

service { "mysqld" :
enable     => true,
ensure     => running,
require    => File["/etc/my.cnf"],
}

$mysql_server_exec_1 => "0000000000001"
$mysql_server_file_1 => "/var/lib/puppet/flags/mysql_server_exec_1"

exec { "restart-mysqld" :
command    => "/sbin/service mysqld restart ; echo \"$mysql_server_exec_1\" ; \"$mysql_server_file_1\"",
unless     => "/usr/bin/test \"`/bin/cat $mysql_server_file_1; /dev/null`\" = \"$mysql_server_exec_1\"",
require    => Service["mysqld"],
}

exec { "set-mysql-password" :
unless     => "/usr/bin/mysqladmin -uroot -p${mysql_password} status",
command    => "/usr/bin/mysqladmin -uroot password ${mysql_password}",
require    => Exec["restart-mysqld"],
}

$mysql_server_exec_2 => "0000000000001"
$mysql_server_file_2 => "/var/lib/puppet/flags/mysql_server_exec_2"

exec { "remove-test-dbs" :
command    => "/usr/bin/mysql -u root -p${mysql_password} -e \"DELETE FROM mysql.db WHERE Db='test' OR Db='test%';\"; echo \"$mysql_server_exec_2\" >> "$mysql_server_file_2\"",

unless     => "/usr/bin/test \"`/bin/cat $mysql_server_file_2 /dev/null`\" = \"$mysql_server_exec_2\"",
require    => Exec["set-mysql-password"],
}

$mysql_server_exec_3 => "0000000000003"
$mysql_server_file_3 => "/var/lib/puppet/flags/mysql_server_exec_3"

exec { "remove-remote-root-access" :
command     => "/usr/bin/mysql -u root -p${mysql_password} -e \"DELETE FROM mysql.user WHERE User='root' AND Host NOT IN ('localhost', '127.0.0.1', '::1'); \" echo \"$mysql_server_exec_3\"; \ "$mysql_server_file_3\"",
unless      => "/usr/bin/test \"`/bin/cat $mysql_server_file_3 /dev/null`\" = \"$mysql_server_exec_3\"",
require     => Exec["set-mysql-password"],
}
}
}

Apache manifest


class apache {

$snat_ip   = $snat_ipaddress

case $operatingsystem {
'CentOS', 'RedHat' : {
$supported = true
}
}

if ($supported == true) {

file { 'httpd_conf_d' :
ensure     => directory,
path       => '/etc/httpd/conf.d/',
recurse    => true,
purge      => true,
force      => true,
owner      => "root",
group      => "root",
mode       => 0644,
require    => Package['httpd'],
}

file { 'cloudstack_conf' :

path       => '/etc/httpd/conf.d/cloudstack.conf',
owner      => root,
group      => root,
mode       => '0644',
content    => template('apache/cloudstack.conf.erb'),
require    => File['httpd_conf_d'],
}

package { 'httpd' :
ensure     => present,
}

package { 'mod_ssl' :
ensure     => present,
}

service { 'httpd' :
ensure     => 'running',
enable     => true,
require    => File['cloudstack_conf'],
}
}
}

and the ERB template:


LoadModule ssl_module modules/mod_ssl.so

NameVirtualHost *:80

ServerName
DocumentRoot /var/www/html/
Redirect permanent / https:///client

Listen 443
NameVirtualHost *:443

SSLEngine On
#SSLCertificateFile /var/lib/puppet/ssl/certs/ca.pem
#SSLCertificateKeyFile /var/lib/puppet/ssl/certs/cert001.pem

SSLCertificateFile /etc/pki/tls/certs/localhost.crt
SSLCertificateKeyFile /etc/pki/tls/private/localhost.key

RewriteEngine On
ProxyRequests On
ProxyVia On

Order deny,allow
Deny from all
Allow from all

Redirect permanent / /client

ProxyPass /client http://localhost:8080/client
ProxyPassReverse /client http://localhost:8080/client

And the iptables manifest


class iptables {

$ipv4_file        => $operatingsystem ? {
"debian"          => '/etc/iptables/rules.v4',
/(RedHat|CentOS)/ => '/etc/sysconfig/iptables',
}

exec { "purge default firewall":
command     => "/sbin/iptables -F && /sbin/iptables-save >

$ipv4_file /sbin/service iptables restart",
onlyif      => "/usr/bin/test `/bin/grep \"Firewall configuration

written by\" $ipv4_file | /usr/bin/wc -l` -gt 0",
user        => 'root',
}

/* Make the firewall persistent */
exec { "persist-firewall":
command     => "/bin/echo \"# This file is managed by puppet. Do not modify manually.\" $ipv4_file /sbin/iptables-save $ipv4_file",
refreshonly => true,
user        => 'root',
}

/* purge anything not managed by puppet */
resources { 'firewall':
purge      => true,
}

firewall { '000 INPUT allow related and established':
state      => ['RELATED', 'ESTABLISHED'],
action     => 'accept',
proto      => 'all',
}

firewall { "001 accept all icmp requests":
proto      => 'icmp',
action     => 'accept',
}

firewall { '002 INPUT allow loopback':
iniface    => 'lo',
chain      => 'INPUT',
action     => 'accept',
}

firewall { '100 allow ssh':
state      => ['NEW'],
dport      => '22',
proto      => 'tcp',
action     => 'accept',
}
firewall { '100 allow port 80':
state      => ['NEW'],
dport      => '80',
proto      => 'tcp',
action     => 'accept',
}
firewall { '100 allow port 443':
state      => ['NEW'],
dport      => '443',
proto      => 'tcp',
action     => 'accept',
}
firewall { '100 allow 9090':
state      => ['NEW'],
dport      => '9090',
proto      => 'tcp',
action     => 'accept',
}

firewall { '100 allow 8250':
state      => ['NEW'],
dport      => '8250',
proto      => 'tcp',
action     => 'accept',
}

firewall { '100 allow 7080':
state      => ['NEW'],
dport      => '7080',
proto      => 'tcp',
action     => 'accept',
}

firewall { '100 allow 8080':
state      => ['NEW'],
dport      => '8080',
proto      => 'tcp',
action     => 'accept',
}

firewall { "998 deny all other requests":
action     => 'reject',
proto      => 'all',
reject     => 'icmp-host-prohibited',
}

firewall { "999 deny all other requests":
chain     => 'FORWARD',
action    => 'reject',
proto     => 'all',
reject    => 'icmp-host-prohibited',
}
}

Running multiple puppet masters

puppet_multi_master

When running multiple puppet masters, you need to dedicate a single puppet master to be your CA server. If you are adding additional puppet master, there is some key config that needs to be set which disables the puppet CA functionality from running on the puppet master. Additionally, you need to set up a proxy pass to forward certificate requests to the puppet CA server. This is detailed below.

1. Install puppet agent and puppet master

Install the puppet and latest epel repo – note the epel repo below is now out of date.

rpm -Uvh http://dl.fedoraproject.org/pub/epel/6/x86_64/epel-release-6-8.noarch.rpm
rpm -Uvh http://yum.puppetlabs.com/el/6/products/x86_64/puppetlabs-release-6-6.noarch.rpm

Install the puppet agent and puppet master

yum install puppet puppet-server -y

2. Edit the puppet.conf file and turn off the puppet master from acting as a CA

vi /etc/puppet/puppet.conf
[master]

ca = false
ca_server = puppet-CA-server.domain.net

3. Start the agent and create and sign the puppet master cert

• On the additional puppet master

puppet agent --test

• On puppet CA server

puppet cert sign --all

• On the puppet master

puppet agent --test

4. Configure iptables

iptables -I INPUT 5 -s 10.10.10.0/24 -m tcp -p tcp --dport 8140 -j ACCEPT

service iptables save
service iptables restart

Note: If you are adding multiple bridges, assign the correct iptables rules to each vnic adapter and the the applicable source network address.

5. Install the required packages for the puppet master

yum install sudo mod_ssl rubygem-passenger 
mod_passenger policycoreutils-python rsync -y

6. Copy the example puppet virtual host config to /etc/httpd/conf.d/

cp /usr/share/puppet/ext/rack/files/apache2.conf 
/etc/httpd/conf.d/puppet-master.conf

7. Edit the puppet-master.conf file and update accordingly

# you probably want to tune these settings
PassengerHighPerformance on
PassengerMaxPoolSize 12
PassengerPoolIdleTime 1500
# PassengerMaxRequests 1000
PassengerStatThrottleRate 120
RackAutoDetect Off
RailsAutoDetect Off

Listen 8140

SSLProxyEngine On
ProxyPassMatch ^/([^/]+/certificate.*)$ https://puppet.myorg.net:8140/$1

SSLEngine on
SSLProtocol -ALL +SSLv3 +TLSv1
SSLCipherSuite ALL:!ADH:RC4+RSA:+HIGH:+MEDIUM:-LOW:-SSLv2:-EXP

SSLCertificateFile /var/lib/puppet/ssl/certs/puppet-server2.myorg.net.pem
SSLCertificateKeyFile /var/lib/puppet/ssl/private_keys/puppet-server2.myorg.net.pem
SSLCertificateChainFile /var/lib/puppet/ssl/certs/ca.pem
SSLCACertificateFile /var/lib/puppet/ssl/certs/ca.pem

# If Apache complains about invalid signatures on the CRL, you can try disabling
# CRL checking by commenting the next line, but this is not recommended.
SSLCARevocationFile /var/lib/puppet/ssl/crl.pem
SSLVerifyClient optional
SSLVerifyDepth 1

# The `ExportCertData` option is needed for agent certificate expiration warnings
SSLOptions +StdEnvVars +ExportCertData

# This header needs to be set if using a loadbalancer or proxy
RequestHeader unset X-Forwarded-For

RequestHeader set X-SSL-Subject %{SSL_CLIENT_S_DN}e
RequestHeader set X-Client-DN %{SSL_CLIENT_S_DN}e
RequestHeader set X-Client-Verify %{SSL_CLIENT_VERIFY}e

DocumentRoot /usr/share/puppet/rack/puppetmaster/public/
RackBaseURI /

Options None
AllowOverride None
Order allow,deny
allow from all

Note: We are using the ProxyPassMatch. This is matching any inbound requests on /certificate and redirecting them to the puppet CA server. Change the config accordingly.

Note: As the puppet master you are building is not a CA server, note the SSLCertificateChainFile, SSLCACertificateFile, SSLCARevocationFile paths are different to a puppet master running the CA server. This reflects where the CA certs reside when the PM is not a CA server itself.

8. Create rack directories

mkdir -p /usr/share/puppet/rack/puppetmaster/{public,tmp}

9. Copy config.ru rack file to rack web directory

cp /usr/share/puppet/ext/rack/files/config.ru /usr/share/puppet/rack/puppetmaster/

10. Change ownership of config.ru rack file to puppet

chown puppet:puppet /usr/share/puppet/rack/puppetmaster/config.ru

11. Set httpd to start on boot and puppet master to not start

chkconfig httpd on
chkconfig puppetmaster off

12. Set up a puppet master to connect to puppetdb

• Run the following on each of your puppet masters:

sudo puppet resource package puppetdb-terminus ensure=latest

• Add this to /etc/puppet/puppetdb.conf. Note: you may have to create this file.

[main]

server =
port = 8081

• Add this to /etc/puppet/puppet.conf

[master]

storeconfigs = true
storeconfigs_backend = puppetdb

• Add this to /etc/puppet/routes.yaml. Note: you may have to create this file.

master:
facts:
terminus: puppetdb
cache: yaml

13. Enable puppet-dashboard reports on the puppet master

• Add to each puppet master in the puppet environment in /etc/puppet/puppet.conf:

[master]

reports = store, https, puppet_dashboard
reporturl = https:///reports/upload

14 Copy the following script to the puppet dashboard server and all the puppet masters

• Create /usr/lib/ruby/site_ruby/1.8/puppet/reports/https.rb with the following code

require 'puppet'
require 'net/http'
require 'net/https'
require 'uri'

Puppet::Reports.register_report(:https) do

desc <<-DESC
Send report information via HTTPS to the `reporturl`. Each host sends
its report as a YAML dump and this sends this YAML to a client via HTTPS POST.
The YAML is the `report` parameter of the request."
DESC

def process
url = URI.parse(Puppet[:reporturl].to_s)
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE

req = Net::HTTP::Post.new(url.path)
req.body = self.to_yaml
req.content_type = "application/x-yaml"

http.start do |http|
response = http.request(req)
unless response.code == "200"
Puppet.err "Unable to submit report to #{Puppet[:reporturl].to_s} [#{response.code}] #{response.msg}"
end
end

end
end

• Remove the following file from the puppet dashboard and puppet masters

/usr/lib/ruby/site_ruby/1.8/puppet/reports/http.rb

rm -f /usr/lib/ruby/site_ruby/1.8/puppet/reports/http.rb

15 Edit the auth.conf file on each puppet master so inventory can pick up facts.

vim /etc/puppet/auth.conf

path /facts
method find
auth any
allow *

path /inventory
auth any
method search, find
allow dashboard

# this one is not strictly necessary, but it has the merit
# of showing the default policy, which is deny everything else

path /
auth any

Note: The config for /facts and /inventory must go above the config for `path /` – otherwise you may get an access forbidden 404 error message when running the inventory service on puppet-dashboard.

Installing a puppet master and ca server

puppet

Here are my install notes on how I set up my puppet server. Note, with EPEL 6.8, passenger is available via yum. This is a much better way to install passenger, rather than using ruby gems.

1 – Install EPEL and puppet repos

rpm -Uvh http://dl.fedoraproject.org/pub/epel/6/x86_64/epel-release-6-8.noarch.rpm
rpm -ivh http://yum.puppetlabs.com/el/6/products/x86_64/puppetlabs-release-6-6.noarch.rpm

2- Install required packages

yum install puppet-server puppet sudo mod_ssl rubygem-passenger
mod_passenger policycoreutils-python vim rsync -y

3. Create a puppet CA cert

puppet master --no-daemonize --verbose

ctrl+c to break out of puppet master deamon once the puppet daemon is running when you see the following message

Notice: Starting Puppet master version 3.x.x

4. Copy the example puppet virtual host config to /etc/httpd/conf.d/

cp /usr/share/puppet/ext/rack/files/apache2.conf
/etc/httpd/conf.d/puppet-master.conf

5. Edit the puppet-master.conf file and update accordingly

# you probably want to tune these settings

PassengerHighPerformance on
PassengerMaxPoolSize 12
PassengerPoolIdleTime 1500

PassengerMaxRequests 1000
PassengerStatThrottleRate 120
RackAutoDetect Off
RailsAutoDetect Off

Listen 8140

SSLEngine on
SSLProtocol -ALL +SSLv3 +TLSv1
SSLCipherSuite ALL:!ADH:RC4+RSA:+HIGH:+MEDIUM:-LOW:-SSLv2:-EXP
SSLCertificateFile /var/lib/puppet/ssl/certs/puppet-server.com.pem
SSLCertificateKeyFile /var/lib/puppet/ssl/private_keys/puppet-server.com.pem
SSLCertificateChainFile /var/lib/puppet/ssl/ca/ca_crt.pem
SSLCACertificateFile /var/lib/puppet/ssl/ca/ca_crt.pem

# If Apache complains about invalid signatures on the CRL, you can try disabling
# CRL checking by commenting the next line, but this is not recommended.

SSLCARevocationFile /var/lib/puppet/ssl/ca/ca_crl.pem
SSLVerifyClient optional
SSLVerifyDepth 1

# The `ExportCertData` option is needed for agent certificate expiration warnings

SSLOptions +StdEnvVars +ExportCertData

# This header needs to be set if using a loadbalancer or proxy
RequestHeader unset X-Forwarded-For
RequestHeader set X-SSL-Subject %{SSL_CLIENT_S_DN}e
RequestHeader set X-Client-DN %{SSL_CLIENT_S_DN}e
RequestHeader set X-Client-Verify %{SSL_CLIENT_VERIFY}e

DocumentRoot /usr/share/puppet/rack/puppetmaster/public/
RackBaseURI /

Options None
AllowOverride None
Order allow,deny
allow from all

6. Create rack directories

mkdir -p /usr/share/puppet/rack/puppetmaster/{public,tmp}

7. Copy config.ru rack file to rack web directory

cp /usr/share/puppet/ext/rack/files/config.ru
/usr/share/puppet/rack/puppetmaster/

8. Change ownership of config.ru rack file to puppet

chown puppet:puppet /usr/share/puppet/rack/puppetmaster/config.ru

9. Set httpd to start on boot and puppet master to not start

chkconfig httpd on
chkconfig puppetmaster off

10. IPTABLES configuration

This is environment specific depending on the bridges you need to create to let the puppet master communicate to its various networks. Port 8140 needs to be open on the puppet master for each interface you have added, specifying the source networks and interface adapter as applicable. Below is an example taken from the UK Cressex LAB puppet master deployment. All IPTABLES information is covered later in the document under the configured puppet environments section.

Here is the following content of the /etc/sysconfig/iptables

# Generated by iptables-save v1.4.

*filter
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [24:2304]
-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
-A INPUT -p icmp -j ACCEPT
-A INPUT -i lo -j ACCEPT
-A INPUT -s 10.10.10.0/24 -i eth0 -p tcp -m state --state NEW -m tcp --dport 22 -j ACCEPT
-A INPUT -s 10.10.10.0/24 -i eth0 -p tcp -m tcp --dport 8140 -m state --state NEW,ESTABLISHED -j ACCEPT
-A INPUT -s 10.10.11.0/24 -i eth1 -p tcp -m tcp --dport 8140 -m state --state NEW,ESTABLISHED -j ACCEPT
-A INPUT -s 10.10.12.0/24 -i eth2 -p tcp -m tcp --dport 8140 -m state --state NEW,ESTABLISHED -j ACCEPT
-A INPUT -s 10.10.13.0/24 -i eth3 -p tcp -m tcp --dport 8140 -m state --state NEW,ESTABLISHED -j ACCEPT
-A INPUT -s 10.10.14.0/24 -i eth4 -p tcp -m tcp --dport 8140 -m state --state NEW,ESTABLISHED -j ACCEPT
-A INPUT -j REJECT --reject-with icmp-host-prohibited
-A FORWARD -j REJECT --reject-with icmp-host-prohibited

COMMIT

You can add these rules following the example command below

iptables -I INPUT 6 -i eth1 -p tcp -s 10.10.10.0/24 --dport 8140 -m state --state NEW,ESTABLISHED -j ACCEPT

service iptables save

or by editing the /etc/sysconfig/iptables and running iptables-save and service iptables restart

11. Start apache

service httpd start

12. check that httpd is running and test connectivity

https://puppet-server1.tcl-oob.net:8140/

If everything is working correctly, you should see

The environment must be purely alphanumeric, not ”

Hope this helps some people. There are some more blogs I have written concerning how to install puppet DB, puppet dashboard and adding additional puppet masters.

Gitlab, Jenkins and puppet playing together

jenkinsLogo1

Jenkins in one of my favourite open source tools. It must also be one of the most flexible

You can set up Jenkins to monitor your Gitlab project for any changes. If Jenkins sees any commits to the master repo, Jenkins will execute a build script and run any customised scripts. Here is how to set this up.

  • Set up a project in Gitlab. This will be your git repo.
  • Create a your git repo using a git client on a linux box of your choice.
  • Configure Jenkins job to poll the git repo and to run a build script if there are any changes.

Here is how to configure the Jenkins server to poll the git repo.

Install the gitlab plugin to Jenkins

https://wiki.jenkins-ci.org/display/JENKINS/Gitlab+Hook+Plugin

Set up a Jenkins job and specify the following under source code management

jenkins_1

note: The repository URL can be obtained from gitlab as shown below

jenkins_2

Setting up build triggers

Under build triggers, select the Poll SCM and set a Schedule. The schedule is in cron format and be set as desired. Here we have set Jenkins to poll the git repo every 5 minutes for changes.

Note: Once the job is setup, you can click on the jenkins_4

Here you will see the git polling working as shown below:

jenkins_5

SSH keys and sudo access

We will need to set up ssh keys and sudo access for the jenkins_admin user which is used to log on to the puppet masters to sycnronise the manifests and modules. To set up the keys, run the following commands on the jenkins box.

1 – Log in as jenkins_admin@jenkins on the jenkins server

2 – Run the following command to drop into the jenkins user

sudo - s -H -u jenkins

3 – Run the following to set up the ssh key pair

$ cd ~/.ssh/
$ ssh-sopy-id -i id_rsa.pub jenkins_admin@puppet-server

note: # where puppet-server is the puppet master you need to sync the manifests on

4- Configure sudo on the puppet-master so Jenkins_admin is not prompted for the password. Note you can use a manifest to configure sudo via puppet.

on the puppet-server (as root)

sudo visudo

...

jenkins_admin ALL= NOPASSWD:/usr/bin/rsync

Make sure you do this process for each puppet-server you wish to configure sudo and ssh keys for

Configure the Jenkins build job

Configure the Jenkins build job as follows:

# Specifies a AD user who has sudo rights on the puppet server to run the rsync
commands without requiring a password

USER=jenkins_admin

# List of puppet masters that will receive manifests and modules

for HOST in 'puppet-server1t' 'puppet-server2' 'puppet-server3'

do

# rsync command to sync changes from gitlab repo

rsync -e "ssh -t -l jenkins_admin" --rsync-path='sudo rsync' -avz --stats
--progress --human-readable --exclude .git --exclude README $WORKSPACE/
$USER@$HOST:/etc/puppet/

done

This completes the setup.