114 lines
		
	
	
		
			2.9 KiB
		
	
	
	
		
			Ruby
		
	
	
	
	
	
			
		
		
	
	
			114 lines
		
	
	
		
			2.9 KiB
		
	
	
	
		
			Ruby
		
	
	
	
	
	
unified_mode true
 | 
						|
 | 
						|
require 'ipaddr'
 | 
						|
 | 
						|
action_class do
 | 
						|
  include FirewallCookbook::Helpers
 | 
						|
  include FirewallCookbook::Helpers::Nftables
 | 
						|
 | 
						|
  def return_early?(new_resource)
 | 
						|
    !new_resource.notify_firewall ||
 | 
						|
      !(new_resource.action.include?(:create) &&
 | 
						|
        !new_resource.should_skip?(:create))
 | 
						|
  end
 | 
						|
end
 | 
						|
 | 
						|
provides :nftables_rule
 | 
						|
default_action :create
 | 
						|
 | 
						|
property :firewall_name,
 | 
						|
         String,
 | 
						|
         default: 'default'
 | 
						|
property :command,
 | 
						|
         [Array, Symbol],
 | 
						|
         default: :accept
 | 
						|
property :protocol,
 | 
						|
         [Integer, Symbol],
 | 
						|
         default: :tcp,
 | 
						|
         callbacks: {
 | 
						|
           'must be either :tcp, :udp, :icmp, :\'ipv6-icmp\', :icmpv6, :none, or a valid IP protocol number' => lambda do |p|
 | 
						|
             %i(udp tcp icmp icmpv6 ipv6-icmp esp ah ipv6 none).include?(p) || (0..142).include?(p)
 | 
						|
           end,
 | 
						|
         }
 | 
						|
property :direction,
 | 
						|
         Symbol,
 | 
						|
         equal_to: [:in, :out, :pre, :post, :forward],
 | 
						|
         default: :in
 | 
						|
# nftables handles ip6 and ip simultaneously.  Except for directions
 | 
						|
# :pre and :post, where where either :ip6 or :ip must be specified.
 | 
						|
# callback should prevent from mixing that up.
 | 
						|
property :family,
 | 
						|
         Symbol,
 | 
						|
         equal_to: [:ip6, :ip],
 | 
						|
         default: :ip
 | 
						|
property :source,
 | 
						|
         [String, Array],
 | 
						|
         callbacks: {
 | 
						|
           'must be a valid ip address' => lambda do |ips|
 | 
						|
             Array(ips).inject(false) do |a, ip|
 | 
						|
               a || !!IPAddr.new(ip)
 | 
						|
             end
 | 
						|
           end,
 | 
						|
         }
 | 
						|
property :sport,
 | 
						|
         [Integer, String, Array, Range]
 | 
						|
property :interface,
 | 
						|
         String
 | 
						|
 | 
						|
property :dport,
 | 
						|
         [Integer, String, Array, Range]
 | 
						|
property :destination,
 | 
						|
         [String, Array],
 | 
						|
         callbacks: {
 | 
						|
           'must be a valid ip address' => lambda do |ips|
 | 
						|
             Array(ips).inject(false) do |a, ip|
 | 
						|
               a || !!IPAddr.new(ip)
 | 
						|
             end
 | 
						|
           end,
 | 
						|
         }
 | 
						|
property :outerface,
 | 
						|
         String
 | 
						|
 | 
						|
property :position,
 | 
						|
         Integer,
 | 
						|
         default: 50
 | 
						|
property :stateful,
 | 
						|
         [Symbol, Array]
 | 
						|
property :redirect_port,
 | 
						|
         Integer
 | 
						|
property :description,
 | 
						|
         String,
 | 
						|
         name_property: true
 | 
						|
property :include_comment,
 | 
						|
         [true, false],
 | 
						|
         default: true
 | 
						|
property :log_prefix,
 | 
						|
         String
 | 
						|
property :log_group,
 | 
						|
         Integer
 | 
						|
# for when you just want to pass a raw rule
 | 
						|
property :raw,
 | 
						|
         String
 | 
						|
 | 
						|
# do you want this rule to notify the firewall to recalculate
 | 
						|
# (and potentially reapply) the firewall_rule(s) it finds?
 | 
						|
property :notify_firewall,
 | 
						|
         [true, false],
 | 
						|
         default: true
 | 
						|
 | 
						|
action :create do
 | 
						|
  return if return_early?(new_resource)
 | 
						|
  fwr = build_firewall_rule(new_resource)
 | 
						|
 | 
						|
  with_run_context :root do
 | 
						|
    edit_resource!('nftables', new_resource.firewall_name) do |fw_rule|
 | 
						|
      r = rules.dup || {}
 | 
						|
      r.merge!({
 | 
						|
                 fwr => fw_rule.position,
 | 
						|
               })
 | 
						|
      rules(r)
 | 
						|
      delayed_action :rebuild
 | 
						|
    end
 | 
						|
  end
 | 
						|
end
 |