iptables-ruby 0.2.4

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,8 @@
1
+ {
2
+ "policy6": {
3
+ "filter": "DROP",
4
+ "mangle": "DROP",
5
+ "nat": "DROP",
6
+ "raw": "DROP"
7
+ }
8
+ }
@@ -0,0 +1,40 @@
1
+ {
2
+ "primitives": {
3
+ "iana_reserved": [
4
+ "0.0.0.0/8",
5
+ "5.0.0.0/8",
6
+ "10.0.0.0/8",
7
+ "36.0.0.0/7",
8
+ "39.0.0.0/8",
9
+ "42.0.0.0/8",
10
+ "49.0.0.0/8",
11
+ "100.0.0.0/6",
12
+ "104.0.0.0/7",
13
+ "106.0.0.0/8",
14
+ "127.0.0.0/8",
15
+ "179.0.0.0/8",
16
+ "185.0.0.0/8",
17
+ "240.0.0.0/4",
18
+ "169.254.0.0/16",
19
+ "172.16.0.0/12",
20
+ "192.0.2.0/24",
21
+ "192.88.99.0/24",
22
+ "192.168.0.0/16"
23
+ ],
24
+ "internet": {
25
+ "address": "198.51.100.10/32",
26
+ "broadcast": "198.51.100.255/32",
27
+ "device": "eth0",
28
+ "subnet": {
29
+ "internet": "198.51.100.0/24",
30
+ "vpn": "203.0.113.0/24"
31
+ }
32
+ },
33
+ "storage": {
34
+ "address": "192.0.2.100/32",
35
+ "device": "eth1",
36
+ "subnet": "192.0.2.0/24"
37
+ }
38
+ }
39
+ }
40
+
@@ -0,0 +1,30 @@
1
+ {
2
+ "rules": {
3
+ "nat": {
4
+ "INPUT": {
5
+ "policy": "ACCEPT"
6
+ },
7
+ "OUTPUT": {
8
+ "policy": "ACCEPT"
9
+ },
10
+ "POSTROUTING": {
11
+ "policy": "ACCEPT"
12
+ },
13
+ "PREROUTING": {
14
+ "policy": "ACCEPT"
15
+ }
16
+ },
17
+ "filter": {
18
+ "in_*": {
19
+ "additions": []
20
+ },
21
+ "in_peers": {
22
+ "additions": []
23
+ },
24
+ "in_public": {
25
+ "additions": []
26
+ }
27
+ }
28
+ }
29
+ }
30
+
@@ -0,0 +1,81 @@
1
+ {
2
+ "services": {
3
+ "dhcp": "-p udp -m udp --sport 67:68 --dport 67:68 -m state --state NEW,ESTABLISHED -j ACCEPT",
4
+ "domain": [
5
+ "-p udp -m udp --sport 53 --dport 53 -m state --state NEW,ESTABLISHED -j ACCEPT",
6
+ {
7
+ "service_udp": "53"
8
+ },
9
+ "-p tcp -m tcp --sport 53 --dport 53 -m state --state NEW,ESTABLISHED -j ACCEPT",
10
+ {
11
+ "service_tcp": "53"
12
+ }
13
+ ],
14
+ "http": 80,
15
+ "https": 443,
16
+ "icmp": "-p icmp -m state --state NEW,ESTABLISHED -j ACCEPT",
17
+ "ipp": 631,
18
+ "jabber": [
19
+ {
20
+ "service_tcp": "5222"
21
+ },
22
+ {
23
+ "service_tcp": "5223"
24
+ }
25
+ ],
26
+ "ldap": 389,
27
+ "ldaps": 636,
28
+ "mysql": 3306,
29
+ "nfs": [
30
+ {
31
+ "service_tcp": "2049"
32
+ },
33
+ {
34
+ "service_udp": "2049"
35
+ }
36
+ ],
37
+ "ntp": [
38
+ "-p udp -m udp --sport 123 --dport 123 -m state --state NEW,ESTABLISHED -j ACCEPT",
39
+ {
40
+ "service_udp": "123"
41
+ },
42
+ "-p tcp -m tcp --sport 123 --dport 123 -m state --state NEW,ESTABLISHED -j ACCEPT",
43
+ {
44
+ "service_tcp": "123"
45
+ }
46
+ ],
47
+ "portmap": [
48
+ {
49
+ "service_tcp": "111"
50
+ },
51
+ {
52
+ "service_udp": "111"
53
+ }
54
+ ],
55
+ "postgres": 5432,
56
+ "rabbitmq": [
57
+ {
58
+ "service_tcp": "5670:5680"
59
+ },
60
+ {
61
+ "service_udp": "5670:5680"
62
+ }
63
+ ],
64
+ "smtp": 25,
65
+ "snmp": 161,
66
+ "ssh": 22,
67
+ "syslog": [
68
+ "-p udp -m udp --sport 514 --dport 514 -m state --state NEW,ESTABLISHED -j ACCEPT",
69
+ {
70
+ "service_udp": "514"
71
+ },
72
+ "-p tcp -m tcp --sport 514 --dport 514 -m state --state NEW,ESTABLISHED -j ACCEPT",
73
+ {
74
+ "service_tcp": "514"
75
+ }
76
+ ],
77
+ "tftp": {
78
+ "service_udp": "69"
79
+ }
80
+ }
81
+ }
data/lib/iptables.rb ADDED
@@ -0,0 +1,5 @@
1
+ require 'iptables/logger'
2
+ require 'iptables/tables'
3
+ require 'iptables/expansions'
4
+ require 'iptables/primitives'
5
+ require 'iptables/configuration'
@@ -0,0 +1,116 @@
1
+ require 'json'
2
+
3
+ module IPTables
4
+ class Configuration
5
+ @@json_pattern = /\.js(on)?$/
6
+
7
+ def initialize(*args)
8
+ @parsed_hash = {}
9
+ self.parse_files(*args)
10
+ end
11
+
12
+ def parse_files(*args)
13
+ args.each{ |arg|
14
+ $log.debug("reading arg #{arg}")
15
+ case arg
16
+ when @@json_pattern
17
+ handle_json(arg)
18
+ else
19
+ raise "don't know how to handle #{arg.inspect}"
20
+ end
21
+ }
22
+ end
23
+
24
+ def policy(in_policy = nil)
25
+ @policy ||= nil
26
+ return @policy unless @policy.nil?
27
+ unless in_policy.nil?
28
+ @policy = in_policy
29
+ return @policy
30
+ end
31
+ raise 'missing policy' unless @parsed_hash.has_key? 'policy'
32
+ @policy = IPTables::Tables.new(@parsed_hash['policy'], self)
33
+ end
34
+
35
+ def policy6(in_policy = nil)
36
+ @policy6 ||= nil
37
+ return @policy6 unless @policy6.nil?
38
+ unless in_policy.nil?
39
+ @policy6 = in_policy
40
+ return @policy6
41
+ end
42
+ raise 'missing policy6' unless @parsed_hash.has_key? 'policy6'
43
+ @policy6 = IPTables::Tables.new(@parsed_hash['policy6'], self)
44
+ end
45
+
46
+ def interpolations(in_interpolations = nil)
47
+ @interpolations ||= nil
48
+ return @interpolations unless @interpolations.nil?
49
+ unless in_interpolations.nil?
50
+ @interpolations = in_interpolations
51
+ return @interpolations
52
+ end
53
+ @interpolations = IPTables::Interpolations.new(self.primitives)
54
+ end
55
+
56
+ def primitives(in_primitives = nil)
57
+ @primitives ||= nil
58
+ return @primitives unless @primitives.nil?
59
+ unless in_primitives.nil?
60
+ @primitives = in_primitives
61
+ return @primitives
62
+ end
63
+ raise 'missing primitives' unless @parsed_hash.has_key? 'primitives'
64
+ @primitives = IPTables::Primitives.new(@parsed_hash['primitives'])
65
+ end
66
+
67
+ def rules(in_rules = nil)
68
+ @rules ||= nil
69
+ return @rules unless @rules.nil?
70
+ unless in_rules.nil?
71
+ @rules = in_rules
72
+ return @rules
73
+ end
74
+ raise 'missing rules' unless @parsed_hash.has_key? 'rules'
75
+ @rules = IPTables::Tables.new(@parsed_hash['rules'], self)
76
+ end
77
+
78
+ def services(in_services = nil)
79
+ @services ||= nil
80
+ return @services unless @services.nil?
81
+ unless in_services.nil?
82
+ @services = in_services
83
+ return @services
84
+ end
85
+ raise 'missing services' unless @parsed_hash.has_key? 'services'
86
+ @services = IPTables::Services.new(@parsed_hash['services'])
87
+ end
88
+
89
+ def macros(in_macros = nil)
90
+ @macros ||= nil
91
+ return @macros unless @macros.nil?
92
+ unless in_macros.nil?
93
+ @macros = in_macros
94
+ return @macros
95
+ end
96
+ raise 'missing macros' unless @parsed_hash.has_key? 'macros'
97
+ @macros = IPTables::Macros.new(@parsed_hash['macros'])
98
+ end
99
+
100
+ def handle_json(file_name)
101
+ json = File.read(file_name)
102
+ JSON.parse(json).each{ |key, value|
103
+ $log.debug("reading #{key} from file #{file_name}")
104
+ raise "duplicate key: #{key}" if @parsed_hash.has_key? key
105
+ @parsed_hash[key] = value
106
+ }
107
+ end
108
+
109
+ def converge_firewall()
110
+ policy_fw = self.policy
111
+ rules_fw = self.rules
112
+ policy_fw.merge(rules_fw)
113
+ return policy_fw
114
+ end
115
+ end
116
+ end
@@ -0,0 +1,189 @@
1
+ require 'iptables/logger'
2
+
3
+ module IPTables
4
+ class Macros
5
+ attr_reader :named
6
+ def initialize(expansion_hash)
7
+ @expansion_hash = expansion_hash
8
+ @named = {}
9
+ @expansion_hash.each{ |name, info|
10
+ @named[name] = Macro.new(name, info)
11
+ }
12
+ end
13
+ end
14
+
15
+ class Macro
16
+ attr_reader :name, :children
17
+ def initialize(name, info)
18
+ @name = name
19
+ @info = info
20
+ @children = []
21
+
22
+ case info
23
+ when Array
24
+ self.handle_array()
25
+ when Hash
26
+ self.handle_hash()
27
+ when String
28
+ self.handle_string()
29
+ else
30
+ raise "don't know how to handle info: #{info.inspect}"
31
+ end
32
+ end
33
+
34
+ def add_child(rule_hash)
35
+ @children.push(rule_hash)
36
+ end
37
+
38
+ def handle_array()
39
+ @info.each{ |macro_hash|
40
+ self.add_child(macro_hash)
41
+ }
42
+ end
43
+
44
+ def handle_hash()
45
+ self.add_child( @info )
46
+ end
47
+
48
+ def handle_string()
49
+ self.add_child( {'raw' => @info} )
50
+ end
51
+ end
52
+
53
+ class Services
54
+ attr_reader :named
55
+ def initialize(expansion_hash)
56
+ @expansion_hash = expansion_hash
57
+ @named = {}
58
+ @expansion_hash.each{ |name, info|
59
+ @named[name] = Service.new(name, info)
60
+ }
61
+ end
62
+ end
63
+
64
+ class Service
65
+ attr_reader :name, :children
66
+ def initialize(name, info)
67
+ @name = name
68
+ @info = info
69
+ @children = []
70
+
71
+ case info
72
+ when Array
73
+ self.handle_array()
74
+ when Hash
75
+ self.handle_hash()
76
+ when Integer
77
+ self.handle_integer()
78
+ when String
79
+ self.handle_string()
80
+ else
81
+ raise "don't know how to handle info: #{info.inspect}"
82
+ end
83
+ end
84
+
85
+ def add_child(rule_hash)
86
+ @children.push(rule_hash)
87
+ end
88
+
89
+ def handle_array()
90
+ self.add_child( { 'comment' => "_ #{@name}" } )
91
+ raise 'empty @info' if @info.empty?
92
+ @info.each{ |service_info_hash|
93
+ self.add_child(service_info_hash)
94
+ }
95
+ end
96
+
97
+ def handle_hash()
98
+ raise 'empty @info' if @info.empty?
99
+ @info['service_name'] = @name
100
+ self.add_child( @info )
101
+ end
102
+
103
+ def handle_integer()
104
+ self.add_child( { 'comment' => "_ Port #{@info} - #{@name}" } )
105
+ self.add_child({
106
+ 'raw' =>
107
+ "-p tcp -m tcp --sport 1024:65535 --dport #{@info} -m state --state NEW,ESTABLISHED -j ACCEPT"
108
+ })
109
+ end
110
+
111
+ def handle_string()
112
+ self.add_child( { 'comment' => "_ #{@name}" } )
113
+ self.add_child( {'raw' => @info} )
114
+ end
115
+ end
116
+
117
+ class Interpolations
118
+ # interpret strings such as "<% foo.bar %>" into equivalent primitives
119
+ attr_reader :primitives, :named
120
+ def initialize(primitives)
121
+ @primitives = primitives
122
+ $log.debug("interpolations primitives: #{@primitives}")
123
+ @named = {}
124
+ end
125
+
126
+ def add(interpolation_string)
127
+ @named[interpolation_string] = Interpolation.new(self, interpolation_string)
128
+ end
129
+
130
+ def children(interpolation_string)
131
+ self.add(interpolation_string) unless @named.has_key? interpolation_string
132
+ strings = @named[interpolation_string].children()
133
+ returned_array = []
134
+ case strings
135
+ when Array
136
+ strings.each{ |result|
137
+ returned_array.push({'raw' => result})
138
+ }
139
+ else
140
+ returned_array.push({'raw' => strings})
141
+ end
142
+ return returned_array
143
+ end
144
+ end
145
+
146
+ class Interpolation
147
+ @@interpolation_regex = /(.*?)<%\s*(\S+)\s*%>(.*)/
148
+
149
+ def initialize(interpolations, initial_string)
150
+ @interpolations = interpolations
151
+ @initial_string = initial_string
152
+ @child = nil
153
+ if @initial_string =~ @@interpolation_regex
154
+ self.add_child($1, $2, $3)
155
+ else
156
+ $log.debug("completed substitution: #{@initial_string}")
157
+ end
158
+ end
159
+
160
+ def add_child(first, identifier, last)
161
+ interpolated = @interpolations.primitives.substitute(identifier)
162
+ case interpolated
163
+ when Array
164
+ @child = []
165
+ interpolated.each{ |value|
166
+ @child.push(Interpolation.new(@interpolations, "#{first}#{value}#{last}"))
167
+ }
168
+ else
169
+ @child = Interpolation.new(@interpolations, "#{first}#{interpolated}#{last}")
170
+ end
171
+ end
172
+
173
+ def children()
174
+ return_value = nil
175
+ case @child
176
+ when nil
177
+ return_value = @initial_string
178
+ when Array
179
+ return_value = []
180
+ @child.each{ |value|
181
+ return_value.push(value.children())
182
+ }
183
+ else
184
+ return_value = @child.children()
185
+ end
186
+ return return_value
187
+ end
188
+ end
189
+ end