iptablez 1.0.2.pre → 1.0.3.pre
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 +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
|