From MozillaWiki
Jump to: navigation, search

Firewall Wrapper Module

This is a wrapper around the `firewall` and 'pf' module. It provides transparency for writing firewall rules that may be interchangeable between both OSX and Linux
The fw module uses a 'Roles & Profiles' framework for managing and applying firewall rules in a simple and easy way. A role is made up of individual rules grouped together on a source/application basis. A Profile is a collection of roles which is applied to a host or group of hosts.

Defining ports and protocols for applications

Each application must be defined in the $app_proto_port hash within the apps.pp manifest.
For example:

 'http'   => { proto => 'tcp', port  => '80' },
 'https'  => { proto => 'tcp', port  => '443' },
 'puppet' => { proto => 'tcp', port  => '8140' },

Valid protocols are:

  • tcp
  • udp

Defining hosts and networks

All sources should be defined within the networks.pp manifest. All variables defined here are arrays even if it is a single element array.
Valid sources are:

  • Network CIDR blocks eg. [ '' ]
  • Single IP CIDR blocks [ '' ]

You can also nest arrays within arrays:

 $rejh = [ $scl3_rejh,  $mdc1_rejh ]


For example, this role allows all sources to the puppet master listening ports:

 class fw::roles::puppetmaster_from_all_releng {
     include fw::networks
     fw::rules { 'allow_puppetmaster_http':
         sources =>  $::fw::networks::all_releng,
         app     => 'http'
     fw::rules { 'allow_puppetmaster_https':
         sources =>  $::fw::networks::all_releng,
         app     => 'https'
     fw::rules { 'allow_puppetmaster_puppet':
         sources =>  $::fw::networks::all_releng,
         app     => 'puppet'

In this example, this role allows ssh access from all puppetmasters (for rsync):

 class fw::roles::puppetmaster_sync_from_all_puppetmasters {
     include fw::networks
     fw::rules { 'allow_puppetmaster_sync':
         sources => [ $::fw::networks::non_distingushed_puppetmasters,
                      $::fw::networks::distingushed_puppetmaster ],
         app     => 'ssh'

And finally, this role allows ssh access from the jumphosts:

 class fw::roles::ssh_from_rejh_logging {
     include fw::networks
     fw::rules { 'allow_ssh_from_rejh_logging':
         sources =>  $::fw::networks::rejh,
         app     => 'ssh',
         log     => true


Now we can take the previous roles and build a profile for the distinguished puppetmaster:

 class fw::profiles::distinguished_puppetmaster {
     include ::fw::roles::puppetmaster_from_all_releng
     include ::fw::roles::puppetmaster_sync_from_all_releng
     include ::fw::roles::ssh_from_rejh_logging

Note: the ssh role is a logging role, therefore it will log the connections in addition to allowing connections

Naming Standards

In order to make sure firewall policies are easy to understand and follow, having good and consistent naming practices will help ensure readability.

Role template

A role should be named as such <type_of_traffic>_from_<name_of_source>.pp. For example, 'nrpe_from_nagios.pp'
Just like any other puppet manifest the file should start with the MPL 2.0 license header
The class within should match the filename.
Make sure to include fw::networks
Each fw::rule resource should be title allow_<service_type>_from_<name_of_source>. For example:

   # This Source Code Form is subject to the terms of the Mozilla Public
   # License, v. 2.0. If a copy of the MPL was not distributed with this
   # file, You can obtain one at
   class fw::roles::nrpe_from_nagios {
       include fw::networks
       fw::rules { 'allow_nrpe_from_nagios':
           sources =>  $::fw::networks::nagios,
           app     => 'nrpe'

Using profiles

To apply this profile to the distinguished puppetmaster, simply include the profile in the node definition. Here we also include a node scope variable ($fw_allow_all) which changes the default policy to allow all traffic.

 node '' {
     $aspects       = [ 'maximum-security' ]
     $fw_allow_all  = true
     include fw::profiles::distinguished_puppetmaster
     include toplevel::server::puppetmaster


Logging can be enabled for any rule. Simply add 'log => true' to the rule being defined with fw::rules. This will cause the connection to be logged when the connection state is created.
For example:

   fw::rules { 'allow_vnc_from_anywhere_logging':
       sources =>  $::fw::networks::everywhere,
       app     => 'vnc',
       log     => true

Default policy and overriding it

The default policy for both IPTables and PF is default deny. This also means every rule within a role is an explicit allow rule.
If you wish to override the default deny policy for testing purposes, you must set the node scope variable ($fw_allow_all) explicitly true within the node definition.

 $fw_allow_all = true

Note: To re-enable the default deny policy, simply remove the node scope variable

Global allowed flows

The only globably allowed flows for both IPTables and PF are:

  • established connections
  • ICMP

All other flows are denied unless explicitly added.