iptables-ruby 0.2.4

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 3cdee7f713d4749034b6106e46c562312fccbaf2
4
+ data.tar.gz: 24934051d8029a1798b7b8d5319274d68c2b5cce
5
+ SHA512:
6
+ metadata.gz: 1bb21c4234d7b3880faa9c16aefac00b474856938f1ea2975e482238f9771b37bf24fca3af16dec71303d11db8302ed7f2785e3e37de0de898cee712562f8c9d
7
+ data.tar.gz: 5ef4fc170a0121d151963910e332ad064d622de4d1ce11e8592deca2cfaf383010cef6e496bb6cc4a5fb67ed2f5d99db966ef86d6cac69c4f25da71949baa86d
data/.gitignore ADDED
@@ -0,0 +1,6 @@
1
+ *.swp
2
+ coverage/*
3
+ pkg
4
+ rdoc
5
+ Gemfile.lock
6
+ .rbenv-version
data/CHANGELOG ADDED
@@ -0,0 +1,23 @@
1
+ 0.2.4
2
+ - Fix comparison corner case.
3
+ - Nagios example script can read iptables output from file.
4
+ - Fix Ruby 1.9-unfriendly bugs
5
+
6
+ 0.2.3
7
+ - Compare two iptables.
8
+ - Add documentation.
9
+ - Add Nagios example script
10
+ - Add example policy files.
11
+
12
+ 0.2.2
13
+ - Generate multi-table output correctly.
14
+
15
+ 0.2.1
16
+ - Properly handle merging on top of a policy with a nil table.
17
+
18
+ 0.2.0
19
+ - New Rule parameter: "has_primitive":
20
+ - Do not evaluate or add a rule if it requires a non-existent primitive.
21
+
22
+ 0.1.0
23
+ - initial release
data/Gemfile ADDED
@@ -0,0 +1,6 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gem 'diff-lcs'
4
+ gem 'simplecov'
5
+ gem 'rake'
6
+ gem 'rdoc'
data/Generate.md ADDED
@@ -0,0 +1,278 @@
1
+ # Generating a firewall
2
+
3
+ A complete, generated firewall requires several JSON configuration
4
+ sections. These can either be compiled into one long JSON file or split
5
+ into separate files. An example usable firewall has been included within
6
+ this gem's `examples/policy` directory.
7
+
8
+ # Example JSON configuration files
9
+
10
+ ## macros.json
11
+
12
+ This file defines macros, which are reusable rules or sets of rules.
13
+ Each macro consists of an identifier (example `accept-established`), and
14
+ its expansion. For more on rules, see section `Rules`.
15
+
16
+ ## policy.json
17
+
18
+ This file defines policy, which is the "top-level" configuration
19
+ for your **desired** iptables rules.
20
+
21
+ Assuming you are using configuration-management software such as
22
+ [http://www.opscode.com/chef](Chef), you can set one policy for all of
23
+ your hosts, and then customize your policy per host using rules (see
24
+ `rules.json`) and primitives (see `primitives.json`).
25
+
26
+ The policy file is a hash of the four "standard" iptables tables:
27
+ `filter`, `mangle`, `nat`, and `raw`. Each of these can in turn either
28
+ be a hash configuring the table, or `null`.
29
+
30
+ ### `null`
31
+
32
+ If `null`, the policy for that table will be "whatever is already
33
+ defined". For example, the example configuration file shows
34
+ `"mangle": null`, which means: "if there is a `mangle` table, use its
35
+ rules, otherwise leave this table undefined".
36
+
37
+ ### hash
38
+
39
+ If a hash, the table must contain a hash of table names. These will be
40
+ the standard tables for the corresponding iptables table. For instance,
41
+ `filter` should minimally contain `INPUT`, `FORWARD`, and `OUTPUT`.
42
+ Other user-defined tables may also be defined/named.
43
+
44
+ Each defined table must have a `policy`. This can either be `DROP`,
45
+ `ACCEPT`, or `-`.
46
+
47
+ Each defined table must also have a `rules` section. This must be an
48
+ array of firewall rules. For more on rules, see section `Rules`.
49
+
50
+ ## policy6.json
51
+
52
+ This is the same as `policy.json`, but defines ipv6 rules.
53
+
54
+ ## primitives.json
55
+
56
+ Primitives are values that can be interpolated into other parts of your
57
+ firewall. For more on how these interpolations are used, see section
58
+ `Interpolation`.
59
+
60
+ ## rules.json
61
+
62
+ `rules` can be an empty hash, or contain any of the named iptables
63
+ tables (`filter`, `nat`, etc). Any named table is **added** to the rules
64
+ defined by policy (see example `policy.json`).
65
+
66
+ If a table is **not** found in policy, it is added to the generated
67
+ firewall. It is advised to define at least all standard chains for the
68
+ table. For instance, `nat` should minimally contain `INPUT`, `OUTPUT`,
69
+ `POSTROUTING` and `PREROUTING`, and each of these should minimally
70
+ contain a `policy` definition.
71
+
72
+ If a table **is** found in policy, each specified chain can either
73
+ override or modify the existing table within the policy.
74
+
75
+ ### Overriding Chain Policy
76
+
77
+ Set `"policy": "ACCEPT"` or any other valid policy.
78
+
79
+ ### Overriding Chain Rules
80
+
81
+ Set `"rules": []`. In this case, rules will be reset to be empty.
82
+ Alternately, fill the array with rules (see section `Rules`).
83
+
84
+ ### Adding Chain Rules
85
+
86
+ Set `"additions": []`. Rules (see section `Rules`) added into this array
87
+ will be added at node addition points within the policy rules (see
88
+ section `additions`).
89
+
90
+ ## services.json
91
+
92
+ This file defines services that you will be using within your firewall.
93
+ See section `Rules` on how to define each service.
94
+
95
+ Once defined, a service may be used within policy, rules, or macros.
96
+
97
+ # Rules
98
+
99
+ Rules fall within an array, and can consist of strings or hashes.
100
+
101
+ ## String Rules
102
+
103
+ A policy that is a string is inserted as-is into the policy
104
+ firewall, preceded by `-A the_chain_name`. A very simple firewall could
105
+ consist solely of string rules.
106
+
107
+ ## Hash rules
108
+
109
+ Other kinds of rules are defined as hashes, with the hash key denoting
110
+ the type of rule:
111
+
112
+ ### `comment`
113
+
114
+ This is shorthand for an iptables comment:
115
+
116
+ "comment": "comment1"
117
+
118
+ becomes
119
+
120
+ -A chain_name -m comment --comment "comment1"
121
+
122
+ The `chain_name` is the name of the chain in which the `comment` rule is
123
+ found.
124
+
125
+ ### `interpolated`
126
+
127
+ See section "Interpolating strings"
128
+
129
+ ### `macro`
130
+
131
+ This inserts the requested macro (see section `macros.json`) into the
132
+ rules.
133
+
134
+ ### `node_addition_points`
135
+
136
+ See section "`additions` and `node_addition_points`"
137
+
138
+ ### `service`
139
+
140
+ This inserts the requested service (see section `services.json`) into
141
+ the rules.
142
+
143
+ ### `service_tcp`
144
+
145
+ This takes an integer or string as an argument and inserts a permitted
146
+ inbound TCP port into the rules:
147
+
148
+ "service_tcp": 8080
149
+
150
+ becomes
151
+
152
+ -A chain_name -p tcp -m tcp --sport 1024:65535 --dport 8080 -m state --state NEW,ESTABLISHED -j ACCEPT
153
+
154
+ Port ranges such as `"8080:8090"` can also be used. The `chain_name` is
155
+ the name of the chain in which the `service_tcp` rule is found.
156
+
157
+ ### `service_udp`
158
+
159
+ This is identical to `service_tcp`, except that it inserts a permitted
160
+ inbound UDP port.
161
+
162
+ ### `ulog`
163
+
164
+ This is shorthand for an iptables logging statement:
165
+
166
+ "ulog": ""
167
+
168
+ becomes
169
+
170
+ -A chain_name -m limit --limit 1/sec --limit-burst 2 -j ULOG --ulog-prefix "chain_name:"
171
+
172
+ This can also use `-p tcp`:
173
+
174
+ "ulog": "-p tcp"
175
+
176
+ becomes
177
+
178
+ -A chain_name -p tcp -m limit --limit 1/sec --limit-burst 2 -j ULOG --ulog-prefix "chain_name:"
179
+
180
+ The `chain_name` is the name of the chain in which the `ulog` rule is
181
+ found.
182
+
183
+ # Interpolation
184
+
185
+ Primitives (see section `primitives.json`) are available within your
186
+ configuration using the `<%%>` notation within an `interpolated` rule.
187
+
188
+ ## Interpolating strings
189
+
190
+ An example usage is:
191
+
192
+ "interpolated": "-s <% internet.subnet.other %> -d <% internet.address %> -i <% internet.device %> -j ACCEPT"
193
+
194
+ Depending upon the defined primitives, the above rule could expand into:
195
+
196
+ -s 192.0.2.0/24 -d 198.51.100.10/32 -i eth0 -j ACCEPT
197
+
198
+ ## Interpolating arrays
199
+
200
+ Primitives that are defined as an array, such as `iana_reserved` in the
201
+ example `primitives.json`, will expand into multiple rules. For instance
202
+
203
+ "interpolated": "-s <% iana_reserved %> -j DROP"
204
+
205
+ would expand into
206
+
207
+ -s 0.0.0.0/8 -j DROP
208
+ -s 5.0.0.0/8 -j DROP
209
+ -s 10.0.0.0/8 -j DROP
210
+ -s 36.0.0.0/7 -j DROP
211
+ -s 39.0.0.0/8 -j DROP
212
+ -s 42.0.0.0/8 -j DROP
213
+ -s 49.0.0.0/8 -j DROP
214
+ -s 100.0.0.0/6 -j DROP
215
+ -s 104.0.0.0/7 -j DROP
216
+ -s 106.0.0.0/8 -j DROP
217
+ -s 127.0.0.0/8 -j DROP
218
+ -s 179.0.0.0/8 -j DROP
219
+ -s 185.0.0.0/8 -j DROP
220
+ -s 240.0.0.0/4 -j DROP
221
+ -s 169.254.0.0/16 -j DROP
222
+ -s 172.16.0.0/12 -j DROP
223
+ -s 192.0.2.0/24 -j DROP
224
+ -s 192.88.99.0/24 -j DROP
225
+ -s 192.168.0.0/16 -j DROP
226
+
227
+
228
+ # `additions` and `node_addition_points`
229
+
230
+ Since adding rules to a policy firewall is very common, there is a
231
+ shorthand for adding rules to one or more policy chains at predefined
232
+ points.
233
+
234
+ For instance, you may define the following policy (see `Rules`):
235
+
236
+ "policy": {
237
+ (other chains)
238
+ "in_public": {
239
+ "policy": "ACCEPT",
240
+ "rules": {
241
+ { "comment": "comment1" },
242
+ {
243
+ "node_addition_points": [
244
+ "in_public",
245
+ "in_*"
246
+ ]
247
+ }
248
+ { "comment": "comment2" },
249
+ }
250
+ }
251
+ }
252
+
253
+ You may then also choose to define the following rules:
254
+
255
+ "rules": {
256
+ "filter": {
257
+ "in_public": {
258
+ "additions": [
259
+ "comment": "public"
260
+ ]
261
+ },
262
+ "in_*": {
263
+ "additions": [
264
+ "comment": "all"
265
+ ]
266
+ }
267
+ }
268
+ }
269
+
270
+ The `rules` defined within the `in_public` chain or `in_*`
271
+ pseudo-chain would be added at the `node_addition_points` within the
272
+ table. So the generated firewall would contain:
273
+
274
+ -A in_public -m comment --comment "comment1"
275
+ -A in_public -m comment --comment "public"
276
+ -A in_public -m comment --comment "all"
277
+ -A in_public -m comment --comment "comment2"
278
+
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2013 Library of Congress
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy of
6
+ this software and associated documentation files (the "Software"), to deal in
7
+ the Software without restriction, including without limitation the rights to
8
+ use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
9
+ the Software, and to permit persons to whom the Software is furnished to do so,
10
+ subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
17
+ FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
18
+ COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
19
+ IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20
+ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,140 @@
1
+ Description
2
+ ===========
3
+
4
+ Iptables-gem is a Ruby API for parsing, generating, and comparing Linux
5
+ iptables rules. It is configured using JSON and oriented toward use
6
+ within configuration-management software such as
7
+ [http://www.opscode.com/chef/](Chef).
8
+
9
+ Requirements
10
+ ============
11
+
12
+ ## Ruby:
13
+
14
+ * Ruby: 1.8
15
+ * Likely also works on 1.9, but testing is giving me fits so I am ignoring it for now
16
+
17
+ ## Platforms:
18
+
19
+ The following platforms and versions are tested:
20
+
21
+ * Ubuntu 10.04, 12.04
22
+ * CentOS 6.4, Red Hat 6.4
23
+
24
+ Ruby Usage
25
+ ==========
26
+
27
+ Install this gem and `require iptables`. In the examples below,
28
+ `/path/to/json/` refers to the directory containing JSON policy files.
29
+ See [Generate.md](the firewall generation documentation) for information
30
+ on setting these up. There are also example configuration files in
31
+ `examples/policy/*.json`.
32
+
33
+ ## Generate a firewall
34
+
35
+ You will first need to create JSON firewall configuration files. See the
36
+ `Generating a Firewall` section below for details. Once this is done,
37
+ you can generate a firewall like so:
38
+
39
+ config = IPTables::Configuration.new
40
+ config.parse_files('/path/to/json/')
41
+ policy_fw = config.converge_firewall
42
+ puts policy_fw.as_array
43
+
44
+ ## Compare two firewalls
45
+
46
+ You can determine whether a proposed/policy firewall and the
47
+ currently-applied firewall are identical:
48
+
49
+ config = IPTables::Configuration.new
50
+ config.parse_files('/path/to/json/')
51
+ policy_fw = config.converge_firewall
52
+ active_fw = IPTables::Tables.new(%x/iptables-save/)
53
+ comparison = IPTables::TablesComparison.new(active_fw, policy_fw)
54
+ comparison.equal?
55
+
56
+ Alternately, you can compare firewalls using only `iptables-save` output:
57
+
58
+ active_fw = IPTables::Tables.new(%x/iptables-save/)
59
+ other_fw = IPTables::Tables.new(File.readlines('/path/to/another/saved/firewall'))
60
+ comparison = IPTables::TablesComparison.new(active_fw, policy_fw)
61
+ comparison.equal?
62
+
63
+ If two firewalls are the same **except** for embedded firewall comments,
64
+ you can ignore comments:
65
+
66
+ comparison.ignore_comments
67
+ comparison.equal?
68
+
69
+ If you want to see **exactly** how two firewalls differ:
70
+
71
+ comparison.as_array
72
+
73
+ ## Log
74
+
75
+ If you want to see debug messages, turn on logging:
76
+
77
+ require 'logger'
78
+ $log = Logger.new(STDOUT)
79
+ $log.level = Logger::DEBUG
80
+ config = IPTables::Configuration.new
81
+ config.parse_files('/path/to/json/')
82
+ policy_fw = config.converge_firewall
83
+
84
+ Generating a Firewall
85
+ =====================
86
+
87
+ An explanation of generating a firewall can be found within
88
+ [Generate.md](the firewall generation documentation). An example set of
89
+ configuration files to create a basic working firewall can be found in
90
+ `examples/policy/*.json`.
91
+
92
+ Included Scripts
93
+ ================
94
+
95
+ ## Nagios
96
+
97
+ The `bin` directory contains a Nagios helper script written in Ruby to
98
+ compare the running firewall against a "policy" firewall. To try it from
99
+ within the gem source directory (that is, without first installing the
100
+ gem), first copy `examples/policy` to a temporary location and edit the
101
+ policy files to taste. Then change to the `bin` directory and run:
102
+
103
+ `./check_firewall.rb -l=/path/to/iptables/gem/lib/ -v -c=/path/to/policy/`
104
+
105
+ The above example includes debugging information which makes it
106
+ unsuitable for use with Nagios. For "live" use with Nagios, you would
107
+ want to install this gem and run:
108
+
109
+ `check_firewall.rb -c=/path/to/policy/`
110
+
111
+ Tests
112
+ =====
113
+
114
+ To run unit tests:
115
+
116
+ * change to iptables directory
117
+ * run `rake`
118
+ * examine coverage reports in directory `coverage`
119
+
120
+ Future
121
+ ======
122
+
123
+ Changes/Features I would like to see:
124
+
125
+ * Is ipv6 even working?
126
+ * Write policy in YAML **or** JSON
127
+ * Deprecate `requires_primitive`: these should be ignored if there is no matching interpolation
128
+ * Deprecate `interpolated`: these should be properly handled inside **any** kind of rule
129
+ * Deprecate `comment` and `ulog`? These seem like they ought to be macros.
130
+ * `ulog` has `-p tcp` but this seems awkward; is it even useful?
131
+ * Do other stuff like ebtables too? Not sure it's in scope here. Certainly the gem name would need to be reconsidered.
132
+ * Generate better error messages when we encounter failures parsing configurations.
133
+ * Move development/testing/coverage environment to Ruby 1.9
134
+
135
+ License and Authors
136
+ ===================
137
+
138
+ * Author:: Kurt Yoder <kyoder@loc.gov>
139
+
140
+ See LICENSE file for project license information.