diff --git a/libraries/helpers.rb b/libraries/helpers.rb index 9eb3e58b..87d73efa 100644 --- a/libraries/helpers.rb +++ b/libraries/helpers.rb @@ -1,5 +1,6 @@ module FirewallCookbook module Helpers + def dport_calc(new_resource) new_resource.dest_port || new_resource.port end @@ -9,6 +10,8 @@ def port_to_s(p) p.to_s elsif p && p.is_a?(Array) p.sort.join(',') + elsif p && p.is_a?(Range) && node['platform_family'] == 'windows' + "#{p.first}-#{p.last}" elsif p && p.is_a?(Range) "#{p.first}:#{p.last}" end @@ -71,6 +74,9 @@ def build_rule_file(rules) contents << "# position #{sorted_value}" rules.each do |k, v| next unless v == sorted_value + if k.include?("COMMIT_") + k = "COMMIT" + end contents << k end end diff --git a/libraries/helpers_iptables.rb b/libraries/helpers_iptables.rb index 72f6f497..afd8a986 100644 --- a/libraries/helpers_iptables.rb +++ b/libraries/helpers_iptables.rb @@ -5,24 +5,27 @@ module Iptables include Chef::Mixin::ShellOut CHAIN = { in: 'INPUT', out: 'OUTPUT', pre: 'PREROUTING', post: 'POSTROUTING' } unless defined? CHAIN # , nil => "FORWARD"} - TARGET = { allow: 'ACCEPT', reject: 'REJECT', deny: 'DROP', masquerade: 'MASQUERADE', redirect: 'REDIRECT', log: 'LOG --log-prefix "iptables: " --log-level 7' } unless defined? TARGET + TARGET = { allow: 'ACCEPT', reject: 'REJECT', deny: 'DROP', masquerade: 'MASQUERADE', redirect: 'REDIRECT', log: 'LOG --log-prefix "iptables: " --log-level 7', snat: 'SNAT' } unless defined? TARGET def build_firewall_rule(current_node, rule_resource, ipv6 = false) - el5 = (current_node['platform'] == 'rhel' || current_node['platform'] == 'centos') && Gem::Dependency.new('', '~> 5.0').match?('', current_node['platform_version']) + el5 = (current_node['platform'] == 'rhel' || current_node['platform'] == 'centos' || current_node['platform'] == 'amazon') && Gem::Dependency.new('', '~> 5.0').match?('', current_node['platform_version']) if rule_resource.raw firewall_rule = rule_resource.raw.strip else - firewall_rule = '-A ' + firewall_rule = ' ' + + #if [:pre, :post].include?(rule_resource.direction) + # firewall_rule << '-t nat ' + #end + if rule_resource.direction - firewall_rule << "#{CHAIN[rule_resource.direction.to_sym]} " + firewall_rule << "-A #{CHAIN[rule_resource.direction.to_sym]} " else - firewall_rule << 'FORWARD ' + firewall_rule << '-A FORWARD ' end - if [:pre, :post].include?(rule_resource.direction) - firewall_rule << '-t nat ' - end +# iptables -t nat -A POSTROUTING -o eth0 -p tcp -d 10.200.110.21 -j SNAT --to-source 10.200.110.6 # Iptables order of prameters is important here see example output below: # -A INPUT -s 1.2.3.4/32 -d 5.6.7.8/32 -i lo -p tcp -m tcp -m state --state NEW -m comment --comment "hello" -j DROP @@ -46,6 +49,10 @@ def build_firewall_rule(current_node, rule_resource, ipv6 = false) end firewall_rule << "-j #{TARGET[rule_resource.command.to_sym]} " + + # Adding to-source for iptables -t nat type of rules + firewall_rule << "--to-source #{rule_resource.to_source} " if rule_resource.command == :snat + firewall_rule << "--to-ports #{rule_resource.redirect_port} " if rule_resource.action == :redirect firewall_rule.strip! @@ -93,11 +100,16 @@ def iptables_default_allow!(new_resource) def default_ruleset(current_node) { - '*filter' => 1, - ":INPUT #{current_node['firewall']['iptables']['defaults'][:policy][:input]}" => 2, - ":FORWARD #{current_node['firewall']['iptables']['defaults'][:policy][:forward]}" => 3, - ":OUTPUT #{current_node['firewall']['iptables']['defaults'][:policy][:output]}" => 4, - 'COMMIT' => 100 + '*nat' => 1, + ':PREROUTING ACCEPT' => 2, + ':POSTROUTING ACCEPT' => 3, + ':OUTPUT ACCEPT' => 4, + 'COMMIT_NAT' => 100, + '*filter' => 101, + ":INPUT #{current_node['firewall']['iptables']['defaults'][:policy][:input]}" => 102, + ":FORWARD #{current_node['firewall']['iptables']['defaults'][:policy][:forward]}" => 103, + ":OUTPUT #{current_node['firewall']['iptables']['defaults'][:policy][:output]}" => 104, + 'COMMIT_FILTER' => 200 } end diff --git a/libraries/helpers_windows.rb b/libraries/helpers_windows.rb index e42ccc42..0d488603 100644 --- a/libraries/helpers_windows.rb +++ b/libraries/helpers_windows.rb @@ -65,16 +65,16 @@ def build_rule(new_resource) if new_resource.direction.to_sym == :out parameters['localip'] = new_resource.source ? fixup_cidr(new_resource.source) : 'any' - parameters['localport'] = new_resource.source_port ? port_to_s(new_resource.source_port) : 'any' + parameters['localport'] = new_resource.source_port ? port_to_s(new_resource.source_port) : 'any' unless new_resource.protocol == 'icmpv4' parameters['interfacetype'] = new_resource.source_interface ? new_resource.source_interface : 'any' parameters['remoteip'] = new_resource.destination ? fixup_cidr(new_resource.destination) : 'any' - parameters['remoteport'] = port_to_s(new_resource.dest_port) ? new_resource.dest_port : 'any' + parameters['remoteport'] = port_to_s(new_resource.dest_port) ? new_resource.dest_port : 'any' unless new_resource.protocol == 'icmpv4' else parameters['localip'] = new_resource.destination ? new_resource.destination : 'any' - parameters['localport'] = dport_calc(new_resource) ? port_to_s(dport_calc(new_resource)) : 'any' + parameters['localport'] = dport_calc(new_resource) ? port_to_s(dport_calc(new_resource)) : 'any' unless new_resource.protocol == 'icmpv4' parameters['interfacetype'] = new_resource.dest_interface ? new_resource.dest_interface : 'any' parameters['remoteip'] = new_resource.source ? fixup_cidr(new_resource.source) : 'any' - parameters['remoteport'] = new_resource.source_port ? port_to_s(new_resource.source_port) : 'any' + parameters['remoteport'] = new_resource.source_port ? port_to_s(new_resource.source_port) : 'any' unless new_resource.protocol == 'icmpv4' end parameters['action'] = type.to_s diff --git a/libraries/provider_firewall_firewalld.rb b/libraries/provider_firewall_firewalld.rb index 7ed69680..540d6afa 100644 --- a/libraries/provider_firewall_firewalld.rb +++ b/libraries/provider_firewall_firewalld.rb @@ -20,7 +20,7 @@ class Provider::FirewallFirewalld < Chef::Provider::LWRPBase include FirewallCookbook::Helpers::Firewalld provides :firewall, os: 'linux', platform_family: %w(rhel fedora) do |node| - node['platform_version'].to_f >= 7.0 && !node['firewall']['redhat7_iptables'] + node['platform_version'].to_f >= 7.0 && !node['firewall']['redhat7_iptables'] && !(node['platform'] == 'amazon') end def whyrun_supported? diff --git a/libraries/provider_firewall_iptables.rb b/libraries/provider_firewall_iptables.rb index 7d484c46..157ce5b3 100644 --- a/libraries/provider_firewall_iptables.rb +++ b/libraries/provider_firewall_iptables.rb @@ -23,7 +23,7 @@ class Provider::FirewallIptables < Chef::Provider::LWRPBase include FirewallCookbook::Helpers::Iptables provides :firewall, os: 'linux', platform_family: %w(rhel fedora) do |node| - node['platform_version'].to_f < 7.0 || node['firewall']['redhat7_iptables'] + node['platform_version'].to_f < 7.0 || node['platform'] == 'amazon' || node['firewall']['redhat7_iptables'] end def whyrun_supported? diff --git a/libraries/provider_firewall_rule_firewalld.rb b/libraries/provider_firewall_rule_firewalld.rb index 13a0cc15..b46dac82 100644 --- a/libraries/provider_firewall_rule_firewalld.rb +++ b/libraries/provider_firewall_rule_firewalld.rb @@ -22,7 +22,7 @@ class Provider::FirewallRuleFirewalld < Chef::Provider::LWRPBase include FirewallCookbook::Helpers::Firewalld provides :firewall_rule, os: 'linux', platform_family: %w(rhel fedora) do |node| - node['platform_version'].to_f >= 7.0 && !node['firewall']['redhat7_iptables'] + node['platform_version'].to_f >= 7.0 && !node['firewall']['redhat7_iptables'] && !(node['platform'] == 'amazon') end action :create do diff --git a/libraries/provider_firewall_rule_iptables.rb b/libraries/provider_firewall_rule_iptables.rb index 3f60a629..d7104e86 100644 --- a/libraries/provider_firewall_rule_iptables.rb +++ b/libraries/provider_firewall_rule_iptables.rb @@ -20,7 +20,7 @@ class Provider::FirewallRuleIptables < Chef::Provider::LWRPBase include FirewallCookbook::Helpers::Iptables provides :firewall_rule, os: 'linux', platform_family: %w(rhel fedora) do |node| - node['platform_version'].to_f < 7.0 || node['firewall']['redhat7_iptables'] + node['platform_version'].to_f < 7.0 || node['platform'] == 'amazon' || node['firewall']['redhat7_iptables'] end action :create do @@ -44,8 +44,12 @@ class Provider::FirewallRuleIptables < Chef::Provider::LWRPBase types.each do |iptables_type| # build rules to apply with weight k = build_firewall_rule(node, new_resource, iptables_type == 'ip6tables') - v = new_resource.position - + unless k.include?("SNAT") + v = new_resource.position + else + v = new_resource.nat_position + end + # unless we're adding them for the first time.... bail out. next if firewall.rules[iptables_type].key?(k) && firewall.rules[iptables_type][k] == v diff --git a/libraries/resource_firewall_rule.rb b/libraries/resource_firewall_rule.rb index 25c64b4b..4242cfea 100644 --- a/libraries/resource_firewall_rule.rb +++ b/libraries/resource_firewall_rule.rb @@ -11,7 +11,7 @@ class Resource::FirewallRule < Chef::Resource::LWRPBase attribute(:firewall_name, kind_of: String, default: 'default') - attribute(:command, kind_of: Symbol, equal_to: [:reject, :allow, :deny, :masquerade, :redirect, :log], default: :allow) + attribute(:command, kind_of: Symbol, equal_to: [:reject, :allow, :deny, :masquerade, :redirect, :log, :snat], default: :allow) attribute(:protocol, kind_of: [Integer, Symbol], default: :tcp, callbacks: { 'must be either :tcp, :udp, :icmp, :\'ipv6-icmp\', :icmpv6, :none, or a valid IP protocol number' => lambda do |p| @@ -31,7 +31,9 @@ class Resource::FirewallRule < Chef::Resource::LWRPBase attribute(:dest_port, kind_of: [Integer, Array, Range]) attribute(:dest_interface, kind_of: String) - attribute(:position, kind_of: Integer, default: 50) + + attribute(:nat_position, kind_of: Integer, default: 50) + attribute(:position, kind_of: Integer, default: 150) attribute(:stateful, kind_of: [Symbol, Array]) attribute(:redirect_port, kind_of: Integer) attribute(:description, kind_of: String, name_attribute: true) @@ -43,6 +45,9 @@ class Resource::FirewallRule < Chef::Resource::LWRPBase attribute(:program, kind_of: String) attribute(:service, kind_of: String) + # --to-source option for nat in iptables + attribute(:to_source, kind_of: String) + # for when you just want to pass a raw rule attribute(:raw, kind_of: String) end diff --git a/metadata.rb b/metadata.rb index c9d1d725..e2966c43 100644 --- a/metadata.rb +++ b/metadata.rb @@ -4,7 +4,7 @@ license 'Apache 2.0' description 'Provides a set of primitives for managing firewalls and associated rules.' long_description IO.read(File.join(File.dirname(__FILE__), 'README.md')) -version '2.2.0' +version '2.2.9008' supports 'amazon' supports 'centos' @@ -15,7 +15,7 @@ supports 'scientific' supports 'ubuntu' -depends 'chef-sugar' +depends 'chef-sugar', '<=3.5.0' source_url 'https://github.com/chef-cookbooks/firewall' if respond_to?(:source_url) issues_url 'https://github.com/chef-cookbooks/firewall/issues' if respond_to?(:issues_url) diff --git a/recipes/default.rb b/recipes/default.rb index 6b68cdcb..cba02340 100644 --- a/recipes/default.rb +++ b/recipes/default.rb @@ -25,7 +25,7 @@ end # create a variable to use as a condition on some rules that follow -iptables_firewall = rhel? || node['firewall']['ubuntu_iptables'] +iptables_firewall = rhel? || node['firewall']['ubuntu_iptables'] || (node['platform'] == 'amazon') firewall_rule 'allow world to ssh' do port 22