ReleaseEngineering/PuppetAgain/Modules/fw
Contents
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. [ '10.26.52.110/22' ]
- Single IP CIDR blocks [ '10.22.8.114/32' ]
You can also nest arrays within arrays:
$rejh = [ $scl3_rejh, $mdc1_rejh ]
Roles
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 } }
Profiles
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 http://mozilla.org/MPL/2.0/. 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 'releng-puppet2.srv.releng.scl3.mozilla.com' { $aspects = [ 'maximum-security' ] $fw_allow_all = true include fw::profiles::distinguished_puppetmaster include toplevel::server::puppetmaster }
Logging
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.