The document discusses different approaches taken by the author's organization, WFU, to manage firewall rules using Puppet. It begins by providing context about WFU's Puppet infrastructure. It then describes three attempts made to manage firewall rules: 1) hardcoding all values; 2) exporting rules explicitly and collecting them; and 3) storing rule data in Hiera and applying rules directly without exporting/collecting. Each attempt is evaluated in terms of its results. The document aims to share lessons learned in managing firewall rules with exported resources and recommends planning naming conventions and environments carefully.
1 of 17
More Related Content
Puppet Camp Charlotte 2015: Exporting Resources: There and Back Again
2. About the WFU Linux Environment
• ~160 servers
• RHEL5, 6, and 7
• Puppet Open Source (3.8)
• Lots of virtualization
• App/DB pairs w/multiple environments
• Some Apps load balanced
• Oracle Active Data Guard
• Moving towards containerization, not there yet (more "pets")
3. Goals
What I intend with this presentation:
• to share our successes and failures
• to provide information to help you prevent some of our failures
• to learn what others have done in this area
What I do NOT intend with this presentation:
• to convince you to use (or not use) exported resources
• to convince you to use our naming conventions
• to tell you you are doing it wrong
4. About WFU environments
University environments are lifecycle stages:
• DEVL
• TEST
• PPRD
• PROD
Puppet environments must encompass all University environments:
• master (production)
• feature development branches
5. Where it all began...
Starting out with Puppet:
• Puppet Open Source
• No existing Puppet code base
• No PuppetDB (no exported/collected resources)
• extlookup, no hiera
• No firewall module
• Rolled our own
How to manage firewall rules?
6. How do you manage firewall rules?
Some firewall rules have specific IPs and ports that need to be allowed.
What we have here is an information problem:
• node that allows traffic knows what port to open
• node that allows traffic does not know what IP to allow
How can we tell the nodes which addresses need to be allowed?
7. Managing Firewall Rules: Attempt #1
Hardcode all values:
class mysql_server {
iptables::rule {
"allow SERVER_NAME to access ${fqdn} (added by ${module_name})":
source => [ '192.168.10.101' ],
dport => 3306,
}
}
8. Managing Firewall Rules: Attempt #1
Results
• Easy to configure - in the beginning
• Hard to update
• Duplication of data
• Adding/Decommissioning servers
9. Managing Firewall Rules: Attempt #2
Export explicitly to a service:
class webapp_server {
@@iptables::rule {
"allow web/app server ($ipaddress) to mysql server (added by ${module_name})":
source => $ipaddress,
tag => 'mysql_server::iptables::webapp_name',
}
}
Collect all rules related to my service, overriding port:
class mysql_server {
Iptables::Rule <<| tag == 'mysql_server::iptables::webapp_name' |>> {
dport => '3306',
}
}
10. Managing Firewall Rules: Attempt #2
Results
• Naming of resources and tags is crucial
• Exported resources cross Puppet environments
• Resources exported during noop Puppet runs
• Can't be collected twice
• Virtual resources allow 'plusignment' and multiple realizations
• Cleanup is messy
• Require multiple Puppet runs
• Adding a firewall rule to a node requires modification of 2 nodes' manifests
11. Managing Firewall Rules: Attempt #2.5
Only export one rule per service:
class webapp_server {
@@iptables::rule {
'allow webapp to access mysql':
source => $ipaddress,
tag => "webapp_server::iptables::i_am_webapp_name_${univ_env}",
}
}
Collect anywhere you need to allow that service access, overriding port:
class mysql_server {
Iptables::Rule <<| tag == "webapp_server::iptables::i_am_webapp_name_${univ_env}" |>> {
dport => '3306',
}
}
12. Attempt #2 vs Attempt #2.5
Attempt #2:
@@iptables::rule {
"allow web/app server ($ipaddress) to mysql server (added by ${module_name})":
source => $ipaddress,
tag => 'mysql_server::iptables::webapp_name',
}
Attempt #2.5:
@@iptables::rule {
'allow webapp to access mysql':
source => $ipaddress,
tag => "webapp_server::iptables::i_am_webapp_name_${univ_env}",
}
13. Managing Firewall Rules: Attempt #2.5
Results
• Exported rule should be available for each server
• Hard to know where rules come from/are going
• Naming of resources and tags is still crucial
• Multiple services on one server are problematic
• Multiple collection/plusignment issue again
• Node definitions are critical
• Edge case - duplicate node definition causes nodes to lose iptables rules
14. Managing Firewall Rules: Attempt #3
Don't export or collect rules, use hiera for data storage as required:
class mysql_server ( {
iptables::rule {
'allow webapp server - linux::devl::app_name::ip':
source => hiera('linux::devl::app_name::ip'),
dport => hiera('linux::devl::mysql_server::port'),
;
}
16. Managing Firewall Rules: Attempt #3
Results
• Naming
• Still figuring it out
• Still crucial
• Hiera works
• Adding a server is easy
• Changing an IP address is easy
• Environments are supported
• Plan well for go-live
Our naming convention:
os::university_environment::service_name::sub_service::ip
os::university_environment::service_name::ip