Fix implicit dependency on firewall cookbook in kosmos-base
Also delete ufw cookbook, we're not using it
This commit is contained in:
parent
11b812fbb8
commit
030b2501eb
3
Batali
3
Batali
@ -25,8 +25,7 @@ Batali.define do
|
||||
cookbook 'redis',
|
||||
git: 'https://github.com/phlipper/chef-redis.git',
|
||||
ref: 'v0.5.6'
|
||||
cookbook 'ufw'
|
||||
cookbook 'firewall'
|
||||
cookbook 'firewall', '~> 2.6.1'
|
||||
cookbook 'chef_nginx'
|
||||
cookbook 'build-essential'
|
||||
cookbook 'mysql'
|
||||
|
@ -962,21 +962,6 @@
|
||||
"subdirectory": null
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "ufw",
|
||||
"dependencies": [
|
||||
[
|
||||
"firewall",
|
||||
">= 2.0"
|
||||
]
|
||||
],
|
||||
"version": "3.1.0",
|
||||
"source": {
|
||||
"type": "Batali::Source::Site",
|
||||
"url": "https://supermarket.chef.io:443/api/v1/cookbooks/ufw/versions/3.1.0/download",
|
||||
"version": "3.1.0"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "firewall",
|
||||
"dependencies": [
|
||||
@ -985,11 +970,11 @@
|
||||
">= 0.0.0"
|
||||
]
|
||||
],
|
||||
"version": "2.5.4",
|
||||
"version": "2.6.1",
|
||||
"source": {
|
||||
"type": "Batali::Source::Site",
|
||||
"url": "https://supermarket.chef.io:443/api/v1/cookbooks/firewall/versions/2.5.4/download",
|
||||
"version": "2.5.4"
|
||||
"url": "https://supermarket.chef.io:443/api/v1/cookbooks/firewall/versions/2.6.1/download",
|
||||
"version": "2.6.1"
|
||||
}
|
||||
},
|
||||
{
|
||||
|
3
cookbooks/firewall/.foodcritic
Normal file
3
cookbooks/firewall/.foodcritic
Normal file
@ -0,0 +1,3 @@
|
||||
~FC001
|
||||
~FC057
|
||||
~FC019
|
@ -2,6 +2,17 @@ firewall Cookbook CHANGELOG
|
||||
=======================
|
||||
This file is used to list changes made in each version of the firewall cookbook.
|
||||
|
||||
v2.6.1 (2017-04-21)
|
||||
-------------------
|
||||
* Add recipe to disable firewall (#164)
|
||||
|
||||
v2.6.0 (2017-04-17)
|
||||
-------------------
|
||||
* Initial Chef 13.x support (#160, #159)
|
||||
* Allow loopback and icmp, when enabled (#161)
|
||||
* Address various newer rubocop and foodcritic complaints
|
||||
* Convert rule provider away from DSL (#159)
|
||||
|
||||
v2.5.4 (2017-02-13)
|
||||
-------------------
|
||||
* Update Test Kitchen platforms to the latest
|
||||
|
@ -84,13 +84,18 @@ keys must be unique but we need multiple commit lines.
|
||||
# Recipes
|
||||
|
||||
### default
|
||||
The default recipe creates a firewall resource with action install, and if `node['firewall']['allow_ssh']`, opens port 22 from the world.
|
||||
The default recipe creates a firewall resource with action install.
|
||||
|
||||
### disable_firewall
|
||||
Used to disable platform specific firewall. Many clouds have their own firewall configured outside of the OS instance such as AWS Security Groups.
|
||||
|
||||
# Attributes
|
||||
|
||||
* `default['firewall']['allow_ssh'] = false`, set true to open port 22 for SSH when the default recipe runs
|
||||
* `default['firewall']['allow_mosh'] = false`, set to true to open UDP ports 60000 - 61000 for [Mosh][0] when the default recipe runs
|
||||
* `default['firewall']['allow_winrm'] = false`, set true to open port 5989 for WinRM when the default recipe runs
|
||||
* `default['firewall']['allow_loopback'] = false`, set to true to allow all traffic on the loopback interface
|
||||
* `default['firewall']['allow_icmp'] = false`, set true to allow icmp protocol on supported OSes (note: ufw and windows implementations don't support this)
|
||||
|
||||
* `default['firewall']['ubuntu_iptables'] = false`, set to true to use iptables on Ubuntu / Debian when using the default recipe
|
||||
* `default['firewall']['redhat7_iptables'] = false`, set to true to use iptables on Red Hat / CentOS 7 when using the default recipe
|
||||
|
@ -1,3 +1,5 @@
|
||||
default['firewall']['allow_ssh'] = false
|
||||
default['firewall']['allow_winrm'] = false
|
||||
default['firewall']['allow_mosh'] = false
|
||||
default['firewall']['allow_loopback'] = false
|
||||
default['firewall']['allow_icmp'] = false
|
||||
|
@ -1,14 +1,14 @@
|
||||
default['firewall']['iptables']['defaults'][:policy] = {
|
||||
input: 'DROP',
|
||||
forward: 'DROP',
|
||||
output: 'ACCEPT'
|
||||
output: 'ACCEPT',
|
||||
}
|
||||
default['firewall']['iptables']['defaults'][:ruleset] = {
|
||||
'*filter' => 1,
|
||||
":INPUT #{node['firewall']['iptables']['defaults'][:policy][:input]}" => 2,
|
||||
":FORWARD #{node['firewall']['iptables']['defaults'][:policy][:forward]}" => 3,
|
||||
":OUTPUT #{node['firewall']['iptables']['defaults'][:policy][:output]}" => 4,
|
||||
'COMMIT_FILTER' => 100
|
||||
'COMMIT_FILTER' => 100,
|
||||
}
|
||||
|
||||
default['firewall']['ubuntu_iptables'] = false
|
||||
|
@ -7,6 +7,6 @@ default['firewall']['ufw']['defaults'] = {
|
||||
input: 'DROP',
|
||||
output: 'ACCEPT',
|
||||
forward: 'DROP',
|
||||
application: 'SKIP'
|
||||
}
|
||||
application: 'SKIP',
|
||||
},
|
||||
}
|
||||
|
@ -3,6 +3,6 @@
|
||||
default['firewall']['windows']['defaults'] = {
|
||||
policy: {
|
||||
input: 'blockinbound',
|
||||
output: 'allowoutbound'
|
||||
}
|
||||
output: 'allowoutbound',
|
||||
},
|
||||
}
|
||||
|
@ -18,14 +18,14 @@ module FirewallCookbook
|
||||
end
|
||||
|
||||
def firewalld_default_zone?(z)
|
||||
raise false unless firewalld_active?
|
||||
return false unless firewalld_active?
|
||||
|
||||
cmd = shell_out('firewall-cmd', '--get-default-zone')
|
||||
cmd.stdout =~ /^#{z.to_s}$/
|
||||
end
|
||||
|
||||
def firewalld_default_zone!(z)
|
||||
raise 'firewall not active' unless firewalld_active?
|
||||
raise 'firewalld not active' unless firewalld_active?
|
||||
|
||||
shell_out!('firewall-cmd', "--set-default-zone=#{z}")
|
||||
end
|
||||
|
@ -46,7 +46,7 @@ module FirewallCookbook
|
||||
end
|
||||
|
||||
# if we don't do this, ufw will fail as it does not support protocol numbers, so we'll only allow it to run if specifying icmp/tcp/udp protocol types
|
||||
if new_resource.protocol && !new_resource.protocol.to_s.downcase.match('^(tcp|udp|icmp|esp|ah|ipv6|none)$')
|
||||
if new_resource.protocol && !new_resource.protocol.to_s.downcase.match('^(tcp|udp|esp|ah|ipv6|none)$')
|
||||
msg = ''
|
||||
msg << "firewall_rule[#{new_resource.name}] was asked to "
|
||||
msg << "#{new_resource.command} a rule using protocol #{new_resource.protocol} "
|
||||
|
@ -27,36 +27,39 @@ class Chef
|
||||
false
|
||||
end
|
||||
|
||||
action :install do
|
||||
next if disabled?(new_resource)
|
||||
def action_install
|
||||
return if disabled?(new_resource)
|
||||
|
||||
converge_by('install firewalld, create template for /etc/sysconfig') do
|
||||
package 'firewalld' do
|
||||
action :install
|
||||
firewalld_package = package 'firewalld' do
|
||||
action :nothing
|
||||
options new_resource.package_options
|
||||
end
|
||||
firewalld_package.run_action(:install)
|
||||
new_resource.updated_by_last_action(firewalld_package.updated_by_last_action?)
|
||||
|
||||
service 'firewalld' do
|
||||
action [:enable, :start]
|
||||
unless ::File.exist?(firewalld_rules_filename)
|
||||
rules_file = lookup_or_create_rulesfile
|
||||
rules_file.content '# created by chef to allow service to start'
|
||||
rules_file.run_action(:create)
|
||||
new_resource.updated_by_last_action(rules_file.updated_by_last_action?)
|
||||
end
|
||||
|
||||
file "create empty #{firewalld_rules_filename}" do
|
||||
path firewalld_rules_filename
|
||||
content '# created by chef to allow service to start'
|
||||
not_if { ::File.exist?(firewalld_rules_filename) }
|
||||
end
|
||||
firewalld_service = lookup_or_create_service
|
||||
[:enable, :start].each do |a|
|
||||
firewalld_service.run_action(a)
|
||||
new_resource.updated_by_last_action(firewalld_service.updated_by_last_action?)
|
||||
end
|
||||
end
|
||||
|
||||
action :restart do
|
||||
next if disabled?(new_resource)
|
||||
def action_restart
|
||||
return if disabled?(new_resource)
|
||||
|
||||
# ensure it's initialized
|
||||
new_resource.rules({}) unless new_resource.rules
|
||||
new_resource.rules['firewalld'] = {} unless new_resource.rules['firewalld']
|
||||
|
||||
# this populates the hash of rules from firewall_rule resources
|
||||
firewall_rules = run_context.resource_collection.select { |item| item.is_a?(Chef::Resource::FirewallRule) }
|
||||
firewall_rules = Chef.run_context.resource_collection.select { |item| item.is_a?(Chef::Resource::FirewallRule) }
|
||||
firewall_rules.each do |firewall_rule|
|
||||
next unless firewall_rule.action.include?(:create) && !firewall_rule.should_skip?(:create)
|
||||
|
||||
@ -79,23 +82,15 @@ class Chef
|
||||
end
|
||||
|
||||
# ensure a file resource exists with the current firewalld rules
|
||||
begin
|
||||
firewalld_file = run_context.resource_collection.find(file: firewalld_rules_filename)
|
||||
rescue
|
||||
firewalld_file = file firewalld_rules_filename do
|
||||
action :nothing
|
||||
end
|
||||
end
|
||||
firewalld_file.content build_rule_file(new_resource.rules['firewalld'])
|
||||
firewalld_file.run_action(:create)
|
||||
rules_file = lookup_or_create_rulesfile
|
||||
rules_file.content build_rule_file(new_resource.rules['firewalld'])
|
||||
rules_file.run_action(:create)
|
||||
|
||||
# ensure the service is running without waiting.
|
||||
firewall_service = service 'firewalld' do
|
||||
action :nothing
|
||||
end
|
||||
firewalld_service = lookup_or_create_service
|
||||
[:enable, :start].each do |a|
|
||||
firewall_service.run_action(a)
|
||||
new_resource.updated_by_last_action(firewall_service.updated_by_last_action?)
|
||||
firewalld_service.run_action(a)
|
||||
new_resource.updated_by_last_action(firewalld_service.updated_by_last_action?)
|
||||
end
|
||||
|
||||
# mark updated if we changed the zone
|
||||
@ -105,7 +100,7 @@ class Chef
|
||||
end
|
||||
|
||||
# if the file was changed, load new ruleset
|
||||
if firewalld_file.updated_by_last_action?
|
||||
return unless rules_file.updated_by_last_action?
|
||||
firewalld_flush!
|
||||
# TODO: support logging
|
||||
|
||||
@ -115,10 +110,9 @@ class Chef
|
||||
|
||||
new_resource.updated_by_last_action(true)
|
||||
end
|
||||
end
|
||||
|
||||
action :disable do
|
||||
next if disabled?(new_resource)
|
||||
def action_disable
|
||||
return if disabled?(new_resource)
|
||||
|
||||
if firewalld_active?
|
||||
firewalld_flush!
|
||||
@ -126,38 +120,60 @@ class Chef
|
||||
new_resource.updated_by_last_action(true)
|
||||
end
|
||||
|
||||
service 'firewalld' do
|
||||
action [:disable, :stop]
|
||||
# ensure the service is stopped without waiting.
|
||||
firewalld_service = lookup_or_create_service
|
||||
[:disable, :stop].each do |a|
|
||||
firewalld_service.run_action(a)
|
||||
new_resource.updated_by_last_action(firewalld_service.updated_by_last_action?)
|
||||
end
|
||||
|
||||
file "create empty #{firewalld_rules_filename}" do
|
||||
path firewalld_rules_filename
|
||||
content '# created by chef to allow service to start'
|
||||
action :create
|
||||
end
|
||||
rules_file = lookup_or_create_rulesfile
|
||||
rules_file.content '# created by chef to allow service to start'
|
||||
rules_file.run_action(:create)
|
||||
new_resource.updated_by_last_action(rules_file.updated_by_last_action?)
|
||||
end
|
||||
|
||||
action :flush do
|
||||
next if disabled?(new_resource)
|
||||
next unless firewalld_active?
|
||||
def action_flush
|
||||
return if disabled?(new_resource)
|
||||
return unless firewalld_active?
|
||||
|
||||
firewalld_flush!
|
||||
new_resource.updated_by_last_action(true)
|
||||
|
||||
file "create empty #{firewalld_rules_filename}" do
|
||||
path firewalld_rules_filename
|
||||
content '# created by chef to allow service to start'
|
||||
action :create
|
||||
end
|
||||
rules_file = lookup_or_create_rulesfile
|
||||
rules_file.content '# created by chef to allow service to start'
|
||||
rules_file.run_action(:create)
|
||||
new_resource.updated_by_last_action(rules_file.updated_by_last_action?)
|
||||
end
|
||||
|
||||
action :save do
|
||||
next if disabled?(new_resource)
|
||||
def action_save
|
||||
return if disabled?(new_resource)
|
||||
return if firewalld_all_rules_permanent!
|
||||
|
||||
unless firewalld_all_rules_permanent!
|
||||
firewalld_save!
|
||||
new_resource.updated_by_last_action(true)
|
||||
end
|
||||
|
||||
def lookup_or_create_service
|
||||
begin
|
||||
firewalld_service = Chef.run_context.resource_collection.find(service: 'firewalld')
|
||||
rescue
|
||||
firewalld_service = service 'firewalld' do
|
||||
action :nothing
|
||||
end
|
||||
end
|
||||
firewalld_service
|
||||
end
|
||||
|
||||
def lookup_or_create_rulesfile
|
||||
begin
|
||||
firewalld_file = Chef.run_context.resource_collection.find(file: firewalld_rules_filename)
|
||||
rescue
|
||||
firewalld_file = file firewalld_rules_filename do
|
||||
action :nothing
|
||||
end
|
||||
end
|
||||
firewalld_file
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -30,34 +30,38 @@ class Chef
|
||||
false
|
||||
end
|
||||
|
||||
action :install do
|
||||
next if disabled?(new_resource)
|
||||
def action_install
|
||||
return if disabled?(new_resource)
|
||||
|
||||
converge_by('install iptables and enable/start services') do
|
||||
# can't pass an array without breaking chef 11 support
|
||||
# Ensure the package is installed
|
||||
iptables_packages(new_resource).each do |p|
|
||||
package p do
|
||||
action :install
|
||||
iptables_pkg = package p do
|
||||
action :nothing
|
||||
end
|
||||
iptables_pkg.run_action(:install)
|
||||
new_resource.updated_by_last_action(true) if iptables_pkg.updated_by_last_action?
|
||||
end
|
||||
|
||||
iptables_commands(new_resource).each do |svc|
|
||||
# must create empty file for service to start
|
||||
file "create empty /etc/sysconfig/#{svc}" do
|
||||
path "/etc/sysconfig/#{svc}"
|
||||
content '# created by chef to allow service to start'
|
||||
not_if { ::File.exist?("/etc/sysconfig/#{svc}") }
|
||||
unless ::File.exist?("/etc/sysconfig/#{svc}")
|
||||
# must create empty file for service to start
|
||||
iptables_file = lookup_or_create_rulesfile(svc)
|
||||
iptables_file.content '# created by chef to allow service to start'
|
||||
iptables_file.run_action(:create)
|
||||
new_resource.updated_by_last_action(true) if iptables_file.updated_by_last_action?
|
||||
end
|
||||
|
||||
service svc do
|
||||
action [:enable, :start]
|
||||
end
|
||||
iptables_service = lookup_or_create_service(svc)
|
||||
[:enable, :start].each do |a|
|
||||
iptables_service.run_action(a)
|
||||
new_resource.updated_by_last_action(true) if iptables_service.updated_by_last_action?
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
action :restart do
|
||||
next if disabled?(new_resource)
|
||||
def action_restart
|
||||
return if disabled?(new_resource)
|
||||
|
||||
# prints all the firewall rules
|
||||
log_iptables(new_resource)
|
||||
@ -67,7 +71,7 @@ class Chef
|
||||
ensure_default_rules_exist(node, new_resource)
|
||||
|
||||
# this populates the hash of rules from firewall_rule resources
|
||||
firewall_rules = run_context.resource_collection.select { |item| item.is_a?(Chef::Resource::FirewallRule) }
|
||||
firewall_rules = Chef.run_context.resource_collection.select { |item| item.is_a?(Chef::Resource::FirewallRule) }
|
||||
firewall_rules.each do |firewall_rule|
|
||||
next unless firewall_rule.action.include?(:create) && !firewall_rule.should_skip?(:create)
|
||||
|
||||
@ -91,65 +95,77 @@ class Chef
|
||||
end
|
||||
|
||||
iptables_commands(new_resource).each do |iptables_type|
|
||||
iptables_filename = "/etc/sysconfig/#{iptables_type}"
|
||||
# ensure a file resource exists with the current iptables rules
|
||||
begin
|
||||
iptables_file = run_context.resource_collection.find(file: iptables_filename)
|
||||
rescue
|
||||
iptables_file = file iptables_filename do
|
||||
action :nothing
|
||||
end
|
||||
end
|
||||
|
||||
# this takes the commands in each hash entry and builds a rule file
|
||||
iptables_file = lookup_or_create_rulesfile(iptables_type)
|
||||
iptables_file.content build_rule_file(new_resource.rules[iptables_type])
|
||||
iptables_file.run_action(:create)
|
||||
|
||||
# if the file was unchanged, skip loop iteration, otherwise restart iptables
|
||||
next unless iptables_file.updated_by_last_action?
|
||||
|
||||
service_affected = service iptables_type do
|
||||
action :nothing
|
||||
end
|
||||
|
||||
new_resource.notifies(:restart, service_affected, :delayed)
|
||||
iptables_service = lookup_or_create_service(iptables_type)
|
||||
new_resource.notifies(:restart, iptables_service, :delayed)
|
||||
new_resource.updated_by_last_action(true)
|
||||
end
|
||||
end
|
||||
|
||||
action :disable do
|
||||
next if disabled?(new_resource)
|
||||
def action_disable
|
||||
return if disabled?(new_resource)
|
||||
|
||||
iptables_flush!(new_resource)
|
||||
iptables_default_allow!(new_resource)
|
||||
new_resource.updated_by_last_action(true)
|
||||
|
||||
iptables_commands(new_resource).each do |svc|
|
||||
service svc do
|
||||
action [:disable, :stop]
|
||||
iptables_service = lookup_or_create_service(svc)
|
||||
[:disable, :stop].each do |a|
|
||||
iptables_service.run_action(a)
|
||||
new_resource.updated_by_last_action(true) if iptables_service.updated_by_last_action?
|
||||
end
|
||||
|
||||
# must create empty file for service to start
|
||||
file "create empty /etc/sysconfig/#{svc}" do
|
||||
path "/etc/sysconfig/#{svc}"
|
||||
content '# created by chef to allow service to start'
|
||||
end
|
||||
iptables_file = lookup_or_create_rulesfile(svc)
|
||||
iptables_file.content '# created by chef to allow service to start'
|
||||
iptables_file.run_action(:create)
|
||||
new_resource.updated_by_last_action(true) if iptables_file.updated_by_last_action?
|
||||
end
|
||||
end
|
||||
|
||||
action :flush do
|
||||
next if disabled?(new_resource)
|
||||
def action_flush
|
||||
return if disabled?(new_resource)
|
||||
|
||||
iptables_flush!(new_resource)
|
||||
new_resource.updated_by_last_action(true)
|
||||
|
||||
iptables_commands(new_resource).each do |svc|
|
||||
# must create empty file for service to start
|
||||
file "create empty /etc/sysconfig/#{svc}" do
|
||||
path "/etc/sysconfig/#{svc}"
|
||||
content '# created by chef to allow service to start'
|
||||
end
|
||||
end
|
||||
iptables_file = lookup_or_create_rulesfile(svc)
|
||||
iptables_file.content '# created by chef to allow service to start'
|
||||
iptables_file.run_action(:create)
|
||||
new_resource.updated_by_last_action(true) if iptables_file.updated_by_last_action?
|
||||
end
|
||||
end
|
||||
|
||||
def lookup_or_create_service(name)
|
||||
begin
|
||||
iptables_service = Chef.run_context.resource_collection.find(service: svc)
|
||||
rescue
|
||||
iptables_service = service name do
|
||||
action :nothing
|
||||
end
|
||||
end
|
||||
iptables_service
|
||||
end
|
||||
|
||||
def lookup_or_create_rulesfile(name)
|
||||
begin
|
||||
iptables_file = Chef.run_context.resource_collection.find(file: name)
|
||||
rescue
|
||||
iptables_file = file "/etc/sysconfig/#{name}" do
|
||||
action :nothing
|
||||
end
|
||||
end
|
||||
iptables_file
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -30,37 +30,41 @@ class Chef
|
||||
false
|
||||
end
|
||||
|
||||
action :install do
|
||||
next if disabled?(new_resource)
|
||||
def action_install
|
||||
return if disabled?(new_resource)
|
||||
|
||||
converge_by('install iptables and enable/start services') do
|
||||
# Can't pass an array without breaking chef 11 support
|
||||
%w(iptables-persistent).each do |p|
|
||||
package p do
|
||||
action :install
|
||||
end
|
||||
# Ensure the package is installed
|
||||
pkg = package 'iptables-persistent' do
|
||||
action :nothing
|
||||
end
|
||||
pkg.run_action(:install)
|
||||
new_resource.updated_by_last_action(true) if pkg.updated_by_last_action?
|
||||
|
||||
rule_files = %w(rules.v4)
|
||||
rule_files << 'rules.v6' if ipv6_enabled?(new_resource)
|
||||
rule_files.each do |svc|
|
||||
next unless ::File.exist?("/etc/iptables/#{svc}")
|
||||
|
||||
# must create empty file for service to start
|
||||
file "create empty /etc/iptables/#{svc}" do
|
||||
path "/etc/iptables/#{svc}"
|
||||
content '# created by chef to allow service to start'
|
||||
not_if { ::File.exist?("/etc/iptables/#{svc}") }
|
||||
f = lookup_or_create_rulesfile(svc)
|
||||
f.content '# created by chef to allow service to start'
|
||||
f.run_action(:create)
|
||||
|
||||
new_resource.updated_by_last_action(true) if f.updated_by_last_action?
|
||||
end
|
||||
|
||||
iptables_service = lookup_or_create_service('netfilter-persistent')
|
||||
[:enable, :start].each do |act|
|
||||
# iptables-persistent isn't a real service
|
||||
iptables_service.status_command 'true'
|
||||
|
||||
iptables_service.run_action(act)
|
||||
new_resource.updated_by_last_action(true) if iptables_service.updated_by_last_action?
|
||||
end
|
||||
end
|
||||
|
||||
service 'netfilter-persistent' do
|
||||
action [:enable, :start]
|
||||
status_command 'true' # netfilter-persistent isn't a real service
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
action :restart do
|
||||
next if disabled?(new_resource)
|
||||
def action_restart
|
||||
return if disabled?(new_resource)
|
||||
|
||||
# prints all the firewall rules
|
||||
log_iptables(new_resource)
|
||||
@ -70,7 +74,7 @@ class Chef
|
||||
ensure_default_rules_exist(node, new_resource)
|
||||
|
||||
# this populates the hash of rules from firewall_rule resources
|
||||
firewall_rules = run_context.resource_collection.select { |item| item.is_a?(Chef::Resource::FirewallRule) }
|
||||
firewall_rules = Chef.run_context.resource_collection.select { |item| item.is_a?(Chef::Resource::FirewallRule) }
|
||||
firewall_rules.each do |firewall_rule|
|
||||
next unless firewall_rule.action.include?(:create) && !firewall_rule.should_skip?(:create)
|
||||
|
||||
@ -105,7 +109,7 @@ class Chef
|
||||
|
||||
# ensure a file resource exists with the current iptables rules
|
||||
begin
|
||||
iptables_file = run_context.resource_collection.find(file: iptables_filename)
|
||||
iptables_file = Chef.run_context.resource_collection.find(file: iptables_filename)
|
||||
rescue
|
||||
iptables_file = file iptables_filename do
|
||||
action :nothing
|
||||
@ -125,29 +129,31 @@ class Chef
|
||||
end
|
||||
end
|
||||
|
||||
action :disable do
|
||||
next if disabled?(new_resource)
|
||||
def action_disable
|
||||
return if disabled?(new_resource)
|
||||
|
||||
iptables_flush!(new_resource)
|
||||
iptables_default_allow!(new_resource)
|
||||
new_resource.updated_by_last_action(true)
|
||||
|
||||
service 'netfilter-persistent' do
|
||||
action [:disable, :stop]
|
||||
iptables_service = lookup_or_create_service('netfilter-persistent')
|
||||
[:disable, :stop].each do |act|
|
||||
iptables_service.run_action(act)
|
||||
new_resource.updated_by_last_action(true) if iptables_service.updated_by_last_action?
|
||||
end
|
||||
|
||||
%w(rules.v4 rules.v6).each do |svc|
|
||||
# must create empty file for service to start
|
||||
file "create empty /etc/iptables/#{svc}" do
|
||||
path "/etc/iptables/#{svc}"
|
||||
content '# created by chef to allow service to start'
|
||||
action :create
|
||||
end
|
||||
f = lookup_or_create_rulesfile(svc)
|
||||
f.content '# created by chef to allow service to start'
|
||||
f.run_action(:create)
|
||||
|
||||
new_resource.updated_by_last_action(true) if f.updated_by_last_action?
|
||||
end
|
||||
end
|
||||
|
||||
action :flush do
|
||||
next if disabled?(new_resource)
|
||||
def action_flush
|
||||
return if disabled?(new_resource)
|
||||
|
||||
iptables_flush!(new_resource)
|
||||
new_resource.updated_by_last_action(true)
|
||||
@ -156,11 +162,34 @@ class Chef
|
||||
rule_files << 'rules.v6' if ipv6_enabled?(new_resource)
|
||||
rule_files.each do |svc|
|
||||
# must create empty file for service to start
|
||||
file "create empty /etc/iptables/#{svc}" do
|
||||
path "/etc/iptables/#{svc}"
|
||||
content '# created by chef to allow service to start'
|
||||
end
|
||||
end
|
||||
f = lookup_or_create_rulesfile(svc)
|
||||
f.content '# created by chef to allow service to start'
|
||||
f.run_action(:create)
|
||||
|
||||
new_resource.updated_by_last_action(true) if f.updated_by_last_action?
|
||||
end
|
||||
end
|
||||
|
||||
def lookup_or_create_service(name)
|
||||
begin
|
||||
iptables_service = Chef.run_context.resource_collection.find(service: svc)
|
||||
rescue
|
||||
iptables_service = service name do
|
||||
action :nothing
|
||||
end
|
||||
end
|
||||
iptables_service
|
||||
end
|
||||
|
||||
def lookup_or_create_rulesfile(name)
|
||||
begin
|
||||
iptables_file = Chef.run_context.resource_collection.find(file: name)
|
||||
rescue
|
||||
iptables_file = file "/etc/iptables/#{name}" do
|
||||
action :nothing
|
||||
end
|
||||
end
|
||||
iptables_file
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -30,37 +30,41 @@ class Chef
|
||||
false
|
||||
end
|
||||
|
||||
action :install do
|
||||
next if disabled?(new_resource)
|
||||
def action_install
|
||||
return if disabled?(new_resource)
|
||||
|
||||
converge_by('install iptables and enable/start services') do
|
||||
# Can't pass an array without breaking chef 11 support
|
||||
%w(iptables-persistent).each do |p|
|
||||
package p do
|
||||
action :install
|
||||
end
|
||||
# Ensure the package is installed
|
||||
pkg = package 'iptables-persistent' do
|
||||
action :nothing
|
||||
end
|
||||
pkg.run_action(:install)
|
||||
new_resource.updated_by_last_action(true) if pkg.updated_by_last_action?
|
||||
|
||||
rule_files = %w(rules.v4)
|
||||
rule_files << 'rules.v6' if ipv6_enabled?(new_resource)
|
||||
rule_files.each do |svc|
|
||||
next unless ::File.exist?("/etc/iptables/#{svc}")
|
||||
|
||||
# must create empty file for service to start
|
||||
file "create empty /etc/iptables/#{svc}" do
|
||||
path "/etc/iptables/#{svc}"
|
||||
content '# created by chef to allow service to start'
|
||||
not_if { ::File.exist?("/etc/iptables/#{svc}") }
|
||||
f = lookup_or_create_rulesfile(svc)
|
||||
f.content '# created by chef to allow service to start'
|
||||
f.run_action(:create)
|
||||
|
||||
new_resource.updated_by_last_action(true) if f.updated_by_last_action?
|
||||
end
|
||||
|
||||
iptables_service = lookup_or_create_service('iptables-persistent')
|
||||
[:enable, :start].each do |act|
|
||||
# iptables-persistent isn't a real service
|
||||
iptables_service.status_command 'true'
|
||||
|
||||
iptables_service.run_action(act)
|
||||
new_resource.updated_by_last_action(true) if iptables_service.updated_by_last_action?
|
||||
end
|
||||
end
|
||||
|
||||
service 'iptables-persistent' do
|
||||
action [:enable, :start]
|
||||
status_command 'true' # iptables-persistent isn't a real service
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
action :restart do
|
||||
next if disabled?(new_resource)
|
||||
def action_restart
|
||||
return if disabled?(new_resource)
|
||||
|
||||
# prints all the firewall rules
|
||||
log_iptables(new_resource)
|
||||
@ -70,7 +74,7 @@ class Chef
|
||||
ensure_default_rules_exist(node, new_resource)
|
||||
|
||||
# this populates the hash of rules from firewall_rule resources
|
||||
firewall_rules = run_context.resource_collection.select { |item| item.is_a?(Chef::Resource::FirewallRule) }
|
||||
firewall_rules = Chef.run_context.resource_collection.select { |item| item.is_a?(Chef::Resource::FirewallRule) }
|
||||
firewall_rules.each do |firewall_rule|
|
||||
next unless firewall_rule.action.include?(:create) && !firewall_rule.should_skip?(:create)
|
||||
|
||||
@ -105,7 +109,7 @@ class Chef
|
||||
|
||||
# ensure a file resource exists with the current iptables rules
|
||||
begin
|
||||
iptables_file = run_context.resource_collection.find(file: iptables_filename)
|
||||
iptables_file = Chef.run_context.resource_collection.find(file: iptables_filename)
|
||||
rescue
|
||||
iptables_file = file iptables_filename do
|
||||
action :nothing
|
||||
@ -125,29 +129,31 @@ class Chef
|
||||
end
|
||||
end
|
||||
|
||||
action :disable do
|
||||
next if disabled?(new_resource)
|
||||
def action_disable
|
||||
return if disabled?(new_resource)
|
||||
|
||||
iptables_flush!(new_resource)
|
||||
iptables_default_allow!(new_resource)
|
||||
new_resource.updated_by_last_action(true)
|
||||
|
||||
service 'iptables-persistent' do
|
||||
action [:disable, :stop]
|
||||
iptables_service = lookup_or_create_service('iptables-persistent')
|
||||
[:disable, :stop].each do |act|
|
||||
iptables_service.run_action(act)
|
||||
new_resource.updated_by_last_action(true) if iptables_service.updated_by_last_action?
|
||||
end
|
||||
|
||||
%w(rules.v4 rules.v6).each do |svc|
|
||||
# must create empty file for service to start
|
||||
file "create empty /etc/iptables/#{svc}" do
|
||||
path "/etc/iptables/#{svc}"
|
||||
content '# created by chef to allow service to start'
|
||||
action :create
|
||||
end
|
||||
f = lookup_or_create_rulesfile(svc)
|
||||
f.content '# created by chef to allow service to start'
|
||||
f.run_action(:create)
|
||||
|
||||
new_resource.updated_by_last_action(true) if f.updated_by_last_action?
|
||||
end
|
||||
end
|
||||
|
||||
action :flush do
|
||||
next if disabled?(new_resource)
|
||||
def action_flush
|
||||
return if disabled?(new_resource)
|
||||
|
||||
iptables_flush!(new_resource)
|
||||
new_resource.updated_by_last_action(true)
|
||||
@ -156,11 +162,34 @@ class Chef
|
||||
rule_files << 'rules.v6' if ipv6_enabled?(new_resource)
|
||||
rule_files.each do |svc|
|
||||
# must create empty file for service to start
|
||||
file "create empty /etc/iptables/#{svc}" do
|
||||
path "/etc/iptables/#{svc}"
|
||||
content '# created by chef to allow service to start'
|
||||
end
|
||||
end
|
||||
f = lookup_or_create_rulesfile(svc)
|
||||
f.content '# created by chef to allow service to start'
|
||||
f.run_action(:create)
|
||||
|
||||
new_resource.updated_by_last_action(true) if f.updated_by_last_action?
|
||||
end
|
||||
end
|
||||
|
||||
def lookup_or_create_service(name)
|
||||
begin
|
||||
iptables_service = Chef.run_context.resource_collection.find(service: svc)
|
||||
rescue
|
||||
iptables_service = service name do
|
||||
action :nothing
|
||||
end
|
||||
end
|
||||
iptables_service
|
||||
end
|
||||
|
||||
def lookup_or_create_rulesfile(name)
|
||||
begin
|
||||
iptables_file = Chef.run_context.resource_collection.find(file: name)
|
||||
rescue
|
||||
iptables_file = file "/etc/iptables/#{name}" do
|
||||
action :nothing
|
||||
end
|
||||
end
|
||||
iptables_file
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -21,9 +21,10 @@ class Chef
|
||||
class Provider::FirewallRuleGeneric < Chef::Provider::LWRPBase
|
||||
provides :firewall_rule
|
||||
|
||||
action :create do
|
||||
if new_resource.notify_firewall
|
||||
firewall_resource = run_context.resource_collection.find(firewall: new_resource.firewall_name)
|
||||
def action_create
|
||||
return unless new_resource.notify_firewall
|
||||
|
||||
firewall_resource = Chef.run_context.resource_collection.find(firewall: new_resource.firewall_name)
|
||||
raise 'could not find a firewall resource' unless firewall_resource
|
||||
|
||||
new_resource.notifies(:restart, firewall_resource, :delayed)
|
||||
@ -31,4 +32,3 @@ class Chef
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -29,40 +29,44 @@ class Chef
|
||||
false
|
||||
end
|
||||
|
||||
action :install do
|
||||
next if disabled?(new_resource)
|
||||
def action_install
|
||||
return if disabled?(new_resource)
|
||||
|
||||
converge_by('install ufw, create template for /etc/default') do
|
||||
package 'ufw' do
|
||||
action :install
|
||||
pkg_ufw = package 'ufw' do
|
||||
action :nothing
|
||||
end
|
||||
pkg_ufw.run_action(:install)
|
||||
new_resource.updated_by_last_action(true) if pkg_ufw.updated_by_last_action?
|
||||
|
||||
template '/etc/default/ufw' do
|
||||
action [:create]
|
||||
defaults_ufw = template '/etc/default/ufw' do
|
||||
action :nothing
|
||||
owner 'root'
|
||||
group 'root'
|
||||
mode '0644'
|
||||
source 'ufw/default.erb'
|
||||
cookbook 'firewall'
|
||||
end
|
||||
defaults_ufw.run_action(:create)
|
||||
new_resource.updated_by_last_action(true) if defaults_ufw.updated_by_last_action?
|
||||
|
||||
file "create empty #{ufw_rules_filename}" do
|
||||
path ufw_rules_filename
|
||||
content '# created by chef to allow service to start'
|
||||
not_if { ::File.exist?(ufw_rules_filename) }
|
||||
end
|
||||
end
|
||||
return if ::File.exist?(ufw_rules_filename)
|
||||
|
||||
ufw_file = lookup_or_create_rulesfile
|
||||
ufw_file.content '# created by chef to allow service to start'
|
||||
ufw_file.run_action(:create)
|
||||
|
||||
new_resource.updated_by_last_action(true) if ufw_file.updated_by_last_action?
|
||||
end
|
||||
|
||||
action :restart do
|
||||
next if disabled?(new_resource)
|
||||
def action_restart
|
||||
return if disabled?(new_resource)
|
||||
|
||||
# ensure it's initialized
|
||||
new_resource.rules({}) unless new_resource.rules
|
||||
new_resource.rules['ufw'] = {} unless new_resource.rules['ufw']
|
||||
|
||||
# this populates the hash of rules from firewall_rule resources
|
||||
firewall_rules = run_context.resource_collection.select { |item| item.is_a?(Chef::Resource::FirewallRule) }
|
||||
firewall_rules = Chef.run_context.resource_collection.select { |item| item.is_a?(Chef::Resource::FirewallRule) }
|
||||
firewall_rules.each do |firewall_rule|
|
||||
next unless firewall_rule.action.include?(:create) && !firewall_rule.should_skip?(:create)
|
||||
|
||||
@ -77,18 +81,12 @@ class Chef
|
||||
end
|
||||
|
||||
# ensure a file resource exists with the current ufw rules
|
||||
begin
|
||||
ufw_file = run_context.resource_collection.find(file: ufw_rules_filename)
|
||||
rescue
|
||||
ufw_file = file ufw_rules_filename do
|
||||
action :nothing
|
||||
end
|
||||
end
|
||||
ufw_file = lookup_or_create_rulesfile
|
||||
ufw_file.content build_rule_file(new_resource.rules['ufw'])
|
||||
ufw_file.run_action(:create)
|
||||
|
||||
# if the file was changed, restart iptables
|
||||
if ufw_file.updated_by_last_action?
|
||||
return unless ufw_file.updated_by_last_action?
|
||||
ufw_reset!
|
||||
ufw_logging!(new_resource.log_level) if new_resource.log_level
|
||||
|
||||
@ -100,32 +98,41 @@ class Chef
|
||||
ufw_enable! unless ufw_active?
|
||||
new_resource.updated_by_last_action(true)
|
||||
end
|
||||
end
|
||||
|
||||
action :disable do
|
||||
next if disabled?(new_resource)
|
||||
def action_disable
|
||||
return if disabled?(new_resource)
|
||||
|
||||
file "create empty #{ufw_rules_filename}" do
|
||||
path ufw_rules_filename
|
||||
content '# created by chef to allow service to start'
|
||||
end
|
||||
ufw_file = lookup_or_create_rulesfile
|
||||
ufw_file.content '# created by chef to allow service to start'
|
||||
ufw_file.run_action(:create)
|
||||
new_resource.updated_by_last_action(true) if ufw_file.updated_by_last_action?
|
||||
|
||||
if ufw_active?
|
||||
return unless ufw_active?
|
||||
ufw_disable!
|
||||
new_resource.updated_by_last_action(true)
|
||||
end
|
||||
end
|
||||
|
||||
action :flush do
|
||||
next if disabled?(new_resource)
|
||||
def action_flush
|
||||
return if disabled?(new_resource)
|
||||
|
||||
ufw_reset!
|
||||
new_resource.updated_by_last_action(true)
|
||||
|
||||
file "create empty #{ufw_rules_filename}" do
|
||||
path ufw_rules_filename
|
||||
content '# created by chef to allow service to start'
|
||||
end
|
||||
ufw_file = lookup_or_create_rulesfile
|
||||
ufw_file.content '# created by chef to allow service to start'
|
||||
ufw_file.run_action(:create)
|
||||
new_resource.updated_by_last_action(true) if ufw_file.updated_by_last_action?
|
||||
end
|
||||
|
||||
def lookup_or_create_rulesfile
|
||||
begin
|
||||
ufw_file = Chef.run_context.resource_collection.find(file: ufw_rules_filename)
|
||||
rescue
|
||||
ufw_file = file ufw_rules_filename do
|
||||
action :nothing
|
||||
end
|
||||
end
|
||||
ufw_file
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -26,8 +26,8 @@ class Chef
|
||||
false
|
||||
end
|
||||
|
||||
action :install do
|
||||
next if disabled?(new_resource)
|
||||
def action_install
|
||||
return if disabled?(new_resource)
|
||||
|
||||
svc = service 'MpsSvc' do
|
||||
action :nothing
|
||||
@ -39,14 +39,14 @@ class Chef
|
||||
end
|
||||
end
|
||||
|
||||
action :restart do
|
||||
next if disabled?(new_resource)
|
||||
def action_restart
|
||||
return if disabled?(new_resource)
|
||||
|
||||
# ensure it's initialized
|
||||
new_resource.rules({}) unless new_resource.rules
|
||||
new_resource.rules['windows'] = {} unless new_resource.rules['windows']
|
||||
|
||||
firewall_rules = run_context.resource_collection.select { |item| item.is_a?(Chef::Resource::FirewallRule) }
|
||||
firewall_rules = Chef.run_context.resource_collection.select { |item| item.is_a?(Chef::Resource::FirewallRule) }
|
||||
firewall_rules.each do |firewall_rule|
|
||||
next unless firewall_rule.action.include?(:create) && !firewall_rule.should_skip?(:create)
|
||||
|
||||
@ -69,7 +69,7 @@ class Chef
|
||||
|
||||
# ensure a file resource exists with the current rules
|
||||
begin
|
||||
windows_file = run_context.resource_collection.find(file: windows_rules_filename)
|
||||
windows_file = Chef.run_context.resource_collection.find(file: windows_rules_filename)
|
||||
rescue
|
||||
windows_file = file windows_rules_filename do
|
||||
action :nothing
|
||||
@ -79,7 +79,8 @@ class Chef
|
||||
windows_file.run_action(:create)
|
||||
|
||||
# if the file was changed, restart iptables
|
||||
if windows_file.updated_by_last_action?
|
||||
return unless windows_file.updated_by_last_action?
|
||||
|
||||
disable! if active?
|
||||
delete_all_rules! # clear entirely
|
||||
reset! # populate default rules
|
||||
@ -92,10 +93,9 @@ class Chef
|
||||
|
||||
new_resource.updated_by_last_action(true)
|
||||
end
|
||||
end
|
||||
|
||||
action :disable do
|
||||
next if disabled?(new_resource)
|
||||
def action_disable
|
||||
return if disabled?(new_resource)
|
||||
|
||||
if active?
|
||||
disable!
|
||||
@ -115,8 +115,8 @@ class Chef
|
||||
end
|
||||
end
|
||||
|
||||
action :flush do
|
||||
next if disabled?(new_resource)
|
||||
def action_flush
|
||||
return if disabled?(new_resource)
|
||||
|
||||
reset!
|
||||
Chef::Log.info("#{new_resource} reset.")
|
||||
|
File diff suppressed because one or more lines are too long
@ -27,6 +27,21 @@ end
|
||||
# create a variable to use as a condition on some rules that follow
|
||||
iptables_firewall = rhel? || node['firewall']['ubuntu_iptables']
|
||||
|
||||
firewall_rule 'allow loopback' do
|
||||
interface 'lo'
|
||||
protocol :none
|
||||
command :allow
|
||||
only_if { linux? && node['firewall']['allow_loopback'] }
|
||||
end
|
||||
|
||||
firewall_rule 'allow icmp' do
|
||||
protocol :icmp
|
||||
command :allow
|
||||
# debian ufw doesn't allow 'icmp' protocol, but does open
|
||||
# icmp by default, so we skip it in default recipe
|
||||
only_if { (!debian? || iptables_firewall) && node['firewall']['allow_icmp'] }
|
||||
end
|
||||
|
||||
firewall_rule 'allow world to ssh' do
|
||||
port 22
|
||||
source '0.0.0.0/0'
|
||||
|
@ -1,9 +1,8 @@
|
||||
#
|
||||
# Author:: Matt Ray <matt@chef.io>
|
||||
# Cookbook:: ufw
|
||||
# Recipe:: disable
|
||||
# Cookbook:: firewall
|
||||
# Recipe:: disable_firewall
|
||||
#
|
||||
# Copyright:: 2011-2017, Chef Software, Inc.
|
||||
# Copyright:: 2011-2016, Chef Software, Inc.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
@ -18,6 +17,7 @@
|
||||
# limitations under the License.
|
||||
#
|
||||
|
||||
firewall 'ufw' do
|
||||
# Disable platform default firewall
|
||||
firewall 'default' do
|
||||
action :disable
|
||||
end
|
@ -1 +0,0 @@
|
||||
~FC003
|
@ -1,47 +0,0 @@
|
||||
# ufw Cookbook CHANGELOG
|
||||
This file is used to list changes made in each version of the ufw cookbook.
|
||||
|
||||
## 3.1.0 (2017-03-02)
|
||||
- Add use of the default['firewall']['allow_ssh'] attribute in the default recipe. Default for this cookbook is set to true, as the default recipe assumed that ssh would be enabled.
|
||||
|
||||
## 3.0.0 (2017-03-01)
|
||||
- Require Chef 12.4 (Depends on firewall which requires Chef 12.4+ at this point)
|
||||
- Update default to remove installation of ufw which is duplication from firewall cookbook, and remove state changes
|
||||
- Due to the change in default recipe, bumping major version in case this is breaking change for some.
|
||||
- Added debian platform as firewall cookbook supports ufw on debian
|
||||
|
||||
## 2.0.0 (2016-11-25)
|
||||
- Add chef_version metadata + remove chef 11 compat
|
||||
- Replace node.set with node.normal
|
||||
- Require Chef 12.1
|
||||
- Fix the recipe to properly converge
|
||||
|
||||
## v1.0.0 (12-14-2015)
|
||||
- Update to use / require the Firewall v2.0.0+ cookbook, which requires Chef 12
|
||||
- Updated all Opscode references to Chef Software Inc.
|
||||
- Updated testing, contributing, and maintainers docs
|
||||
- Added source_url and issues_url metadata for supermarket
|
||||
- Resolved all rubocop warnings and add the standard Chef rubocop file
|
||||
- Added travis and supermarket version badges to the readme
|
||||
- Added requirements section to the readme
|
||||
- Added a chefignore file
|
||||
- Added a Rakefile for simplified testing
|
||||
- Added a basic converge chefspec
|
||||
|
||||
## v0.7.4
|
||||
No change. Version bump for toolchain
|
||||
|
||||
## v0.7.2
|
||||
Updating metadata to depend on firewall >= 0.9
|
||||
|
||||
## v0.7.0
|
||||
[COOK-3592] - allow source ports to be defined as a range in ufw
|
||||
|
||||
## v0.6.4
|
||||
### Bug
|
||||
- **[COOK-3316](https://tickets.chef.io/browse/COOK-3316)** - Fix README.md example
|
||||
|
||||
## v0.6.2
|
||||
### Bug
|
||||
- [COOK-2487]: when setting a node attribute you must specify the precedence
|
||||
- [COOK-2982]: ufw cookbook has foodcritic failures
|
@ -1,2 +0,0 @@
|
||||
Please refer to
|
||||
https://github.com/chef-cookbooks/community_cookbook_documentation/blob/master/CONTRIBUTING.MD
|
@ -1,15 +0,0 @@
|
||||
<!-- This is a generated file. Please do not edit directly -->
|
||||
|
||||
# Maintainers
|
||||
|
||||
This file lists how this cookbook project is maintained. When making changes to the system, this file tells you who needs to review your patch - you need a review from an existing maintainer for the cookbook to provide a :+1: on your pull request. Additionally, you need to not receive a veto from a Lieutenant or the Project Lead.
|
||||
|
||||
Check out [How Cookbooks are Maintained](https://github.com/chef-cookbooks/community_cookbook_documentation/blob/master/CONTRIBUTING.MD) for details on the process and how to become a maintainer or the project lead.
|
||||
|
||||
# Project Maintainer
|
||||
* [Tim Smith](https://github.com/tas50)
|
||||
|
||||
# Maintainers
|
||||
* [Jennifer Davis](https://github.com/sigje)
|
||||
* [Tim Smith](https://github.com/tas50)
|
||||
* [Thom May](https://github.com/thommay)
|
@ -1,173 +0,0 @@
|
||||
# Description
|
||||
|
||||
[](http://travis-ci.org/chef-cookbooks/ufw) [](https://supermarket.chef.io/cookbooks/ufw)
|
||||
|
||||
Configures Uncomplicated Firewall (ufw) on Ubuntu and Debian. Including the `ufw` recipe in a run list means the firewall will be enabled and will deny everything except SSH and ICMP ping by default.
|
||||
|
||||
Rules may be added to the node by adding them to the `['firewall']['rules']` attributes in roles or on the node directly. The `firewall` cookbook has an LWRP that may be used to apply rules directly from other recipes as well. There is no need to explicitly remove rules, they are reevaluated on changes and reset. Rules are applied in the order of the run list, unless ordering is explicitly added.
|
||||
|
||||
## Requirements
|
||||
|
||||
### Platforms
|
||||
|
||||
- Ubuntu
|
||||
- Debian
|
||||
|
||||
### Chef
|
||||
|
||||
- Chef 12.4+
|
||||
|
||||
### Cookbooks
|
||||
|
||||
- firewall 2.0+
|
||||
|
||||
## Recipes
|
||||
|
||||
### default
|
||||
|
||||
The `default` recipe looks for the list of firewall rules to apply from the `['firewall']['rules']` attribute added to roles and on the node itself. The list of rules is then applied to the node in the order specified.
|
||||
|
||||
### disable
|
||||
|
||||
The `disable` recipe is used if there is a need to disable the existing firewall, perhaps for testing. It disables the ufw firewall even if other ufw recipes attempt to enable it.
|
||||
|
||||
If you remove this recipe, the firewall does not get automatically re-enabled. You will need clear the value of the `['firewall']['state']` to force a recalculation of the firewall rules. This can be done with `knife node edit`.
|
||||
|
||||
### databag
|
||||
|
||||
The `databag` recipe looks in the `firewall` data bag for to apply firewall rules based on inspecting the runlist for roles and recipe names for keys that map to the data bag items and are applied in the the order specified.
|
||||
|
||||
The `databag` recipe calls the `default` recipe after the `['firewall']['rules']` attribute is set to apply the rules, so you may mix roles with databag items if you want (roles apply first, then data bag contents).
|
||||
|
||||
### recipes
|
||||
|
||||
The `recipes` recipe applies firewall rules based on inspecting the runlist for recipes that have node[
|
||||
|
||||
<recipe>]['firewall']['rules'] attributes. These are appended to node['firewall']['rules'] and applied to the node. Cookbooks may define attributes for recipes like so:</recipe>
|
||||
|
||||
#### attributes/default.rb for test cookbook
|
||||
|
||||
```ruby
|
||||
default['test']['firewall']['rules'] = [
|
||||
{"test"=> {
|
||||
"port"=> "27901",
|
||||
"protocol"=> "udp"
|
||||
}
|
||||
}
|
||||
]
|
||||
default['test::awesome']['firewall']['rules'] = [
|
||||
{"awesome"=> {
|
||||
"port"=> "99427",
|
||||
"protocol"=> "udp"
|
||||
}
|
||||
},
|
||||
{"awesome2"=> {
|
||||
"port"=> "99428"
|
||||
}
|
||||
}
|
||||
]
|
||||
```
|
||||
|
||||
Note that the 'test::awesome' rules are only applied if that specific recipe is in the runlist. Recipe-applied firewall rules are applied after any rules defined in role attributes.
|
||||
|
||||
### securitylevel
|
||||
|
||||
The `securitylevel` recipe is used if there are any node['firewall']['securitylevel'] settings that need to be enforced. It is a reference implementation with nothing configured.
|
||||
|
||||
## Attributes
|
||||
|
||||
Roles and the node may have the `['firewall']['rules']` attribute set. This attribute is a list of hashes, the key will be rule name, the value will be the hash of parameters. Application order is based on run list.
|
||||
|
||||
### Example Role
|
||||
|
||||
```ruby
|
||||
name "fw_example"
|
||||
description "Firewall rules for Examples"
|
||||
override_attributes(
|
||||
"firewall" => {
|
||||
"rules" => [
|
||||
{"tftp" => {}},
|
||||
{"http" => {
|
||||
"port" => "80"
|
||||
}
|
||||
},
|
||||
{"block tomcat from 192.168.1.0/24" => {
|
||||
"port" => "8080",
|
||||
"source" => "192.168.1.0/24",
|
||||
"action" => "deny"
|
||||
}
|
||||
},
|
||||
{"Allow access to udp 1.2.3.4 port 5469 from 1.2.3.5 port 5469" => {
|
||||
"protocol" => "udp",
|
||||
"port" => "5469",
|
||||
"source" => "1.2.3.4",
|
||||
"destination" => "1.2.3.5",
|
||||
"dest_port" => "5469"
|
||||
}
|
||||
},
|
||||
{"allow to tcp ports 8000-8010 from 192.168.1.0/24" => {
|
||||
"port_range" => "8000..8010",
|
||||
"source" => "192.168.1.0/24",
|
||||
"protocol" => "tcp" //protocol is mandatory when using port ranges
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
)
|
||||
```
|
||||
|
||||
* default['firewall']['allow_ssh'] Opens port 22 for SSH when set to true. Default set to true.
|
||||
|
||||
## Data Bags
|
||||
|
||||
The `firewall` data bag may be used with the `databag` recipe. It will contain items that map to role names (eg. the 'apache' role will map to the 'apache' item in the 'firewall' data bag). Either roles or recipes may be keys (role[webserver] is 'webserver', recipe[apache2] is 'apache2'). If you have recipe-specific firewall rules, you will need to replace the '::' with '**' (double underscores) (eg. recipe[apache2::mod_ssl] is 'apache2**mod_ssl' in the data bag item).
|
||||
|
||||
The items in the data bag will contain a 'rules' array of hashes to apply to the `['firewall']['rules']` attribute.
|
||||
|
||||
```shell
|
||||
% knife data bag create firewall
|
||||
% knife data bag from file firewall examples/data_bags/firewall/apache2.json
|
||||
% knife data bag from file firewall examples/data_bags/firewall/apache2__mod_ssl.json
|
||||
```
|
||||
|
||||
### Example 'firewall' data bag item
|
||||
|
||||
```javascript
|
||||
{
|
||||
"id": "apache2",
|
||||
"rules": [
|
||||
{"http": {
|
||||
"port": "80"
|
||||
}},
|
||||
{"block http from 192.168.1.0/24": {
|
||||
"port": "80",
|
||||
"source": "192.168.1.0/24",
|
||||
"action": "deny"
|
||||
}}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
## Resources/Providers
|
||||
|
||||
The `firewall` cookbook provides the `firewall` and `firewall_rule` LWRPs, for which there is a ufw provider.
|
||||
|
||||
## License & Authors
|
||||
|
||||
**Author:** Cookbook Engineering Team ([cookbooks@chef.io](mailto:cookbooks@chef.io))
|
||||
|
||||
**Copyright:** 2011-2014, Chef Software, Inc.
|
||||
|
||||
```
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
```
|
@ -1,3 +0,0 @@
|
||||
default['firewall']['rules'] = []
|
||||
default['firewall']['securitylevel'] = ''
|
||||
default['firewall']['allow_ssh'] = true
|
File diff suppressed because one or more lines are too long
@ -1,58 +0,0 @@
|
||||
#
|
||||
# Author:: Matt Ray <matt@chef.io>
|
||||
# Cookbook:: ufw
|
||||
# Recipe:: databag
|
||||
#
|
||||
# Copyright:: 2011-2017, Chef Software, Inc.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
|
||||
# flatten the run_list to just the names of the roles and recipes in order
|
||||
def run_list_names(run_list)
|
||||
names = []
|
||||
run_list.each do |entry|
|
||||
Chef::Log.debug "ufw::databag:run_list_names+name: #{entry.name}"
|
||||
if entry.name.index('::') # cookbook::recipe
|
||||
names.push(entry.name.sub('::', '__'))
|
||||
else
|
||||
names.push(entry.name)
|
||||
end
|
||||
if entry.role?
|
||||
rol = search(:role, "name:#{entry.name}")[0]
|
||||
names.concat(run_list_names(rol.run_list))
|
||||
end
|
||||
end
|
||||
Chef::Log.debug "ufw::databag:run_list_names+names: #{names}"
|
||||
names
|
||||
end
|
||||
|
||||
rlist = run_list_names(node.run_list)
|
||||
rlist.uniq!
|
||||
Chef::Log.debug "ufw::databag:rlist: #{rlist}"
|
||||
|
||||
fw_db = data_bag('firewall')
|
||||
Chef::Log.debug "ufw::databag:firewall:#{fw_db}"
|
||||
|
||||
rlist.each do |entry|
|
||||
Chef::Log.debug "ufw::databag: \"#{entry}\""
|
||||
next unless fw_db.member?(entry)
|
||||
|
||||
# add the list of firewall rules to the current list
|
||||
item = data_bag_item('firewall', entry)
|
||||
rules = item['rules']
|
||||
node.normal['firewall']['rules'].concat(rules) unless rules.nil?
|
||||
end
|
||||
|
||||
# now go apply the rules
|
||||
include_recipe 'ufw::default'
|
@ -1,71 +0,0 @@
|
||||
#
|
||||
# Author:: Matt Ray <matt@chef.io>
|
||||
# Cookbook:: ufw
|
||||
# Recipe:: default
|
||||
#
|
||||
# Copyright:: 2011-2017, Chef Software, Inc.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
|
||||
firewall 'default' do
|
||||
action :install
|
||||
end
|
||||
|
||||
# leave this on by default
|
||||
firewall_rule 'ssh' do
|
||||
port 22
|
||||
action :create
|
||||
only_if { node['firewall']['allow_ssh'] }
|
||||
end
|
||||
|
||||
node['firewall']['rules'].each do |rule_mash|
|
||||
Chef::Log.debug "ufw:rule \"#{rule_mash}\""
|
||||
rule_mash.keys.each do |rule|
|
||||
Chef::Log.debug "ufw:rule:name \"#{rule}\""
|
||||
params = rule_mash[rule]
|
||||
Chef::Log.debug "ufw:rule:parameters \"#{params}\""
|
||||
Chef::Log.debug "ufw:rule:name #{params['name']}" if params['name']
|
||||
Chef::Log.debug "ufw:rule:protocol #{params['protocol']}" if params['protocol']
|
||||
Chef::Log.debug "ufw:rule:direction #{params['direction']}" if params['direction']
|
||||
Chef::Log.debug "ufw:rule:interface #{params['interface']}" if params['interface']
|
||||
Chef::Log.debug "ufw:rule:logging #{params['logging']}" if params['logging']
|
||||
Chef::Log.debug "ufw:rule:port #{params['port']}" if params['port']
|
||||
Chef::Log.debug "ufw:rule:port_range #{params['port_range']}" if params['port_range']
|
||||
Chef::Log.debug "ufw:rule:source #{params['source']}" if params['source']
|
||||
Chef::Log.debug "ufw:rule:destination #{params['destination']}" if params['destination']
|
||||
Chef::Log.debug "ufw:rule:dest_port #{params['dest_port']}" if params['dest_port']
|
||||
Chef::Log.debug "ufw:rule:position #{params['position']}" if params['position']
|
||||
act = params['action']
|
||||
act ||= 'create'
|
||||
raise 'ufw: port_range was specified to firewall_rule without protocol' if params['port_range'] && !params['protocol']
|
||||
Chef::Log.debug "ufw:rule:action :#{act}"
|
||||
firewall_rule rule do
|
||||
name params['name'] if params['name']
|
||||
protocol params['protocol'].to_sym if params['protocol']
|
||||
direction params['direction'].to_sym if params['direction']
|
||||
interface params['interface'] if params['interface']
|
||||
logging params['logging'].to_sym if params['logging']
|
||||
port params['port'].to_i if params['port']
|
||||
if params['port_range']
|
||||
ends = params['port_range'].split('..').map { |d| Integer(d) }
|
||||
port_range ends[0]..ends[1]
|
||||
end
|
||||
source params['source'] if params['source']
|
||||
destination params['destination'] if params['destination']
|
||||
dest_port params['dest_port'].to_i if params['dest_port']
|
||||
position params['position'].to_i if params['position']
|
||||
action act
|
||||
end
|
||||
end
|
||||
end
|
@ -1,41 +0,0 @@
|
||||
#
|
||||
# Author:: Matt Ray <matt@chef.io>
|
||||
# Cookbook:: ufw
|
||||
# Recipe:: recipes
|
||||
#
|
||||
# Copyright:: 2011-2017, Chef Software, Inc.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
|
||||
# expand and parse the node's runlist for recipes and find attributes of the form node[<recipe>]['firewall']['rules']
|
||||
# append them to the node['firewall']['rules'] array attribute
|
||||
node.expand!.recipes.each do |recipe|
|
||||
Chef::Log.debug "ufw::recipes: #{recipe}"
|
||||
cookbook = recipe.split('::')[0]
|
||||
# get the cookbook attributes if there are any
|
||||
if recipe != cookbook && node[cookbook] && node[cookbook]['firewall'] && node[cookbook]['firewall']['rules']
|
||||
rules = node[cookbook]['firewall']['rules']
|
||||
Chef::Log.debug "ufw::recipes:#{cookbook}:rules #{rules}"
|
||||
node.normal['firewall']['rules'].concat(rules) unless rules.nil?
|
||||
end
|
||||
# get the recipe attributes if there are any
|
||||
next unless node[recipe] && node[recipe]['firewall'] && node[recipe]['firewall']['rules']
|
||||
|
||||
rules = node[recipe]['firewall']['rules']
|
||||
Chef::Log.debug "ufw::recipes:#{recipe}:rules #{rules}"
|
||||
node.normal['firewall']['rules'].concat(rules) unless rules.nil?
|
||||
end
|
||||
|
||||
# now go apply the rules
|
||||
include_recipe 'ufw::default'
|
@ -1,41 +0,0 @@
|
||||
#
|
||||
# Author:: Matt Ray <matt@chef.io>
|
||||
# Cookbook:: ufw
|
||||
# Recipe:: securitylevel
|
||||
#
|
||||
# Copyright:: 2011-2017, Chef Software, Inc.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
|
||||
securitylevel = node['firewall']['securitylevel']
|
||||
|
||||
Chef::Log.info "ufw::securitylevel:#{securitylevel}"
|
||||
|
||||
# verify that only 1 "color" security group is applied"
|
||||
count = node.expand!.roles.count { |role| role =~ /SecurityLevel-(Red|Green|Yellow)/ }
|
||||
if count > 1
|
||||
raise Chef::Exceptions::AmbiguousRunlistSpecification, "conflicting SecurityLevel-'color' roles, only 1 may be applied."
|
||||
end
|
||||
|
||||
# case securitylevel
|
||||
# when 'red'
|
||||
# # put special stuff for red here
|
||||
# when 'yellow'
|
||||
# # put special stuff for red here
|
||||
# when 'green'
|
||||
# # put special stuff for red here
|
||||
# end
|
||||
|
||||
# now go apply the rules
|
||||
include_recipe 'ufw::default'
|
@ -11,6 +11,6 @@ depends 'users'
|
||||
depends 'sudo'
|
||||
depends 'kosmos-postfix'
|
||||
depends 'hostname'
|
||||
depends 'ufw'
|
||||
depends 'firewall'
|
||||
depends 'omnibus_updater'
|
||||
depends 'timezone-ii'
|
||||
|
Loading…
x
Reference in New Issue
Block a user