Welcome to the Open Source Puppet Firewall Quick Start Guide. This document provides instructions for getting started managing firewall rules with Puppet.
With a firewall, admins define a set of policies (also known as firewall rules) that consist of things like application ports (TCP/UDP), network ports, IP addresses, and an accept/deny statement. These rules are applied in a “top-to-bottom” approach. For example, when a service, say SSH, attempts to access resources on the other side of a firewall, the firewall applies a list of rules to determine if or how SSH communications are handled. If a rule allowing SSH access can’t be found, the firewall will deny access to that SSH attempt.
To best manage such rules with Puppet, you want to divide these rules into pre and post groups to ensure Puppet checks firewall rules in the correct order.
Using this guide, you will learn how to do the following tasks:
- Install the puppetlabs-firewall module.
- Write a simple module to define the firewall rules for your Puppet-managed infrastructure.
- Add the firewall module to the main manifest.
- Enforce the desired state of the
my_firewallclass.
Before starting this walk-through, complete the previous exercises in the essential configuration tasks. Log in as root or administrator on your nodes.
Prerequisites: This guide assumes you’ve already installed Puppet, and have installed at least one *nix agent.
You should still be logged in as root or administrator on your nodes.
Install the puppetlabs-firewall module
The firewall module, available on the Puppet Forge, introduces the firewall resource, which is used to manage and configure firewall rules from with Puppet. Learn more about the module by visiting http://forge.puppet.com/puppetlabs/firewall.
To install the firewall module:
From the Puppet master, run puppet module install puppetlabs-firewall.
You should see output similar to the following:
Preparing to install into /etc/puppetlabs/puppet/environments/production/modules ...
Notice: Downloading from https://forgeapi.puppetlabs.com ...
Notice: Installing -- do not interrupt ...
/etc/puppetlabs/puppet/environments/production/modules
└── puppetlabs-firewall (v1.6.0)
That’s it! You’ve just installed the firewall module.
Write the my_firewall module
Some modules can be large, complex, and require a significant amount of trial and error. This module, however, will be a very simple module to write. It contains just three classes.
A quick note about module directories
By default, Puppet keeps modules in an environment’s
modulepath, which for the production environment defaults to/etc/puppetlabs/code/environments/production/modules. This includes modules that Puppet installs, those that you download from the Forge, and those you write yourself.Note: Puppet also creates another module directory:
/opt/puppetlabs/puppet/modules. Don’t modify or add anything in this directory, including modules of your own.There are plenty of resources about modules and the creation of modules that you can reference. Check out Module Fundamentals, the Beginner’s Guide to Modules, and the Puppet Forge.
Modules are directory trees. For this task, you’ll create the following files:
my_firewall/(the module name)manifests/pre.pppost.pp
To write the my_firewall module:
-
From the command line on the Puppet master, navigate to the modules directory:
cd /etc/puppetlabs/code/environments/production/modules. -
Run
mkdir -p my_fw/manifeststo create the new module directory and its manifests directory. -
From the
manifestsdirectory, use your text editor to createpre.pp. -
Edit
pre.ppso it contains the following Puppet code. These rules allow basic networking to ensure that existing connections are not closed.
# Default firewall rulesclass my_fw::pre { Firewall { require => undef, }firewall { '000 accept all icmp': proto => 'icmp', action => 'accept', } firewall { '001 accept all to lo interface': proto => 'all', iniface => 'lo', action => 'accept', } firewall { '002 reject local traffic not on loopback interface': iniface => '! lo', proto => 'all', destination => '127.0.0.1/8', action => 'reject', } firewall { '003 accept related established rules': proto => 'all', state => ['RELATED', 'ESTABLISHED'], action => 'accept', } } - Save and exit the file.
- From the
manifestsdirectory, use your text editor to createpost.pp. -
Edit
post.ppso it contains the following Puppet code. This drops any requests that don’t meet the rules defined inpre.ppor your rules defined insite.pp(see next section).class my_fw::post { firewall { '999 drop all': proto => 'all', action => 'drop', before => undef, } } - Save and exit the file.
That’s it! You’ve written a module that contains a class that, once applied, ensures your firewall has rules in it that will be managed by Puppet. Note the following about your new class:
pre.ppdefines the “pre” group rules the firewall applies when a service requests access. It is run before any other rules.post.ppdefines the rule for the firewall to drop any requests that haven’t met the rules defined bypre.ppor insite.pp(see next section).
Add the firewall module to the main manifest
- On your Puppet master, navigate to the main manifest:
cd /etc/puppetlabs/code/environments/production/manifests. - Use your text editor to open
site.pp. -
Add the following Puppet code to your
site.ppfile. This will clear any existing rules and make sure that only rules defined in Puppet exist on the machine.resources { 'firewall': purge => true, } -
Add the following Puppet code to your
site.ppfile. These defaults will ensure that thepreandpostclasses are run in the correct order to avoid locking you out of your box during the first Puppet run, and declaringmy_fw::preandmy_fw::postsatisfies the specified dependencies.Firewall { before => Class['my_fw::post'], require => Class['my_fw::pre'], } class { ['my_fw::pre', 'my_fw::post']: } -
Add the
firewallclass to yoursite.ppto ensure the correct packages are installed:class { 'firewall': }
That’s it! To check your firewall configuration, run
iptables --listfrom the command line of your Puppet agent. The result should look similar to this:
Chain INPUT (policy ACCEPT)
target prot opt source destination
ACCEPT icmp -- anywhere anywhere /* 000 accept all icmp */
ACCEPT all -- anywhere anywhere /* 001 accept all to lo interface */
REJECT all -- anywhere loopback/8 /* 002 reject local traffic not on loopback interface */ reject-with icmp-port-unreachable
ACCEPT all -- anywhere anywhere /* 003 accept related established rules */ state RELATED,ESTABLISHED
DROP all -- anywhere anywhere /* 999 drop all */
Chain FORWARD (policy ACCEPT)
target prot opt source destination
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
Enforce the desired state of the my_firewall class
Lastly, let’s take a look at how Puppet ensures the desired state of the my_firewall class on your agents. In the previous task, you applied your firewall class. Now imagine a scenario where a member of your team changes the contents of the iptables to allow connections on a random port that was not specified in my_firewall.
-
Select an agent on which you applied the
my_firewallclass, and runiptables --list. -
Note that the rules from the
my_firewallclass have been applied. -
From the command line, insert a new rule to allow connections to port 8449 by running
iptables -I INPUT -m state --state NEW -m tcp -p tcp --dport 8449 -j ACCEPT. -
Run
iptables --listagain and note that this new rule is now listed. -
Run
puppet agent -t --onetimeto trigger a Puppet run on that agent. -
Run
iptables --liston that node once more, and notice that Puppet has enforced the desired state you specified for the firewall rules.
That’s it–Puppet has enforced the desired state of your agent!
Other resources
You can learn more about the Puppet Firewall module by visiting the Puppet Forge.
Check out the other quick start guides in our Puppet QSG series:
Puppet offers many opportunities for learning and training, from formal certification courses to guided online lessons. We’ve noted one below; head over to the learning Puppet page to discover more.
- The Puppet workshop contains a series of self-paced, online lessons that cover a variety of topics on Puppet basics. You can sign up at the learning page.