riptables 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/MIT-LICENSE +20 -0
- data/README.md +130 -0
- data/bin/riptables +34 -0
- data/lib/riptables.rb +26 -0
- data/lib/riptables/chain.rb +17 -0
- data/lib/riptables/condition.rb +25 -0
- data/lib/riptables/dsl/global.rb +30 -0
- data/lib/riptables/dsl/root.rb +19 -0
- data/lib/riptables/dsl/rule.rb +30 -0
- data/lib/riptables/dsl/table.rb +43 -0
- data/lib/riptables/error.rb +4 -0
- data/lib/riptables/role_condition.rb +16 -0
- data/lib/riptables/rule.rb +39 -0
- data/lib/riptables/rule_permutation.rb +41 -0
- data/lib/riptables/table.rb +29 -0
- data/lib/riptables/table_export.rb +40 -0
- data/lib/riptables/version.rb +3 -0
- data/lib/riptables/zone_condition.rb +14 -0
- metadata +67 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 6163673be40ac8debc91fbbb58b934d622a0551b
|
4
|
+
data.tar.gz: 834420f08005d80abf266219d82445f9187b42cb
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: ffcca219d8afdab19f25844fa2e6352cd49f5149e7254fc70c691864db89c7698a4d7950639b9a93900165544cfe5bfb0b65901903352f1b3fa7d19eaaa71153
|
7
|
+
data.tar.gz: 97b4c44f8ec3b26978c6cf7e3bca149a7dfa79277f4f77db1e627beacf47f84b25e123444b427653e94bd8e1d087e6264a6a60ce26f48942e739ad7007b4c5e0
|
data/MIT-LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright 2014 Adam Cooke.
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,130 @@
|
|
1
|
+
# Riptables
|
2
|
+
|
3
|
+
Riptables (pronounced ri-pee-tables) is a Ruby DSL for generating configuration
|
4
|
+
for IP tables. The following design goals were employed for development:
|
5
|
+
|
6
|
+
* Must support IPv4 and IPv6 rules
|
7
|
+
* Must allow a single file to contain configuration for multiple environments
|
8
|
+
based on a given `role` and `zone`.
|
9
|
+
* Must support any type of table or chain.
|
10
|
+
* Must support any rule or action without limitation.
|
11
|
+
* Must include a command line tool for exporting configuration.
|
12
|
+
* Should be simple to understand the configuration syntax.
|
13
|
+
* Should be well documentated.
|
14
|
+
|
15
|
+
## `FirewallFile` Syntax
|
16
|
+
|
17
|
+
Riptables works with `FirewallFile` which contains the complete configuration for
|
18
|
+
all servers where this configuration will be distributed. In this example, we're
|
19
|
+
just going to configure a single rule to drop everything except SSH.
|
20
|
+
|
21
|
+
```ruby
|
22
|
+
# Using the `table` method we define a new table. In this case, we'll be
|
23
|
+
# configuring a simple firewall.
|
24
|
+
table :filter do
|
25
|
+
|
26
|
+
# Set some default actions for the three main chains in the filter table.
|
27
|
+
# The action you enter will simply be passed to iptables. If it is a symbol
|
28
|
+
# it will be uppercased otherwise it will be passed through un-touched.
|
29
|
+
default_action :input, :drop
|
30
|
+
default_action :forward, :accept
|
31
|
+
default_action :output, :accept
|
32
|
+
|
33
|
+
# In it's most basic form, you can add rules by simply calling the name of the
|
34
|
+
# chain and a description.
|
35
|
+
input "Allow SSH" do
|
36
|
+
# Set the conditions for the rule you want to apply. This is passed unfettered
|
37
|
+
# to iptables so you can write anything you would normally before the -j flag.
|
38
|
+
rule "-p tcp --dport 22"
|
39
|
+
# Set the action to take if the rule is matched. If this is a symbol it will
|
40
|
+
# be uppercased automatically. If it's a string, it will be passed stright
|
41
|
+
# through after a -j flag.
|
42
|
+
action :accept
|
43
|
+
end
|
44
|
+
|
45
|
+
end
|
46
|
+
```
|
47
|
+
|
48
|
+
### Permutations
|
49
|
+
|
50
|
+
If you have rules which are always similar to other rules (for example a set of
|
51
|
+
IP ranges which must all be permitted) you can use permutations.
|
52
|
+
|
53
|
+
```ruby
|
54
|
+
input "Allow web access" do
|
55
|
+
rule "-p tcp --dport {{port}}"
|
56
|
+
action :accept
|
57
|
+
permutation "Insecure", :port => "80"
|
58
|
+
permutation "Secure", :port => "443"
|
59
|
+
end
|
60
|
+
```
|
61
|
+
|
62
|
+
Each permutation will be applied as its own rule using the base rule as a template.
|
63
|
+
Using the variable interpolation, you can insert any variable you wish in each
|
64
|
+
permutation. The final `:v => 4` option sets that this should only apply to the
|
65
|
+
IPv4 firewall - it can be set to 6 to only apply them to IPv6 firewalls.
|
66
|
+
|
67
|
+
### Zones & Roles
|
68
|
+
|
69
|
+
If you have different types of servers and want to apply different rules based
|
70
|
+
on what and where a machine is, you can do so. You can either limit whole rules
|
71
|
+
or just permutations within a rule.
|
72
|
+
|
73
|
+
```ruby
|
74
|
+
# Any rules which are defined within this role block will only be included when
|
75
|
+
# you generate an iptables config for the `vpn` role.
|
76
|
+
role :vpn do
|
77
|
+
|
78
|
+
input "Allow management access" do
|
79
|
+
rule "-s {{ip}}"
|
80
|
+
action :accept
|
81
|
+
permutation "Allow Internal", :ip => '10.0.0.0/16', :v => 4
|
82
|
+
permutation "Allow IPv6", :ip => '2a00:67a0:a:123::/64', :v => 6
|
83
|
+
|
84
|
+
# Any permutations within this block will only be included when you generate
|
85
|
+
# an iptavles config for any `eu-east` zone or 'us-west-4'.
|
86
|
+
zone /eu\-east\-(\d+)/, "us-west-4" do
|
87
|
+
permutation "aTech Media", :ip => "185.22.208.0/25", :v => 4
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
end
|
92
|
+
```
|
93
|
+
|
94
|
+
### IPv4 vs. IPv6
|
95
|
+
|
96
|
+
By default, any rule you configure will apply to both your IPv4 firewall and your
|
97
|
+
IPv6 firewall. However, you can define rule or permutations to only use one or
|
98
|
+
the other.
|
99
|
+
|
100
|
+
```ruby
|
101
|
+
input "Block nasty IPv6 person" do
|
102
|
+
rule "-s 2a00:67a0:abc::1234/128"
|
103
|
+
action :drop
|
104
|
+
# Add the `version` option to restrict this rule to the IPv6 firewall only.
|
105
|
+
# You can also use `4` for the IPv4 firewall.
|
106
|
+
version 6
|
107
|
+
end
|
108
|
+
```
|
109
|
+
|
110
|
+
You'll see in the previous example, you can pass the `:v` option to permutations
|
111
|
+
to restrict which firewall they belong to. Default rules will always apply to
|
112
|
+
both and cannot currently be different depending on IP version.
|
113
|
+
|
114
|
+
## Command Line
|
115
|
+
|
116
|
+
The `riptables` command is used to generate your iptables-save files. These can
|
117
|
+
then be used with `iptables-restore`.
|
118
|
+
|
119
|
+
```text
|
120
|
+
$ riptables
|
121
|
+
```
|
122
|
+
|
123
|
+
The following options are supported and can be used interchagably:
|
124
|
+
|
125
|
+
* `-4` - return the IPv4 configuration (default)
|
126
|
+
* `-6` - return the IPv6 configuration (defaults to v4)
|
127
|
+
* `-f [PATH]` - path to your FirewallFile (defaults to ./FirewallFile)
|
128
|
+
* `--zone [ZONE]` - set the zone to export configuration for
|
129
|
+
* `--role [ROLE]` - set the role to export configuration for
|
130
|
+
* `--color` - return a [colorized output](http://s.adamcooke.io/14/Vmzd2.png) (useful for debugging)
|
data/bin/riptables
ADDED
@@ -0,0 +1,34 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
$:.unshift(File.expand_path('../../lib', __FILE__))
|
3
|
+
require 'riptables'
|
4
|
+
require 'optparse'
|
5
|
+
|
6
|
+
options = {}
|
7
|
+
options[:conditions] = {}
|
8
|
+
options[:color] = false
|
9
|
+
ipv = 4
|
10
|
+
load_path = File.expand_path('./FirewallFile')
|
11
|
+
|
12
|
+
OptionParser.new do |opts|
|
13
|
+
opts.banner = "Usage: riptables [options]"
|
14
|
+
opts.on("-4", "Return IPv6 records") { ipv = 4 }
|
15
|
+
opts.on("-6", "Return IPv6 records") { ipv = 6 }
|
16
|
+
opts.on("-r", "--role [ROLE]", "The role to generate for") { |v| options[:conditions][:role] = v }
|
17
|
+
opts.on("-z", "--zone [ZONE]", "The zone to generate for") { |v| options[:conditions][:zone] = v }
|
18
|
+
opts.on("--color", "Colorize the output") { |v| options[:color] = true }
|
19
|
+
opts.on("--color", "Colorize the output") { |v| options[:color] = true }
|
20
|
+
opts.on("-f", "--file [PATH]", "The Riptables configuration file") { |v| load_path = v }
|
21
|
+
end.parse!
|
22
|
+
|
23
|
+
begin
|
24
|
+
Riptables.load_from_file(load_path)
|
25
|
+
Riptables.tables.each do |table|
|
26
|
+
puts table.export(options).to_savefile(ipv)
|
27
|
+
end
|
28
|
+
rescue Riptables::Error => e
|
29
|
+
$stderr.puts "\e[31m#{e}\e[0m"
|
30
|
+
exit 1
|
31
|
+
rescue => e
|
32
|
+
$stderr.puts "\e[31m#{e.class}: #{e.message}\e[0m"
|
33
|
+
exit 1
|
34
|
+
end
|
data/lib/riptables.rb
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'riptables/dsl/root'
|
2
|
+
require 'riptables/error'
|
3
|
+
|
4
|
+
module Riptables
|
5
|
+
|
6
|
+
#
|
7
|
+
# Store all tables configured
|
8
|
+
#
|
9
|
+
def self.tables
|
10
|
+
@tables ||= []
|
11
|
+
end
|
12
|
+
|
13
|
+
#
|
14
|
+
# Parse a given file
|
15
|
+
#
|
16
|
+
def self.load_from_file(file)
|
17
|
+
if File.file?(file)
|
18
|
+
dsl = DSL::Root.new
|
19
|
+
dsl.instance_eval(File.read(file), file)
|
20
|
+
true
|
21
|
+
else
|
22
|
+
raise Error, "File not found at `#{file}`"
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module Riptables
|
2
|
+
class Chain
|
3
|
+
|
4
|
+
def initialize(table, name)
|
5
|
+
@table = table
|
6
|
+
@name = name
|
7
|
+
@default_action = :accept
|
8
|
+
@rules = []
|
9
|
+
end
|
10
|
+
|
11
|
+
attr_accessor :default_action
|
12
|
+
attr_reader :table
|
13
|
+
attr_reader :name
|
14
|
+
attr_reader :rules
|
15
|
+
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require 'riptables/condition'
|
2
|
+
|
3
|
+
module Riptables
|
4
|
+
class Condition
|
5
|
+
|
6
|
+
def self.conditions
|
7
|
+
@conditions ||= []
|
8
|
+
end
|
9
|
+
|
10
|
+
def initialize(condition, &block)
|
11
|
+
@condition = [condition].flatten
|
12
|
+
@block = block
|
13
|
+
self.call
|
14
|
+
end
|
15
|
+
|
16
|
+
attr_reader :condition
|
17
|
+
|
18
|
+
def call
|
19
|
+
Condition.conditions << self
|
20
|
+
@block.call
|
21
|
+
Condition.conditions.delete(self)
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
require 'riptables/zone_condition'
|
2
|
+
require 'riptables/role_condition'
|
3
|
+
|
4
|
+
module Riptables
|
5
|
+
module DSL
|
6
|
+
class Global
|
7
|
+
|
8
|
+
#
|
9
|
+
# Any rules which are defined while inside this block should only apply
|
10
|
+
# to the associated zones.
|
11
|
+
#
|
12
|
+
def zone(*zones, &block)
|
13
|
+
ZoneCondition.new(zones) do
|
14
|
+
block.call
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
#
|
19
|
+
# Any rules which are defined while inside this block should only apply
|
20
|
+
# to the associated roles.
|
21
|
+
#
|
22
|
+
def role(*roles, &block)
|
23
|
+
RoleCondition.new(roles) do
|
24
|
+
block.call
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
require 'riptables/dsl/global'
|
2
|
+
require 'riptables/table'
|
3
|
+
|
4
|
+
module Riptables
|
5
|
+
module DSL
|
6
|
+
class Root < Global
|
7
|
+
|
8
|
+
#
|
9
|
+
# Rules within a given table
|
10
|
+
#
|
11
|
+
def table(name, &block)
|
12
|
+
table = Riptables::Table.new(name)
|
13
|
+
table.dsl.instance_eval(&block)
|
14
|
+
Riptables.tables << table
|
15
|
+
end
|
16
|
+
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
require 'riptables/dsl/global'
|
2
|
+
require 'riptables/rule_permutation'
|
3
|
+
|
4
|
+
module Riptables
|
5
|
+
module DSL
|
6
|
+
class Rule < Global
|
7
|
+
|
8
|
+
def initialize(rule)
|
9
|
+
@rule = rule
|
10
|
+
end
|
11
|
+
|
12
|
+
def rule(rule)
|
13
|
+
@rule.rule = rule
|
14
|
+
end
|
15
|
+
|
16
|
+
def action(action)
|
17
|
+
@rule.action = action
|
18
|
+
end
|
19
|
+
|
20
|
+
def permutation(description, options = {})
|
21
|
+
@rule.permutations << RulePermutation.new(@rule, description, options)
|
22
|
+
end
|
23
|
+
|
24
|
+
def version(number)
|
25
|
+
@rule.versions = [number]
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
require 'riptables/dsl/global'
|
2
|
+
require 'riptables/rule'
|
3
|
+
|
4
|
+
module Riptables
|
5
|
+
module DSL
|
6
|
+
class Table < Global
|
7
|
+
|
8
|
+
def initialize(table)
|
9
|
+
@table = table
|
10
|
+
end
|
11
|
+
|
12
|
+
#
|
13
|
+
# Defines a default rule for a chain on this table
|
14
|
+
#
|
15
|
+
def default_action(chain, action)
|
16
|
+
@table.chain(chain).default_action = action
|
17
|
+
end
|
18
|
+
|
19
|
+
#
|
20
|
+
# Add a new rule in this table
|
21
|
+
#
|
22
|
+
def rule(chain, description = nil, &block)
|
23
|
+
rule = Riptables::Rule.new(@table.chain(chain))
|
24
|
+
rule.description = description
|
25
|
+
rule.dsl.instance_eval(&block)
|
26
|
+
@table.chain(chain).rules << rule
|
27
|
+
end
|
28
|
+
|
29
|
+
#
|
30
|
+
# Any method which do not exist are most likely just new rules when inside
|
31
|
+
# this block.
|
32
|
+
#
|
33
|
+
def method_missing(chain, *args, &block)
|
34
|
+
if block_given?
|
35
|
+
self.rule(chain, *args, &block)
|
36
|
+
else
|
37
|
+
super
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'riptables/condition'
|
2
|
+
|
3
|
+
module Riptables
|
4
|
+
class RoleCondition < Condition
|
5
|
+
|
6
|
+
def matches?(conditions)
|
7
|
+
return false unless conditions[:role]
|
8
|
+
roles = conditions[:role].split(/\s?\,\s?/)
|
9
|
+
roles.each do |role|
|
10
|
+
return true if condition.any? { |c| c.is_a?(Regexp) ? c.match(role) : role.to_s == c.to_s }
|
11
|
+
end
|
12
|
+
return false
|
13
|
+
end
|
14
|
+
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
require 'riptables/dsl/rule'
|
2
|
+
|
3
|
+
module Riptables
|
4
|
+
class Rule
|
5
|
+
|
6
|
+
def initialize(chain)
|
7
|
+
@chain = chain
|
8
|
+
@permutations = []
|
9
|
+
@conditions = Condition.conditions.dup
|
10
|
+
@versions = [4, 6]
|
11
|
+
end
|
12
|
+
|
13
|
+
attr_accessor :description
|
14
|
+
attr_accessor :rule
|
15
|
+
attr_accessor :action
|
16
|
+
attr_accessor :conditions
|
17
|
+
attr_accessor :versions
|
18
|
+
attr_reader :chain
|
19
|
+
attr_reader :permutations
|
20
|
+
attr_reader :conditions
|
21
|
+
|
22
|
+
def dsl
|
23
|
+
@dsl ||= DSL::Rule.new(self)
|
24
|
+
end
|
25
|
+
|
26
|
+
def include?(conditions)
|
27
|
+
@conditions.all? { |c| c.matches?(conditions) }
|
28
|
+
end
|
29
|
+
|
30
|
+
def permuted_rules
|
31
|
+
if permutations.empty?
|
32
|
+
[self]
|
33
|
+
else
|
34
|
+
permutations.map(&:to_rule)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
require 'riptables/condition'
|
2
|
+
require 'riptables/rule'
|
3
|
+
|
4
|
+
module Riptables
|
5
|
+
class RulePermutation
|
6
|
+
|
7
|
+
def initialize(rule, description, options = {})
|
8
|
+
@rule = rule
|
9
|
+
@description = description
|
10
|
+
@options = options
|
11
|
+
@conditions = Condition.conditions.dup - @rule.conditions
|
12
|
+
end
|
13
|
+
|
14
|
+
attr_reader :rule
|
15
|
+
attr_reader :description
|
16
|
+
attr_reader :options
|
17
|
+
attr_reader :conditions
|
18
|
+
|
19
|
+
#
|
20
|
+
# Convert this permutation into a full rule in its own right
|
21
|
+
#
|
22
|
+
def to_rule
|
23
|
+
new_rule = Rule.new(rule.chain)
|
24
|
+
new_rule.description = "#{rule.description} (#{self.description})"
|
25
|
+
new_rule.rule = rule.rule.gsub(/\{\{(\w+)\}\}/) do
|
26
|
+
if value = self.options[$1.to_sym]
|
27
|
+
value
|
28
|
+
else
|
29
|
+
"{{#{$1}}}"
|
30
|
+
end
|
31
|
+
end
|
32
|
+
new_rule.action = rule.action
|
33
|
+
new_rule.conditions = rule.conditions | self.conditions
|
34
|
+
if v = (self.options[:v] || self.options[:version])
|
35
|
+
new_rule.versions = [v.to_i]
|
36
|
+
end
|
37
|
+
new_rule
|
38
|
+
end
|
39
|
+
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
require 'riptables/dsl/table'
|
2
|
+
require 'riptables/chain'
|
3
|
+
require 'riptables/table_export'
|
4
|
+
|
5
|
+
module Riptables
|
6
|
+
class Table
|
7
|
+
|
8
|
+
attr_reader :name
|
9
|
+
attr_reader :chains
|
10
|
+
|
11
|
+
def initialize(name)
|
12
|
+
@name = name
|
13
|
+
@chains = {}
|
14
|
+
end
|
15
|
+
|
16
|
+
def dsl
|
17
|
+
@dsl ||= DSL::Table.new(self)
|
18
|
+
end
|
19
|
+
|
20
|
+
def chain(name)
|
21
|
+
@chains[name] ||= Chain.new(self, name)
|
22
|
+
end
|
23
|
+
|
24
|
+
def export(options = {})
|
25
|
+
TableExport.new(self, options)
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
module Riptables
|
2
|
+
class TableExport
|
3
|
+
|
4
|
+
def initialize(table, options = {})
|
5
|
+
@table = table
|
6
|
+
@options = options
|
7
|
+
end
|
8
|
+
|
9
|
+
def to_savefile(version = 4)
|
10
|
+
Array.new.tap do |s|
|
11
|
+
s << "*#{col 31, @table.name}"
|
12
|
+
@table.chains.each do |_, chain|
|
13
|
+
s << ":#{col 32, chain.name.to_s.upcase} #{col 35, chain.default_action.to_s.upcase} [0:0]"
|
14
|
+
end
|
15
|
+
|
16
|
+
@table.chains.each do |_, chain|
|
17
|
+
chain.rules.map(&:permuted_rules).flatten.each do |rule|
|
18
|
+
next unless rule.include?(@options[:conditions] || {})
|
19
|
+
next unless rule.versions.include?(version)
|
20
|
+
action = rule.action ? "-j #{rule.action.is_a?(Symbol) ? rule.action.upcase : rule.action}" : ''
|
21
|
+
comment = "-m comment --comment=\"#{rule.description.gsub('"', '\'')}\""
|
22
|
+
s << "-A #{col 32, chain.name.to_s.upcase} #{col 33, rule.rule} #{col 35, action} #{col 36, comment}"
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
s << "COMMIT"
|
27
|
+
s << "# Compiled by riptables on #{Time.now.strftime("%a %b %e %H:%M:%S %Y")}"
|
28
|
+
end.join("\n")
|
29
|
+
end
|
30
|
+
|
31
|
+
def col(number, text)
|
32
|
+
if @options[:color] == false
|
33
|
+
text
|
34
|
+
else
|
35
|
+
"\e[#{number}m#{text}\e[0m"
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
require 'riptables/condition'
|
2
|
+
|
3
|
+
module Riptables
|
4
|
+
class ZoneCondition < Condition
|
5
|
+
|
6
|
+
def matches?(conditions)
|
7
|
+
conditions[:zone] &&
|
8
|
+
condition.any? do |c|
|
9
|
+
c.is_a?(Regexp) ? c.match(conditions[:zone]) : conditions[:zone].to_s == c.to_s
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
end
|
14
|
+
end
|
metadata
ADDED
@@ -0,0 +1,67 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: riptables
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Adam Cooke
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2014-11-21 00:00:00.000000000 Z
|
12
|
+
dependencies: []
|
13
|
+
description: 'An Ruby DSL for generating iptables configuration. '
|
14
|
+
email:
|
15
|
+
- me@adamcooke.io
|
16
|
+
executables:
|
17
|
+
- riptables
|
18
|
+
extensions: []
|
19
|
+
extra_rdoc_files: []
|
20
|
+
files:
|
21
|
+
- MIT-LICENSE
|
22
|
+
- README.md
|
23
|
+
- bin/riptables
|
24
|
+
- lib/riptables.rb
|
25
|
+
- lib/riptables/chain.rb
|
26
|
+
- lib/riptables/condition.rb
|
27
|
+
- lib/riptables/dsl/global.rb
|
28
|
+
- lib/riptables/dsl/root.rb
|
29
|
+
- lib/riptables/dsl/rule.rb
|
30
|
+
- lib/riptables/dsl/table.rb
|
31
|
+
- lib/riptables/error.rb
|
32
|
+
- lib/riptables/role_condition.rb
|
33
|
+
- lib/riptables/rule.rb
|
34
|
+
- lib/riptables/rule_permutation.rb
|
35
|
+
- lib/riptables/table.rb
|
36
|
+
- lib/riptables/table_export.rb
|
37
|
+
- lib/riptables/version.rb
|
38
|
+
- lib/riptables/zone_condition.rb
|
39
|
+
homepage: http://adamcooke.io
|
40
|
+
licenses:
|
41
|
+
- MIT
|
42
|
+
metadata: {}
|
43
|
+
post_install_message:
|
44
|
+
rdoc_options: []
|
45
|
+
require_paths:
|
46
|
+
- lib
|
47
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
48
|
+
requirements:
|
49
|
+
- - ">="
|
50
|
+
- !ruby/object:Gem::Version
|
51
|
+
version: '2.0'
|
52
|
+
- - "<"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '3'
|
55
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
56
|
+
requirements:
|
57
|
+
- - ">="
|
58
|
+
- !ruby/object:Gem::Version
|
59
|
+
version: '0'
|
60
|
+
requirements: []
|
61
|
+
rubyforge_project:
|
62
|
+
rubygems_version: 2.2.2
|
63
|
+
signing_key:
|
64
|
+
specification_version: 4
|
65
|
+
summary: An Ruby DSL for generating iptables configuration.
|
66
|
+
test_files: []
|
67
|
+
has_rdoc:
|