iptablez 1.0.2.pre → 1.0.3.pre
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/bin/iptablez-shell +6 -2
- data/lib/iptablez.rb +3 -0
- data/lib/iptablez/chains/chains.rb +45 -2
- data/lib/iptablez/commands/append_chain.rb +10 -0
- data/lib/iptablez/commands/helpers/argument_helpers.rb +4 -0
- data/lib/iptablez/commands/list.rb +11 -0
- data/lib/iptablez/commands/stats.rb +17 -0
- data/lib/iptablez/commands/stats/bytes.rb +81 -0
- data/lib/iptablez/commands/stats/packets.rb +80 -0
- data/lib/iptablez/helpers/README.md +113 -0
- data/lib/iptablez/helpers/version.rb +1 -1
- metadata +6 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1440f17ad339ac23dc229322f5ae21219029e598
|
4
|
+
data.tar.gz: 43742fd31b17bb868f5aa3d0672a22a153efc38c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 55c5f8de9bcea965e6d42554464291349aafaa7b3f5cf8713bc71fc46151c71cb745d9db19c62c685d6cf06bdcefe8c1f9ad1c6fe8e42fe97d050b0085627ef7
|
7
|
+
data.tar.gz: 8eb8c9e4ed6b8fd39ced1f8f812d64ea8db645f6c24e4c03e2e983615862055748da1b62f47aa94cb1b3923c44df9ac922bc14b4237e5d2627130ff61b08034c
|
data/bin/iptablez-shell
CHANGED
@@ -1,4 +1,3 @@
|
|
1
|
-
$LOAD_PATH.unshift File.expand_path('../../lib', __FILE__)
|
2
1
|
#!/usr/bin/env ruby
|
3
2
|
|
4
3
|
require 'iptablez'
|
@@ -7,15 +6,20 @@ require 'pry'
|
|
7
6
|
|
8
7
|
include Iptablez
|
9
8
|
|
9
|
+
def chains
|
10
|
+
Chains
|
11
|
+
end
|
12
|
+
|
10
13
|
prompt_name = "#{"<コ".red + ":".green + "彡".red} #{"~".blue} "
|
11
14
|
|
12
15
|
Pry.config.prompt = [
|
13
16
|
proc { |target_self, nest_level, pry|
|
14
|
-
"#{prompt_name}#{":#{nest_level}" unless nest_level.zero?}
|
17
|
+
"#{prompt_name}#{":#{nest_level}" unless nest_level.zero?} "
|
15
18
|
},
|
16
19
|
proc { |target_self, nest_level, pry|
|
17
20
|
"#{prompt_name}(#{Pry.view_clip(target_self)})#{":#{nest_level}" unless nest_level.zero?}* "
|
18
21
|
}
|
19
22
|
]
|
20
23
|
Pry.config.prompt_name = prompt_name
|
24
|
+
|
21
25
|
Pry.start
|
data/lib/iptablez.rb
CHANGED
@@ -12,6 +12,9 @@ require "iptablez/commands/flush_chain"
|
|
12
12
|
require "iptablez/commands/interface"
|
13
13
|
require "iptablez/commands/policy"
|
14
14
|
require "iptablez/commands/new_chain"
|
15
|
+
require "iptablez/commands/stats/bytes"
|
16
|
+
require "iptablez/commands/stats/packets"
|
17
|
+
require "iptablez/commands/stats"
|
15
18
|
require "iptablez/commands/append_chain"
|
16
19
|
require "iptablez/commands/rename_chain"
|
17
20
|
require "iptablez/commands/delete_chain"
|
@@ -169,6 +169,42 @@ module Iptablez
|
|
169
169
|
raise "Cannot use both a single name and multiple names together."
|
170
170
|
end
|
171
171
|
end
|
172
|
+
|
173
|
+
def self.stats
|
174
|
+
Commands::Stats
|
175
|
+
end
|
176
|
+
|
177
|
+
def self.packets
|
178
|
+
Commands::Stats::Packets
|
179
|
+
end
|
180
|
+
|
181
|
+
def self.bytes
|
182
|
+
Commands::Stats::Bytes
|
183
|
+
end
|
184
|
+
|
185
|
+
def self.list
|
186
|
+
Commands::List
|
187
|
+
end
|
188
|
+
|
189
|
+
def self.new_chain
|
190
|
+
Commands::NewChain
|
191
|
+
end
|
192
|
+
|
193
|
+
def self.delete_chain
|
194
|
+
Commands::DeleteChain
|
195
|
+
end
|
196
|
+
|
197
|
+
def self.flush_chain
|
198
|
+
Commands::FlushChain
|
199
|
+
end
|
200
|
+
|
201
|
+
def self.rename_chain
|
202
|
+
Commands::RenameChain
|
203
|
+
end
|
204
|
+
|
205
|
+
def self.append_chain
|
206
|
+
Commands::AppendChain
|
207
|
+
end
|
172
208
|
|
173
209
|
def self.create(name: false, names: [], error: false, continue: !error)
|
174
210
|
if name
|
@@ -205,7 +241,7 @@ module Iptablez
|
|
205
241
|
end
|
206
242
|
end
|
207
243
|
end
|
208
|
-
|
244
|
+
|
209
245
|
def self.rename(from: false, to: false, pairs: {}, error: false, continue: !error)
|
210
246
|
if from && to
|
211
247
|
Commands::RenameChain.chain(from: from, to: to, continue: continue) do |result|
|
@@ -220,7 +256,14 @@ module Iptablez
|
|
220
256
|
end
|
221
257
|
end
|
222
258
|
end
|
223
|
-
|
259
|
+
|
260
|
+
def self.append(name: false, names: [], error: false, continue: !error, **args)
|
261
|
+
if name
|
262
|
+
Commands::AppendChain.chain(name: name, continue: continue, **args)
|
263
|
+
elsif !names.empty?
|
264
|
+
Commands::AppendChain.chains(names: names, continue: continue, **args)
|
265
|
+
end
|
266
|
+
end
|
224
267
|
|
225
268
|
end
|
226
269
|
|
@@ -57,6 +57,16 @@ module Iptablez
|
|
57
57
|
end
|
58
58
|
end
|
59
59
|
|
60
|
+
def self.chains(names:, error: false, continue: !error, **args)
|
61
|
+
results = {}
|
62
|
+
names.each do |name|
|
63
|
+
results[name] = chain(name: name, continue: continue, **args) do |name, result|
|
64
|
+
yield [name, result] if block_given?
|
65
|
+
end
|
66
|
+
end
|
67
|
+
results
|
68
|
+
end
|
69
|
+
|
60
70
|
end
|
61
71
|
end
|
62
72
|
end
|
@@ -88,9 +88,13 @@ module Iptablez
|
|
88
88
|
results[:protocol] = normalize_protocol(args[:protocol])[:protocol] if args[:protocol]
|
89
89
|
results[:interface]= normalize_interface(args[:interface])[:interface] if args[:interface]
|
90
90
|
results[:src] = normalize_source(args[:src])[:source] if args[:src]
|
91
|
+
results[:src] = normalize_source(args[:source])[:source] if args[:source]
|
91
92
|
results[:sport] = normalize_source(args[:sport], port: true)[:source_port] if args[:sport]
|
93
|
+
results[:sport] = normalize_source(args[:source_port], port: true)[:source_port] if args[:source_port]
|
92
94
|
results[:dst] = normalize_destination(args[:dst])[:destination] if args[:dst]
|
95
|
+
results[:dst] = normalize_destination(args[:destination])[:destination] if args[:destination]
|
93
96
|
results[:dport] = normalize_destination(args[:dport], port: true)[:destination_port] if args[:dport]
|
97
|
+
results[:dport] = normalize_destination(args[:destination_port], port: true)[:destination_port] if args[:destination_port] # lol
|
94
98
|
results
|
95
99
|
end
|
96
100
|
|
@@ -205,6 +205,17 @@ module Iptablez
|
|
205
205
|
determine_error(chain: name, error: e)
|
206
206
|
end
|
207
207
|
end
|
208
|
+
|
209
|
+
def self.chains(names:, policy: false, error: false, continue: !error)
|
210
|
+
results = {}
|
211
|
+
names.each do |name|
|
212
|
+
results[name] = chain(name: name, policy: policy, continue: continue) do |name, result|
|
213
|
+
yield [name, result] if block_given?
|
214
|
+
end
|
215
|
+
end
|
216
|
+
results
|
217
|
+
end
|
218
|
+
|
208
219
|
end
|
209
220
|
end
|
210
221
|
end
|
@@ -0,0 +1,81 @@
|
|
1
|
+
module Iptablez
|
2
|
+
module Commands
|
3
|
+
module Stats
|
4
|
+
module Bytes
|
5
|
+
include MoveOn
|
6
|
+
UNKOWN_OPTION = 'unknown option'.freeze
|
7
|
+
NO_CHAIN_MATCH_ERROR = 'iptables: No chain/target/match by that name.'.freeze
|
8
|
+
PERMISSION_DENIED = 'Permission denied (you must be root)'.freeze
|
9
|
+
INVALID_RULE_NUMBER = 'Invalid rule number'.freeze
|
10
|
+
|
11
|
+
KNOWN_ERRORS = [NO_CHAIN_MATCH_ERROR, PERMISSION_DENIED, INVALID_RULE_NUMBER, UNKOWN_OPTION].freeze
|
12
|
+
|
13
|
+
# @api private
|
14
|
+
# Determine a given error. Optionally a chain can be used to provide better context.
|
15
|
+
private_class_method def self.determine_error(error:, chain: false, number: false)
|
16
|
+
if error == NO_CHAIN_MATCH_ERROR
|
17
|
+
raise ChainExistenceError, "#{chain} doesn't exist!"
|
18
|
+
elsif error == INVALID_RULE_NUMBER
|
19
|
+
raise InvalidRuleIndexError, "#{chain} invalid number #{number}!"
|
20
|
+
else
|
21
|
+
raise error
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def self.chain(name:, error: false, continue: !error, **args)
|
26
|
+
o, e, s = Open3.capture3(Iptablez.bin_path, '-L', name, '-v', '-n')
|
27
|
+
e.strip! # remove new line
|
28
|
+
if s.success?
|
29
|
+
result = if Iptablez::Chains.defaults.include?(name)
|
30
|
+
default_chain(o)
|
31
|
+
else
|
32
|
+
user_defined_chain(o)
|
33
|
+
end
|
34
|
+
yield [name, result] if block_given?
|
35
|
+
return result
|
36
|
+
elsif MoveOn.continue?(continue: continue, message: e, known_errors: KNOWN_ERRORS)
|
37
|
+
yield [name, false] if block_given?
|
38
|
+
return false
|
39
|
+
else
|
40
|
+
determine_error(chain: name, error: e)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
def self.chains(names:, error: false, continue: !error, **args)
|
45
|
+
results = {}
|
46
|
+
names.each do |name|
|
47
|
+
results[name] = chain(name: name, continue: continue) do |name, result|
|
48
|
+
yield [name, result] if block_given?
|
49
|
+
end
|
50
|
+
end
|
51
|
+
results
|
52
|
+
end
|
53
|
+
|
54
|
+
def self.user_defined_chain(o)
|
55
|
+
result = 0
|
56
|
+
o = o.split("\n")
|
57
|
+
2.times { o.delete_at(0) }
|
58
|
+
o.each { |line| result += line.split[1].to_i }
|
59
|
+
yield result if block_given?
|
60
|
+
result
|
61
|
+
end
|
62
|
+
|
63
|
+
def self.default_chain(o)
|
64
|
+
o = o.split("\n")
|
65
|
+
result = o[0].match(/\d+(K)/).to_s.to_i
|
66
|
+
yield result if block_given?
|
67
|
+
result
|
68
|
+
end
|
69
|
+
|
70
|
+
def self.all(names: Iptablez::Chains.all, error: false, continue: !error)
|
71
|
+
chains(names: names, continue: continue) do |name, result|
|
72
|
+
yield [name, result] if block_given?
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
|
77
|
+
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
@@ -0,0 +1,80 @@
|
|
1
|
+
module Iptablez
|
2
|
+
module Commands
|
3
|
+
module Stats
|
4
|
+
module Packets
|
5
|
+
include MoveOn
|
6
|
+
|
7
|
+
UNKOWN_OPTION = 'unknown option'.freeze
|
8
|
+
NO_CHAIN_MATCH_ERROR = 'iptables: No chain/target/match by that name.'.freeze
|
9
|
+
PERMISSION_DENIED = 'Permission denied (you must be root)'.freeze
|
10
|
+
INVALID_RULE_NUMBER = 'Invalid rule number'.freeze
|
11
|
+
|
12
|
+
KNOWN_ERRORS = [NO_CHAIN_MATCH_ERROR, PERMISSION_DENIED, INVALID_RULE_NUMBER, UNKOWN_OPTION].freeze
|
13
|
+
|
14
|
+
# @api private
|
15
|
+
# Determine a given error. Optionally a chain can be used to provide better context.
|
16
|
+
private_class_method def self.determine_error(error:, chain: false, number: false)
|
17
|
+
if error == NO_CHAIN_MATCH_ERROR
|
18
|
+
raise ChainExistenceError, "#{chain} doesn't exist!"
|
19
|
+
elsif error == INVALID_RULE_NUMBER
|
20
|
+
raise InvalidRuleIndexError, "#{chain} invalid number #{number}!"
|
21
|
+
else
|
22
|
+
raise error
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def self.chain(name:, error: false, continue: !error, **args)
|
27
|
+
o, e, s = Open3.capture3(Iptablez.bin_path, '-L', name, '-v', '-n')
|
28
|
+
e.strip! # remove new line
|
29
|
+
if s.success?
|
30
|
+
result = if Iptablez::Chains.defaults.include?(name)
|
31
|
+
default_chain(o)
|
32
|
+
else
|
33
|
+
user_defined_chain(o)
|
34
|
+
end
|
35
|
+
yield [name, result] if block_given?
|
36
|
+
return result
|
37
|
+
elsif MoveOn.continue?(continue: continue, message: e, known_errors: KNOWN_ERRORS)
|
38
|
+
yield [name, false] if block_given?
|
39
|
+
return false
|
40
|
+
else
|
41
|
+
determine_error(chain: name, error: e)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def self.user_defined_chain(o)
|
46
|
+
result = 0
|
47
|
+
o = o.split("\n")
|
48
|
+
2.times { o.delete_at(0) }
|
49
|
+
o.each { |line| result += line.split[0].to_i }
|
50
|
+
yield result if block_given?
|
51
|
+
result
|
52
|
+
end
|
53
|
+
|
54
|
+
def self.default_chain(o)
|
55
|
+
o = o.split("\n")
|
56
|
+
result = o[0].match(/\d+/).to_s.to_i
|
57
|
+
yield result if block_given?
|
58
|
+
result
|
59
|
+
end
|
60
|
+
|
61
|
+
def self.chains(names:, error: false, continue: !error, **args)
|
62
|
+
results = {}
|
63
|
+
names.each do |name|
|
64
|
+
results[name] = chain(name: name, continue: continue) do |name, result|
|
65
|
+
yield [name, result] if block_given?
|
66
|
+
end
|
67
|
+
end
|
68
|
+
results
|
69
|
+
end
|
70
|
+
|
71
|
+
def self.all(names: Iptablez::Chains.all, error: false, continue: !error)
|
72
|
+
chains(names: names, continue: continue) do |name, result|
|
73
|
+
yield [name, result] if block_given?
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
@@ -0,0 +1,113 @@
|
|
1
|
+
# Helpers
|
2
|
+
|
3
|
+
Iptablez helpers are here to make life easier by helping out.
|
4
|
+
|
5
|
+
## Method Overview
|
6
|
+
```ruby
|
7
|
+
require 'iptablez'
|
8
|
+
|
9
|
+
Iptablez.bin_path
|
10
|
+
Iptablez.version
|
11
|
+
Iptablez.list
|
12
|
+
Iptablez.chains
|
13
|
+
# more to come I'm sure...
|
14
|
+
```
|
15
|
+
|
16
|
+
## Bin Path
|
17
|
+
|
18
|
+
Return the full path to `iptables`.
|
19
|
+
|
20
|
+
```ruby
|
21
|
+
Iptablez.bin_path
|
22
|
+
# => "/sbin/iptables"
|
23
|
+
```
|
24
|
+
|
25
|
+
## Version
|
26
|
+
|
27
|
+
Get `iptables` version.
|
28
|
+
|
29
|
+
```ruby
|
30
|
+
Iptablez::Chains.version
|
31
|
+
# => "1.6.0"
|
32
|
+
```
|
33
|
+
|
34
|
+
## Delete
|
35
|
+
|
36
|
+
Delete a list of a given single `name` or an array of `names`. If the chain is not empty, the operation will fail. Consider flushing the chain(s) if you want to delete them.
|
37
|
+
|
38
|
+
```ruby
|
39
|
+
Iptablez::Chains.delete(name: "frogs") # frogs is not a real chain
|
40
|
+
# => false
|
41
|
+
|
42
|
+
Iptablez::Chains.delete(name: "frogs") do |name, result|
|
43
|
+
if result # this will be false
|
44
|
+
puts "#{name} was deleted!"
|
45
|
+
else
|
46
|
+
puts "#{name} couldn't be deleted!"
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
Iptablez::Chains.delete(names: ["dogs", "cats"])
|
51
|
+
# => {"dogs"=>true, "cats"=>true}
|
52
|
+
|
53
|
+
Iptablez::Chains.delete(names: ["dogs", "cats"]) do |name, result|
|
54
|
+
puts name if result # won't happen, already deleted! :)
|
55
|
+
end
|
56
|
+
# => {"dogs"=>false, "cats"=>false}
|
57
|
+
```
|
58
|
+
|
59
|
+
## Exists?
|
60
|
+
|
61
|
+
Check if a list of a given single `name` or an array of `names` actually exists.
|
62
|
+
|
63
|
+
```ruby
|
64
|
+
Iptablez::Chains.exists?(name: "frogs") # frogs is not a real chain
|
65
|
+
# => false
|
66
|
+
|
67
|
+
Iptablez::Chains.exists?(name: "frogs") do |name, result|
|
68
|
+
if result # this will be false
|
69
|
+
puts "#{name} exists!"
|
70
|
+
else
|
71
|
+
puts "#{name} doesn't exist!"
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
Iptablez::Chains.exists?(names: ["dogs", "cats"])
|
76
|
+
# => {"dogs"=>true, "cats"=>true}
|
77
|
+
|
78
|
+
Iptablez::Chains.exists?(names: ["dogs", "cats"]) do |name, result|
|
79
|
+
puts name if result # won't happen, already deleted! :)
|
80
|
+
end
|
81
|
+
# => {"dogs"=>false, "cats"=>false}
|
82
|
+
```
|
83
|
+
|
84
|
+
## Policies
|
85
|
+
|
86
|
+
Get a a list of a given single `name` or an array of `names` default policy response/target.
|
87
|
+
|
88
|
+
```ruby
|
89
|
+
Iptablez::Chains.policies(name: "frogs") # frogs is not a real chain
|
90
|
+
# => false
|
91
|
+
|
92
|
+
Iptablez::Chains.exists?(name: "frogs") do |name, result|
|
93
|
+
if result # this will be false
|
94
|
+
puts "#{name} exists!"
|
95
|
+
else
|
96
|
+
puts "#{name} doesn't exist!"
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
Iptablez::Chains.exists?(names: ["dogs", "cats"])
|
101
|
+
# => {"dogs"=>true, "cats"=>true}
|
102
|
+
|
103
|
+
Iptablez::Chains.exists?(names: ["dogs", "cats"]) do |name, result|
|
104
|
+
puts name if result # won't happen, already deleted! :)
|
105
|
+
end
|
106
|
+
# => {"dogs"=>false, "cats"=>false}
|
107
|
+
```
|
108
|
+
|
109
|
+
|
110
|
+
|
111
|
+
|
112
|
+
|
113
|
+
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: iptablez
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.
|
4
|
+
version: 1.0.3.pre
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Kent 'picat' Gruber
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-04-
|
11
|
+
date: 2017-04-28 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: colorize
|
@@ -114,8 +114,12 @@ files:
|
|
114
114
|
- lib/iptablez/commands/new_chain.rb
|
115
115
|
- lib/iptablez/commands/policy.rb
|
116
116
|
- lib/iptablez/commands/rename_chain.rb
|
117
|
+
- lib/iptablez/commands/stats.rb
|
118
|
+
- lib/iptablez/commands/stats/bytes.rb
|
119
|
+
- lib/iptablez/commands/stats/packets.rb
|
117
120
|
- lib/iptablez/commands/version.rb
|
118
121
|
- lib/iptablez/commands/zero.rb
|
122
|
+
- lib/iptablez/helpers/README.md
|
119
123
|
- lib/iptablez/helpers/helpers.rb
|
120
124
|
- lib/iptablez/helpers/version.rb
|
121
125
|
homepage: https://github.com/picatz/iptablez
|