Module: Asbestos::Firewall::IPTables

Defined in:
lib/asbestos/firewalls/iptables.rb

Class Method Summary collapse

Class Method Details

.chain(name, default_action) ⇒ Object


15
16
17
18
19
# File 'lib/asbestos/firewalls/iptables.rb', line 15

def self.chain(name, default_action)
  default_action = '-' if default_action == :none

  ":#{name.upcase} #{default_action.upcase} [0:0]"
end

.open_port(interfaces, port, protocol, comment, remote_address = nil) ⇒ Object


22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
# File 'lib/asbestos/firewalls/iptables.rb', line 22

def self.open_port(interfaces, port, protocol, comment, remote_address = nil)
  if interfaces
    interfaces.collect do |interface|
      accept :state     => :new,
             :protocol  => protocol,
             :port      => port,
             :comment   => comment,
             :interface => interface,
             :remote_address => remote_address
    end
  else
    accept :state     => :new,
           :protocol  => protocol,
           :port      => port,
           :comment   => comment,
           :remote_address => remote_address
  end
end

.postamble(host) ⇒ Object


111
112
113
114
115
116
117
118
119
120
121
122
123
124
# File 'lib/asbestos/firewalls/iptables.rb', line 111

def self.postamble(host)
  Array.new.tap do |rules|
   rules << log(:limit => '5/min',
                :log_level => 7,
                :log_prefix => "iptables dropped: ",
                :comment => "log dropped packets") if host.log_denials?

   rules << drop(:chain => :input,
                 :comment => "drop packets that haven't been explicitly accepted") if host.chains[:input].upcase == :ACCEPT

   rules << 'COMMIT'
   rules << "# Asbestos completed at #{Time.now.utc}"
  end
end

.preamble(host) ⇒ Object


4
5
6
7
8
9
10
11
12
# File 'lib/asbestos/firewalls/iptables.rb', line 4

def self.preamble(host)
  [ "# Generated by Asbestos at #{Time.now.utc} for #{host.name}",
    "# #{Asbestos::HOMEPAGE}",
    "*filter"
  ] +
  host.chains.collect do |name, default_action|
    chain name, default_action
  end
end

.rule(args) ⇒ Object

TODO: Use iptables' long options here for clarity?


44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
# File 'lib/asbestos/firewalls/iptables.rb', line 44

def self.rule(args)
  Array.new.tap do |r|
    chain = \
      if args[:chain]
        args[:chain].to_s.upcase
      else
        'INPUT'
      end
    r << "-A #{chain}"

    r << "-j #{args[:action].upcase}" if args[:action]

    if args[:interface]
      direction = \
        if args[:direction]
          case args[:direction]
            when :incoming
              'i'
            when :outgoing
              'o'
            else
              raise "you must provide a :direction flag of either :incoming or :outgoing"
          end
        elsif %w{INPUT PREROUTING}.include? chain
          'i'
        elsif %w{OUTPUT POSTROUTING}.include? chain
          'o'
        else
          raise "you must provide a :direction flag of either :incoming or :outgoing to use :interface with chain #{chain}"
        end
      r << "-#{direction} #{args[:interface]}"
    end

    r << "-p #{args[:protocol]}" if args[:protocol]
    r << "-d #{args[:local_address]}" if args[:local_address]
    r << "-s #{args[:remote_address]}" if args[:remote_address]

    r << "-m state --state #{args[:state].upcase}" if args[:state]
    #r << "-m #{args[:protocol]} --dport #{args[:port]}" if args[:protocol] && args[:port]
    r << "--dport #{args[:port]}" if args[:port]
    r << "-m limit --limit #{args[:limit]}" if args[:limit]

    r << %{--log-prefix "#{args[:log_prefix]}"} if args[:log_prefix]
    r << "--log-level #{args[:log_level]}" if args[:log_level]

    r << "--icmp-type #{args[:icmp_type]}" if args[:icmp_type]

    if args[:comment]
      if args[:interface]
        r << %{-m comment --comment "#{args[:comment]} on #{args[:interface]}"}
      else
        r << %{-m comment --comment "#{args[:comment]}"}
      end
    end
  end.join(' ')
end