117 lines
		
	
	
		
			5.0 KiB
		
	
	
	
		
			Ruby
		
	
	
	
	
	
			
		
		
	
	
			117 lines
		
	
	
		
			5.0 KiB
		
	
	
	
		
			Ruby
		
	
	
	
	
	
module FirewallCookbook
 | 
						|
  module Helpers
 | 
						|
    module Firewalld
 | 
						|
      include FirewallCookbook::Helpers
 | 
						|
      include Chef::Mixin::ShellOut
 | 
						|
 | 
						|
      def firewalld_rules_filename
 | 
						|
        '/etc/sysconfig/firewalld-chef.rules'
 | 
						|
      end
 | 
						|
 | 
						|
      def firewalld_rule!(cmd)
 | 
						|
        shell_out!(cmd, input: 'yes')
 | 
						|
      end
 | 
						|
 | 
						|
      def firewalld_active?
 | 
						|
        cmd = shell_out('firewall-cmd', '--state')
 | 
						|
        cmd.stdout =~ /^running$/
 | 
						|
      end
 | 
						|
 | 
						|
      def firewalld_default_zone?(z)
 | 
						|
        return false unless firewalld_active?
 | 
						|
 | 
						|
        cmd = shell_out('firewall-cmd', '--get-default-zone')
 | 
						|
        cmd.stdout =~ /^#{z}$/
 | 
						|
      end
 | 
						|
 | 
						|
      def firewalld_default_zone!(z)
 | 
						|
        raise 'firewalld not active' unless firewalld_active?
 | 
						|
 | 
						|
        shell_out!('firewall-cmd', "--set-default-zone=#{z}")
 | 
						|
      end
 | 
						|
 | 
						|
      def log_current_firewalld
 | 
						|
        shell_out!('firewall-cmd --direct --get-all-rules')
 | 
						|
      end
 | 
						|
 | 
						|
      def firewalld_flush!
 | 
						|
        raise 'firewall not active' unless firewalld_active?
 | 
						|
 | 
						|
        shell_out!('firewall-cmd', '--direct', '--remove-rules', 'ipv4', 'filter', 'INPUT')
 | 
						|
        shell_out!('firewall-cmd', '--direct', '--remove-rules', 'ipv4', 'filter', 'OUTPUT')
 | 
						|
        shell_out!('firewall-cmd', '--direct', '--permanent', '--remove-rules', 'ipv4', 'filter', 'INPUT')
 | 
						|
        shell_out!('firewall-cmd', '--direct', '--permanent', '--remove-rules', 'ipv4', 'filter', 'OUTPUT')
 | 
						|
      end
 | 
						|
 | 
						|
      def firewalld_all_rules_permanent!
 | 
						|
        raise 'firewall not active' unless firewalld_active?
 | 
						|
 | 
						|
        rules = shell_out!('firewall-cmd', '--direct', '--get-all-rules').stdout
 | 
						|
        perm_rules = shell_out!('firewall-cmd', '--direct', '--permanent', '--get-all-rules').stdout
 | 
						|
        rules == perm_rules
 | 
						|
      end
 | 
						|
 | 
						|
      def firewalld_save!
 | 
						|
        raise 'firewall not active' unless firewalld_active?
 | 
						|
 | 
						|
        shell_out!('firewall-cmd', '--direct', '--permanent', '--remove-rules', 'ipv4', 'filter', 'INPUT')
 | 
						|
        shell_out!('firewall-cmd', '--direct', '--permanent', '--remove-rules', 'ipv4', 'filter', 'OUTPUT')
 | 
						|
        shell_out!('firewall-cmd', '--direct', '--get-all-rules').stdout.lines do |line|
 | 
						|
          shell_out!("firewall-cmd --direct --permanent --add-rule #{line}")
 | 
						|
        end
 | 
						|
      end
 | 
						|
 | 
						|
      def ip_versions(resource)
 | 
						|
        if ipv4_rule?(resource)
 | 
						|
          %w(ipv4)
 | 
						|
        elsif ipv6_rule?(resource)
 | 
						|
          %w(ipv6)
 | 
						|
        else # no source or destination address, add rules for both ipv4 and ipv6
 | 
						|
          %w(ipv4 ipv6)
 | 
						|
        end
 | 
						|
      end
 | 
						|
 | 
						|
      CHAIN = { in: 'INPUT', out: 'OUTPUT', pre: 'PREROUTING', post: 'POSTROUTING' }.freeze unless defined? CHAIN # , nil => "FORWARD"}
 | 
						|
      TARGET = { allow: 'ACCEPT', reject: 'REJECT', deny: 'DROP', masquerade: 'MASQUERADE', redirect: 'REDIRECT', log: 'LOG --log-prefix \'iptables: \' --log-level 7' }.freeze unless defined? TARGET
 | 
						|
 | 
						|
      def build_firewall_rule(new_resource, ip_version = 'ipv4')
 | 
						|
        return new_resource.raw.strip if new_resource.raw
 | 
						|
 | 
						|
        type = new_resource.command
 | 
						|
        firewall_rule = if new_resource.direction
 | 
						|
                          "#{ip_version} filter #{CHAIN[new_resource.direction.to_sym]} "
 | 
						|
                        else
 | 
						|
                          "#{ip_version} filter FORWARD "
 | 
						|
                        end
 | 
						|
        firewall_rule << "#{new_resource.position} "
 | 
						|
 | 
						|
        if [:pre, :post].include?(new_resource.direction)
 | 
						|
          firewall_rule << '-t nat '
 | 
						|
        end
 | 
						|
 | 
						|
        # Firewalld order of prameters is important here see example output below:
 | 
						|
        # ipv4 filter INPUT 1 -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
 | 
						|
        firewall_rule << "-s #{ip_with_mask(new_resource, new_resource.source)} " if new_resource.source && new_resource.source != '0.0.0.0/0'
 | 
						|
        firewall_rule << "-d #{new_resource.destination} " if new_resource.destination
 | 
						|
 | 
						|
        firewall_rule << "-i #{new_resource.interface} " if new_resource.interface
 | 
						|
        firewall_rule << "-o #{new_resource.dest_interface} " if new_resource.dest_interface
 | 
						|
 | 
						|
        firewall_rule << "-p #{new_resource.protocol} " if new_resource.protocol && new_resource.protocol.to_s.to_sym != :none
 | 
						|
        firewall_rule << '-m tcp ' if new_resource.protocol && new_resource.protocol.to_s.to_sym == :tcp
 | 
						|
 | 
						|
        # using multiport here allows us to simplify our greps and rule building
 | 
						|
        firewall_rule << "-m multiport --sports #{port_to_s(new_resource.source_port)} " if new_resource.source_port
 | 
						|
        firewall_rule << "-m multiport --dports #{port_to_s(dport_calc(new_resource))} " if dport_calc(new_resource)
 | 
						|
 | 
						|
        firewall_rule << "-m state --state #{new_resource.stateful.is_a?(Array) ? new_resource.stateful.join(',').upcase : new_resource.stateful.to_s.upcase} " if new_resource.stateful
 | 
						|
        firewall_rule << "-m comment --comment '#{new_resource.description}' " if new_resource.include_comment
 | 
						|
        firewall_rule << "-j #{TARGET[type]} "
 | 
						|
        firewall_rule << "--to-ports #{new_resource.redirect_port} " if type == :redirect
 | 
						|
        firewall_rule.strip!
 | 
						|
        firewall_rule
 | 
						|
      end
 | 
						|
    end
 | 
						|
  end
 | 
						|
end
 |