2

I took over administrative duties for an Linux environment of around 20 boxes. Trying to consolidate configuration management with Puppet. Most is straightforward, however I stumbled on the firewall rules.

Previous administrator relied on a custom script that created iptables rules for each box out of a common template.

The template rules look like this:

hostname:   Action   Interface   Source    Protocol   destPort

Some examples:

ALL:          Accept   eth0    any           tcp   80
server4:       Accept   All    x.x.x.x/24   tcp/udp   111
node5:         Deny     All    y.y.y.y

Rules for ALL would apply to all boxes. The rest of the params are used to populate iptables rules. There are about 250 rules in the template.

Is it possible to re-use this common template via puppet and build iptables ruleset for each node? Is this kind of text mangling even possible with puppet?

Swartz
  • 304

5 Answers5

4

Not really.

To be more exact; it's technically possible. But since neither puppet's DSL or puppet itself is designed for such tasks¹, you'll accrue technical debt on a brittle gum-and-paperclip solution.³

IMHO, since you want to keep this template, the best course of action is to write a script which will transform data from this apparently legacy format into to the native puppet DSL (emitting .pp files you'll include appropriately)², using whatever Types/Modules that are most fitting to your boxen.

Now instead of re-running the script all the time, I would make your puppet manifests the authoritative source instead. I.e. do all changes in there, and export as necessary, until you got rid of the legacy plumbing that relies on this format. It may make sense to omit this if your transition period is short enough; and you don't mind 'importing' a few times.


¹) That should be obvious if you think briefly about it: A CM's duty is to be the authoritative source of configuration data, not to mangle data. That's what sed, awk, Pipes, et al. are for.

²) Consider hiera as well.

³) Most likely, your successor will hate your for it, and more importantly, you'll hate yourself after some distance down the rabbit hole.

roeme
  • 3,955
  • 3
  • 23
  • 34
1

The sanest way of doing this would be parsing your old config from the legacy files you mentioned into puppet DSL with a custom script and modifying the firewall module to include support for your legacy systems and run puppet on them too.

You could use the ipfilter on the puppet forge as a starting point.

A quick and dirty way to do this would be by using define to wrap ipfilter and firewall depending on the node's operating system.

fuero
  • 9,879
0

It kinda looks like someone wanted to reimplement shorewall and didn't quite get there...

I think you're going to out of luck looking for a ready-made solution which will turn that custom file format into Puppet resources; being a custom file format, nobody else will have ever heard of it or dealt with it. The format looks relatively straightforward, though, so a quick bit of scripting in a language of your choice should make it possible to turn it into resources. The next question, of course, is which package to use to define the firewall resources within Puppet...

If, instead, you're looking to keep the crazy custom file format, but use Puppet as an intermediary to ship the "compiled" rulesets out to machines, I'd advise against doing anything particularly fancy. I'd probably look to "compile" the rulesets on the Puppetmaster when you deploy the tree, so that if there are changes to the "source" file, new rulesets will then be available in the fileserver to be shipped out to the clients when they next run.

womble
  • 98,245
0

I disbelieve that you can implement this kind of transformation inside the Puppet DSL.

You will want to write a Ruby function that consumes the text input and creates resources for the firewall module.

Felix Frank
  • 3,123
0

We are using Shorewall to achieve this. Shorewall builds upon iptables (netfilter). There are several modules in the puppetlabs to automate Shorewall in Puppet.

Usually you have a couple of data sources in Puppet, for example Hiera and an ENC. In this case, if you have set-up Hiera the right way, you can have your firewall configuration in there. The good thing with Hiera is that you can "overrule" configuration for specific networks/hosts/services/etc (for example: default.yaml -> webserver.yaml -> apache.yaml). The most specific containing the key you need will be leading.

If you need to get rules from a database (MySQL for example) you can have the ENC pass those to Puppet.

In Puppet you can make templates for Shorewall (ex: webserver.erb) and include them in your shorewall configuration. They could contain something like:

# This file is managed by Puppet
<% @firewall_rules.each do |entry| -%>
<%= entry['ip'] %>/<%= entry['mask'] %> - - src,dst
<% end -%>
Jeroen
  • 1,339