Class: IPTables::Rule

Inherits:
Object
  • Object
show all
Defined in:
lib/iptables/tables.rb

Constant Summary collapse

@@valid_custom_service_keys =

possible key names for custom named tcp and/or udp services

%w/service_name service_udp service_tcp/
@@parse_comment_regex =
/^\-m\s+comment\s+\-\-comment\s+"([^"]+)"/

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(rule_info, my_chain) ⇒ Rule

Returns a new instance of Rule.



615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
# File 'lib/iptables/tables.rb', line 615

def initialize(rule_info, my_chain)
  $log.debug("received Rule info #{rule_info.inspect}")

  @rule_info = rule_info
  case rule_info
  when String
    self.handle_string(rule_info)
  when Hash
    @rule_hash = rule_info
  else
    raise "don't know how to handle rule_info: #{rule_info.inspect}"
  end

  @my_chain = my_chain

  @position = nil

  # expanded rules will use this instead of @args
  @children = []

  @args = ''

  self.handle_requires_primitive

  case @rule_hash.length
  when 1
    @type = @rule_hash.keys.first
  when 2, 3
    @type = 'custom_service'
  else
    raise 'do not know how to handle this rule'
  end

  $log.debug("create Rule #{@type}")

  case @type
  when 'comment'

  when 'custom_service'
    self.handle_custom_service()

  when 'empty'

  when 'interpolated'
    self.handle_interpolated()

  when 'macro'
    self.handle_macro()

  when 'node_addition_points'
    self.handle_node_addition_points()

  when 'raw'

  when 'service'
    self.handle_service()

  when 'service_tcp'

  when 'service_udp'

  when 'ulog'

  else
    raise "unrecognized rule type #{@type}"
  end
end

Instance Attribute Details

#positionObject (readonly)

Returns the value of attribute position.



611
612
613
# File 'lib/iptables/tables.rb', line 611

def position
  @position
end

#rule_hashObject (readonly)

Returns the value of attribute rule_hash.



611
612
613
# File 'lib/iptables/tables.rb', line 611

def rule_hash
  @rule_hash
end

#typeObject (readonly)

Returns the value of attribute type.



611
612
613
# File 'lib/iptables/tables.rb', line 611

def type
  @type
end

Instance Method Details

#add_child(rule_hash) ⇒ Object



683
684
685
# File 'lib/iptables/tables.rb', line 683

def add_child(rule_hash)
  @children.push(IPTables::Rule.new(rule_hash, @my_chain))
end

#apply_additions(other_firewall) ⇒ Object



840
841
842
843
844
845
846
847
848
849
# File 'lib/iptables/tables.rb', line 840

def apply_additions(other_firewall)
  @rule_hash['node_addition_points'].each{ |addition_name|
    other_rules = other_firewall.get_node_additions(@my_chain.my_table.name, addition_name)
    next if other_rules.nil?
    $log.debug("applying additions at #{addition_name}")
    other_rules.each{ |other_rule_object|
      self.add_child(other_rule_object.rule_hash)
    }
  }
end

#as_array(comments = true) ⇒ Object



776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
# File 'lib/iptables/tables.rb', line 776

def as_array(comments = true)
  case @type
  when 'comment'
    return [] unless comments
    self.generate_comment()

  when 'empty'
    return []

  when 'raw'
    self.generate_raw()

  when 'service_tcp'
    self.generate_tcp()

  when 'service_udp'
    self.generate_udp()

  when 'ulog'
    self.generate_ulog()
  end

  if @children.empty?
    raise "@args is empty" unless @args.length > 0
    return ["-A #{@my_chain.name} #{@args}"]
  else
    rules = @children.collect{ |child| child.as_array(comments)}.flatten
    $log.debug(rules)
    return rules
  end
end

#generate_commentObject



808
809
810
# File 'lib/iptables/tables.rb', line 808

def generate_comment()
  @args = %Q|-m comment --comment "#{@rule_hash['comment']}"|
end

#generate_rawObject



812
813
814
# File 'lib/iptables/tables.rb', line 812

def generate_raw()
  @args = @rule_hash['raw']
end

#generate_tcpObject



816
817
818
# File 'lib/iptables/tables.rb', line 816

def generate_tcp()
  @args = "-p tcp -m tcp --sport 1024:65535 --dport #{@rule_hash['service_tcp']} -m state --state NEW,ESTABLISHED -j ACCEPT"
end

#generate_udpObject



820
821
822
# File 'lib/iptables/tables.rb', line 820

def generate_udp()
  @args = "-p udp -m udp --sport 1024:65535 --dport #{@rule_hash['service_udp']} -m state --state NEW,ESTABLISHED -j ACCEPT"
