shutter 0.0.6 → 0.0.7
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +1 -0
- data/README.md +58 -8
- data/SERVER.md +5 -0
- data/bin/shutter +2 -2
- data/lib/shutter.rb +1 -0
- data/lib/shutter/command_line.rb +13 -1
- data/lib/shutter/content.rb +20 -0
- data/lib/shutter/iptables.rb +1 -0
- data/lib/shutter/iptables/base.rb +10 -0
- data/lib/shutter/iptables/forward.rb +47 -0
- data/lib/shutter/version.rb +1 -1
- metadata +4 -2
data/.gitignore
CHANGED
data/README.md
CHANGED
@@ -1,9 +1,12 @@
|
|
1
1
|
# Shutter
|
2
2
|
|
3
|
-
Shutter is a tool that
|
4
|
-
iptables firewall settings through simple lists instead of complex iptables commands
|
5
|
-
|
6
|
-
distributions
|
3
|
+
Shutter is a tool that gives system administrators the ability to manage
|
4
|
+
iptables firewall settings through simple lists instead of complex iptables commands, making it
|
5
|
+
easier to define host and service firewall setting with configuration management tools. Please note:
|
6
|
+
This application currently only works with Red Hat based distributions, as the need arises more
|
7
|
+
distributions will be added.
|
8
|
+
|
9
|
+
**Note: Shutter server is not yet complete**
|
7
10
|
|
8
11
|
## Installation
|
9
12
|
|
@@ -11,6 +14,12 @@ Instalation is through the gem package management program.
|
|
11
14
|
|
12
15
|
$ gem install shutter
|
13
16
|
|
17
|
+
## Upgrading from 0.0.6 to 0.0.7
|
18
|
+
|
19
|
+
Version 0.0.7 adds forwarding capabilities to shutter. To upgrade the base template and add the new configuration files, use the following command:
|
20
|
+
|
21
|
+
$ shutter --upgrade
|
22
|
+
|
14
23
|
## Usage
|
15
24
|
|
16
25
|
#### Install the gem.
|
@@ -36,19 +45,60 @@ placeholders. By default the files are will be found in the */etc/shutter.d* di
|
|
36
45
|
* **ports.public:** A list of ports and protocols that are available publically to everyone except the 'Bastards' listed in ip.deny
|
37
46
|
|
38
47
|
Shutter was designed to work with the Fail2ban access monitoring/management tool. It includes a
|
39
|
-
special chain called 'Jail' which is used to insert the jump rules that fail2ban uses to deny
|
40
|
-
To work correctly, you configure fail2ban to use the Jail chain instead of
|
48
|
+
special chain called 'Jail' which is used to insert the jump rules that fail2ban uses to deny
|
49
|
+
access 'on-the-fly'. To work correctly, you configure fail2ban to use the Jail chain instead of
|
50
|
+
INPUT. The dynamic rules that fail2ban has created in the jail chain remain persistant when
|
51
|
+
shutter is 'restored' or reloaded.
|
52
|
+
|
53
|
+
Shutter can also run as a server to recieve requests from clients to populate the ip.allow and ip.deny files from a central location. To use this feature, you will need to generate an encryption key on the system you plan on using as the server by running the command:
|
54
|
+
|
55
|
+
server $ shutter --keygen
|
56
|
+
|
57
|
+
This will create the file validation.pem in the /etc/shutter.d (or the user defined) folder. The validation key can then be distributed to the shutter clients to pull in lists. On the shutter server, you will need to define the available lists in the server.json configuration file. It could look like this:
|
58
|
+
|
59
|
+
{
|
60
|
+
'allow_lists': [
|
61
|
+
'default.allow',
|
62
|
+
'private.allow',
|
63
|
+
'public.allow'
|
64
|
+
],
|
65
|
+
'deny_lists': [
|
66
|
+
'default.deny',
|
67
|
+
'bastards.deny'
|
68
|
+
]
|
69
|
+
}
|
70
|
+
|
71
|
+
To start the server run:
|
72
|
+
|
73
|
+
server $ shutter --server start
|
74
|
+
|
75
|
+
To stop the server run:
|
76
|
+
|
77
|
+
server $ shutter --server stop
|
78
|
+
|
79
|
+
To restart the server run:
|
80
|
+
|
81
|
+
server $ shutter --server restart
|
82
|
+
|
83
|
+
The first time you run shutter-server, empty files will be created in /etc/shutter.d/lists. Edit the files just like you would the ip.allow and ip.deny files. Make sure you copy the validation.pem file to your client and then on the client run:
|
84
|
+
|
85
|
+
client $ shutter --allow private --remote shutter.example.com
|
86
|
+
|
87
|
+
If the '--allow' is not specified it will grab default.allow file and if the file does not exist on the server it will return an error. In this case, shutter will grab the private.allow file from the remote site and replace ip.allow with the contents if the contents have changed.
|
88
|
+
|
89
|
+
Under the hood: A request is sent out to retrieve the MD5 sum of the file that lives on the server, if the md5sum of the file on the remote server is different than the one that is on the local server, the file is retrieved and updated on the client.
|
90
|
+
|
41
91
|
|
42
92
|
#### To check your firewall you can run:
|
43
93
|
|
44
|
-
$ shutter --save
|
94
|
+
client $ shutter --save
|
45
95
|
|
46
96
|
This command mimics the 'iptables-save' command which prints the rules out to the screen.
|
47
97
|
This does not modify the firewall settings.
|
48
98
|
|
49
99
|
#### To implement the changes, use:
|
50
100
|
|
51
|
-
$ shutter --restore
|
101
|
+
client $ shutter --restore
|
52
102
|
|
53
103
|
This command uses 'iptables-restore' under the hood to update the firewall. You can use the '--persist' option
|
54
104
|
to make the changes permanent and survive reboots.
|
data/SERVER.md
ADDED
data/bin/shutter
CHANGED
@@ -6,6 +6,6 @@ rescue LoadError
|
|
6
6
|
end
|
7
7
|
|
8
8
|
require 'shutter'
|
9
|
-
config_path = ENV['SHUTTER_CONFIG']
|
10
|
-
ENV['SHUTTER_MODE'] = "production"
|
9
|
+
config_path = ENV['SHUTTER_CONFIG'] || "/etc/shutter.d"
|
10
|
+
ENV['SHUTTER_MODE'] = ENV['SHUTTER_MODE'] || "production"
|
11
11
|
Shutter::CommandLine.new(config_path).execute
|
data/lib/shutter.rb
CHANGED
data/lib/shutter/command_line.rb
CHANGED
@@ -14,7 +14,6 @@ module Shutter
|
|
14
14
|
exit
|
15
15
|
end
|
16
16
|
end
|
17
|
-
|
18
17
|
@config_path = path
|
19
18
|
end
|
20
19
|
|
@@ -33,6 +32,9 @@ module Shutter
|
|
33
32
|
opts.on( '--reinit', 'Rereate the initial configuration files' ) do
|
34
33
|
options[:command] = :reinit
|
35
34
|
end
|
35
|
+
opts.on( '--upgrade', 'Rereate the base template to add new features' ) do
|
36
|
+
options[:command] = :upgrade
|
37
|
+
end
|
36
38
|
opts.on( '-s', '--save', 'Output the firewall to stdout. (DEFAULT)') do
|
37
39
|
options[:command] = :save
|
38
40
|
end
|
@@ -85,6 +87,16 @@ module Shutter
|
|
85
87
|
end
|
86
88
|
end
|
87
89
|
|
90
|
+
def upgrade
|
91
|
+
create_config_dir
|
92
|
+
["base.ipt", "iface.forward"].each do |name|
|
93
|
+
file = "#{@config_path}/#{name}"
|
94
|
+
File.open(file, 'w') do |f|
|
95
|
+
f.write(Shutter.const_get(name.upcase.gsub(/\./, "_")))
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
88
100
|
def save
|
89
101
|
init
|
90
102
|
@ipt = iptables.generate
|
data/lib/shutter/content.rb
CHANGED
@@ -139,12 +139,27 @@ BASE_IPT = %q{# Generated by Shutter
|
|
139
139
|
-A DropDDOS ! -d 0.0.0.255/0.0.0.255 -m limit --limit 3/min -j LOG --log-prefix "iptables: DDOS detected:"
|
140
140
|
-A DropDDOS -j DROP
|
141
141
|
|
142
|
+
##################################################################
|
143
|
+
# NATing
|
144
|
+
##################################################################
|
145
|
+
# [RULES:FORWARD]
|
146
|
+
-A FORWARD ! -d 0.0.0.255/0.0.0.255 -m limit --limit 3/min -j LOG --log-prefix "iptables: Unauthorized Forward:"
|
147
|
+
-A FORWARD -j DROP
|
148
|
+
|
142
149
|
##################################################################
|
143
150
|
# Add any additional rules that fail2ban has added
|
144
151
|
##################################################################
|
145
152
|
# [RULES:FAIL2BAN]
|
146
153
|
|
147
154
|
COMMIT
|
155
|
+
|
156
|
+
*nat
|
157
|
+
:PREROUTING ACCEPT [0:0]
|
158
|
+
:POSTROUTING ACCEPT [0:0]
|
159
|
+
:OUTPUT ACCEPT [0:0]
|
160
|
+
# [RULES:POSTROUTING]
|
161
|
+
COMMIT
|
162
|
+
|
148
163
|
}
|
149
164
|
|
150
165
|
IFACE_DMZ = %q{# Generated by Shutter
|
@@ -175,4 +190,9 @@ PORTS_PRIVATE = %q{
|
|
175
190
|
# proto port
|
176
191
|
22 tcp
|
177
192
|
}
|
193
|
+
|
194
|
+
IFACE_FORWARD = %q{
|
195
|
+
# src iface | dst iface
|
196
|
+
# eth0 eth1
|
197
|
+
}
|
178
198
|
end
|
data/lib/shutter/iptables.rb
CHANGED
@@ -23,20 +23,30 @@ module Shutter
|
|
23
23
|
def generate_filter
|
24
24
|
@dmz = Iface.new("#{@path}", :dmz).to_ipt
|
25
25
|
@content = @content.gsub(/#\ \[RULES:DMZ\]/, @dmz)
|
26
|
+
|
27
|
+
@forward = Forward.new("#{@path}")
|
28
|
+
@content = @content.gsub(/#\ \[RULES:FORWARD\]/, @forward.to_forward_ipt)
|
29
|
+
@content = @content.gsub(/#\ \[RULES:POSTROUTING\]/, @forward.to_masq_ipt)
|
30
|
+
|
26
31
|
@bastards = EyePee.new("#{@path}", :deny).to_ipt
|
27
32
|
@content = @content.gsub(/#\ \[RULES:BASTARDS\]/, @bastards)
|
33
|
+
|
28
34
|
@public = Port.new("#{@path}", :public).to_ipt
|
29
35
|
@content = @content.gsub(/#\ \[RULES:PUBLIC\]/, @public)
|
36
|
+
|
30
37
|
@allow = EyePee.new("#{@path}", :allow).to_ipt
|
31
38
|
@content = @content.gsub(/#\ \[RULES:ALLOWIP\]/, @allow)
|
39
|
+
|
32
40
|
@private = Port.new("#{@path}", :private).to_ipt
|
33
41
|
@content = @content.gsub(/#\ \[RULES:PRIVATE\]/, @private)
|
34
42
|
|
35
43
|
# Make sure we are restoring what fail2ban has added
|
36
44
|
@f2b_chains = Jail.new.fail2ban_chains
|
37
45
|
@content = @content.gsub(/#\ \[CHAIN:FAIL2BAN\]/, @f2b_chains)
|
46
|
+
|
38
47
|
@f2b_rules = Jail.new.fail2ban_rules
|
39
48
|
@content = @content.gsub(/#\ \[RULES:FAIL2BAN\]/, @f2b_rules)
|
49
|
+
|
40
50
|
@jail = Jail.new.jail_rules
|
41
51
|
@content = @content.gsub(/#\ \[RULES:JAIL\]/, @jail)
|
42
52
|
|
@@ -0,0 +1,47 @@
|
|
1
|
+
module Shutter
|
2
|
+
module IPTables
|
3
|
+
class Forward
|
4
|
+
def initialize( path )
|
5
|
+
file = File.open("#{path}/iface.forward", "r")
|
6
|
+
@content = file.read
|
7
|
+
@forward = ""
|
8
|
+
@masq = ""
|
9
|
+
@masq_ifaces = []
|
10
|
+
@content.each_line do |line|
|
11
|
+
line = line.strip
|
12
|
+
if line =~ /^[a-z].+$/
|
13
|
+
src, dst = line.split(' ')
|
14
|
+
@forward += forward_ipt(src,dst)
|
15
|
+
@masq_ifaces << dst unless @masq_ifaces.include?(dst)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
@masq_ifaces.each do |iface|
|
19
|
+
@masq += masq_ipt(iface)
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
23
|
+
|
24
|
+
def to_s
|
25
|
+
@content
|
26
|
+
end
|
27
|
+
|
28
|
+
def to_forward_ipt
|
29
|
+
@forward
|
30
|
+
end
|
31
|
+
|
32
|
+
def to_masq_ipt
|
33
|
+
@masq
|
34
|
+
end
|
35
|
+
|
36
|
+
def forward_ipt( src, dst )
|
37
|
+
rule = "-A FORWARD -i #{src} -o #{dst} -m state --state NEW,RELATED,ESTABLISHED -j ACCEPT\n"
|
38
|
+
rule += "-A FORWARD -i #{dst} -o #{src} -m state --state RELATED,ESTABLISHED -j ACCEPT\n"
|
39
|
+
rule
|
40
|
+
end
|
41
|
+
|
42
|
+
def masq_ipt( iface )
|
43
|
+
"-A POSTROUTING -o #{iface} -j MASQUERADE\n"
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
data/lib/shutter/version.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: shutter
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.7
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-
|
12
|
+
date: 2012-08-25 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rspec
|
@@ -61,6 +61,7 @@ files:
|
|
61
61
|
- LICENSE
|
62
62
|
- README.md
|
63
63
|
- Rakefile
|
64
|
+
- SERVER.md
|
64
65
|
- bin/shutter
|
65
66
|
- lib/shutter.rb
|
66
67
|
- lib/shutter/command_line.rb
|
@@ -68,6 +69,7 @@ files:
|
|
68
69
|
- lib/shutter/iptables.rb
|
69
70
|
- lib/shutter/iptables/base.rb
|
70
71
|
- lib/shutter/iptables/eyepee.rb
|
72
|
+
- lib/shutter/iptables/forward.rb
|
71
73
|
- lib/shutter/iptables/iface.rb
|
72
74
|
- lib/shutter/iptables/jail.rb
|
73
75
|
- lib/shutter/iptables/port.rb
|