iptables-ruby 0.2.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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.