end

#generate_ulogObject



824
825
826
827
828
829
830
# File 'lib/iptables/tables.rb', line 824

def generate_ulog()
  @args = %Q|-m limit --limit 1/sec --limit-burst 2 -j ULOG --ulog-prefix "#{@my_chain.name}:"|

  if @rule_hash['ulog'] == '-p tcp'
    @args = "-p tcp #{@args}"
  end
end

#handle_custom_serviceObject



699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
# File 'lib/iptables/tables.rb', line 699

def handle_custom_service()
  raise "missing service name: #{@rule_hash.inspect}" unless @rule_hash.has_key? 'service_name'

  custom_service_port = nil
  custom_services = []
  @rule_hash.keys.sort.each{ |key|
    next if key == 'service_name'
    raise "unknown service key: #{key}" unless @@valid_custom_service_keys.include? key
    custom_services << {key => @rule_hash[key]}
    # set the custom service port if exactly one custom service has a port
    # or both services have the same port
    if custom_service_port.nil?
      custom_service_port = @rule_hash[key]
    else
      custom_service_port = nil unless @rule_hash[key].to_i == custom_service_port.to_i
    end
  }

  if custom_service_port.nil?
    self.add_child({'comment' => "_ #{@rule_hash['service_name']}"})
  else
    self.add_child({'comment' => "_ Port #{custom_service_port} - #{@rule_hash['service_name']}"})
  end
  custom_services.each{ |service_hash|
    self.add_child(service_hash)
  }
end

#handle_interpolatedObject



727
728
729
730
731
732
733
734
735
# File 'lib/iptables/tables.rb', line 727

def handle_interpolated()
  config = @my_chain.my_table.my_iptables.config
  raise 'missing config' if config.nil?
  interpolations = config.interpolations
  $log.debug("interpolating: #{@rule_hash['interpolated']}")
  interpolations.children(@rule_hash['interpolated']).each{ |rule_hash|
    self.add_child(rule_hash)
  }
end

#handle_macroObject



737
738
739
740
741
742
743
744
745
# File 'lib/iptables/tables.rb', line 737

def handle_macro()
  config = @my_chain.my_table.my_iptables.config
  raise 'missing config' if config.nil?
  macro = config.macros.named[@rule_hash['macro']]
  $log.debug("macro: #{macro.name}")
  macro.children.each{ |rule_hash|
    self.add_child(rule_hash)
  }
end

#handle_node_addition_pointsObject



747
748
749
750
751
752
# File 'lib/iptables/tables.rb', line 747

def handle_node_addition_points()
  self.add_child({'empty' => nil})
  @rule_hash['node_addition_points'].each{ |addition_name|
    @my_chain.register_node_addition_point(self, addition_name)
  }
end

#handle_requires_primitiveObject



687
688
689
690
691
692
693
694
695
696
697
# File 'lib/iptables/tables.rb', line 687

def handle_requires_primitive
  @requires_primitive = nil
  return unless @rule_hash.has_key? 'requires_primitive'
  @requires_primitive = @rule_hash['requires_primitive']
  @rule_hash.delete('requires_primitive')
  config = @my_chain.my_table.my_iptables.config
  raise 'missing config' if config.nil?
  primitives = config.primitives
  raise 'missing primitives' if primitives.nil?
  @rule_hash = {'empty' => nil} unless primitives.has_primitive?(@requires_primitive)
end

#handle_serviceObject



754
755
756
757
758
759
760
761
762
# File 'lib/iptables/tables.rb', line 754

def handle_service()
  config = @my_chain.my_table.my_iptables.config
  raise 'missing config' if config.nil?
  service = config.services.named[@rule_hash['service']]
  $log.debug("service: #{service.name}")
  service.children.each{ |rule_hash|
    self.add_child(rule_hash)
  }
end

#handle_string(rule_info) ⇒ Object



764
765
766
767
768
769
770
771
772
773
774
# File 'lib/iptables/tables.rb', line 764

def handle_string(rule_info)
  # try to parse strings

  if rule_info =~ @@parse_comment_regex
    # if we're a comment, set as comment
    @rule_hash = {'comment' => $1}
  else
    # otherwise set as raw
    @rule_hash = {'raw' => rule_info}
  end
end

#pathObject



832
833
834
# File 'lib/iptables/tables.rb', line 832

def path()
  @my_chain.path + ".#{@position}"
end

#set_position(number) ⇒ Object



836
837
838
# File 'lib/iptables/tables.rb', line 836

def set_position(number)
  @position = number
end