CloudyScripts 1.6.1 → 1.7.27
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.
- data/Rakefile +1 -1
- data/lib/audit/checks/APACHE2.group +6 -0
- data/lib/audit/checks/APACHE2_CONFIG_01.check +36 -0
- data/lib/audit/checks/APACHE2_CONFIG_02.check +34 -0
- data/lib/audit/checks/APACHE2_CONFIG_03.check +60 -0
- data/lib/audit/checks/APACHE2_CONFIG_04.check +23 -0
- data/lib/audit/checks/APACHE2_CONFIG_05.check +23 -0
- data/lib/audit/checks/APACHE2_CONFIG_06.check +30 -0
- data/lib/audit/checks/APACHE2_INIT_1.check +14 -0
- data/lib/audit/checks/APACHE2_INIT_2.check +66 -0
- data/lib/audit/checks/APACHE2_INIT_3.check +13 -0
- data/lib/audit/checks/APACHE2_USER_7.check +17 -0
- data/lib/audit/checks/BACKUP_HOME_DOTFILES.check +26 -0
- data/lib/audit/checks/BACKUP_LOG.check +24 -0
- data/lib/audit/checks/BACKUP_MAIL.check +19 -0
- data/lib/audit/checks/BACKUP_WEB.check +12 -0
- data/lib/audit/checks/CONFIGURATION_BACKUP.check +14 -0
- data/lib/audit/checks/DIRECTORY_LISTING.check +14 -0
- data/lib/audit/checks/DISTRIBUTION_FACTS.check +60 -0
- data/lib/audit/checks/DMESG_OUTPUT.check +14 -0
- data/lib/audit/checks/FIND_GROUP_FILE.check +6 -0
- data/lib/audit/checks/FIND_PASSWD_FILE.check +8 -0
- data/lib/audit/checks/FIND_SHADOW_FILE.check +5 -0
- data/lib/audit/checks/FIND_SUDOERS_FILE.check +6 -0
- data/lib/audit/checks/FREE_SPACE.check +26 -0
- data/lib/audit/checks/HAS_AWK.check +30 -0
- data/lib/audit/checks/HAS_BASE.check +21 -0
- data/lib/audit/checks/HAS_CAT.check +18 -0
- data/lib/audit/checks/HAS_COMPRESSOR.check +30 -0
- data/lib/audit/checks/HAS_CUT.check +18 -0
- data/lib/audit/checks/HAS_DF.check +19 -0
- data/lib/audit/checks/HAS_DPKG.check +18 -0
- data/lib/audit/checks/HAS_FILE_DOWNLOADER.check +32 -0
- data/lib/audit/checks/HAS_FIND.check +18 -0
- data/lib/audit/checks/HAS_GREP.check +19 -0
- data/lib/audit/checks/HAS_GROUPCHECK.check +23 -0
- data/lib/audit/checks/HAS_GROUPS.check +19 -0
- data/lib/audit/checks/HAS_HOSTNAME.check +7 -0
- data/lib/audit/checks/HAS_ID.check +7 -0
- data/lib/audit/checks/HAS_LSB_RELEASE.check +16 -0
- data/lib/audit/checks/HAS_MOUNT.check +19 -0
- data/lib/audit/checks/HAS_NETSTAT.check +20 -0
- data/lib/audit/checks/HAS_PASSWD_CHECK.check +17 -0
- data/lib/audit/checks/HAS_PS.check +19 -0
- data/lib/audit/checks/HAS_ROUTE.check +19 -0
- data/lib/audit/checks/HAS_SH.check +19 -0
- data/lib/audit/checks/HAS_SORT.check +17 -0
- data/lib/audit/checks/HAS_STAT.check +17 -0
- data/lib/audit/checks/HAS_SUPERUSER.check +11 -0
- data/lib/audit/checks/HAS_TAIL.check +16 -0
- data/lib/audit/checks/HAS_TAR.check +7 -0
- data/lib/audit/checks/HAS_TR.check +22 -0
- data/lib/audit/checks/HAS_UNAME.check +7 -0
- data/lib/audit/checks/HAS_UNIQ.check +17 -0
- data/lib/audit/checks/HAS_WC.check +16 -0
- data/lib/audit/checks/HAS_WHO.check +18 -0
- data/lib/audit/checks/HAS_YUM.check +18 -0
- data/lib/audit/checks/LASTLOG.check +28 -0
- data/lib/audit/checks/LIST_ROUTES.check +33 -0
- data/lib/audit/checks/LIST_USER_ACCOUNTS.check +25 -0
- data/lib/audit/checks/LOADED_MODULES.check +22 -0
- data/lib/audit/checks/LOCAL_NMAP.check +97 -0
- data/lib/audit/checks/LOGGED_USERS.check +28 -0
- data/lib/audit/checks/LYNIS_AUTH.group +9 -0
- data/lib/audit/checks/LYNIS_AUTH_9204.check +43 -0
- data/lib/audit/checks/LYNIS_AUTH_9208.check +35 -0
- data/lib/audit/checks/LYNIS_AUTH_9216.check +24 -0
- data/lib/audit/checks/LYNIS_AUTH_9222.check +25 -0
- data/lib/audit/checks/LYNIS_AUTH_9226.check +24 -0
- data/lib/audit/checks/LYNIS_AUTH_9228.check +24 -0
- data/lib/audit/checks/LYNIS_AUTH_9252.check +19 -0
- data/lib/audit/checks/MAYBE_HAS_BZIP2.check +17 -0
- data/lib/audit/checks/MAYBE_HAS_CURL.check +17 -0
- data/lib/audit/checks/MAYBE_HAS_DU.check +17 -0
- data/lib/audit/checks/MAYBE_HAS_HOSTNAME.check +17 -0
- data/lib/audit/checks/MAYBE_HAS_ID.check +17 -0
- data/lib/audit/checks/MAYBE_HAS_LSB_RELEASE.check +15 -0
- data/lib/audit/checks/MAYBE_HAS_SUPERUSER.check +36 -0
- data/lib/audit/checks/MAYBE_HAS_TAR.check +19 -0
- data/lib/audit/checks/MAYBE_HAS_UNAME.check +17 -0
- data/lib/audit/checks/MAYBE_HAS_WGET.check +17 -0
- data/lib/audit/checks/MOUNTED_DEVICES.check +22 -0
- data/lib/audit/checks/MYSQL_HISTORY_1.check +29 -0
- data/lib/audit/checks/MYSQL_INIT_1.check +9 -0
- data/lib/audit/checks/MYSQL_INIT_2.check +12 -0
- data/lib/audit/checks/MYSQL_INIT_3.check +7 -0
- data/lib/audit/checks/PACKAGES_INSTALLED_DPKG.check +38 -0
- data/lib/audit/checks/PACKAGES_INSTALLED_YUM.check +36 -0
- data/lib/audit/checks/PASSWORD_INFORMATION.check +33 -0
- data/lib/audit/checks/PLATFORM_FACTS.check +35 -0
- data/lib/audit/checks/PORTS_OPEN_NETSTAT.check +121 -0
- data/lib/audit/checks/PROCESS_LIST.check +87 -0
- data/lib/audit/checks/SLOW.group +7 -0
- data/lib/audit/checks/SLOW_1.check +4 -0
- data/lib/audit/checks/SLOW_2.check +4 -0
- data/lib/audit/checks/SLOW_3.check +4 -0
- data/lib/audit/checks/SSH.group +14 -0
- data/lib/audit/checks/SSH_CONFIG_01.check +12 -0
- data/lib/audit/checks/SSH_CONFIG_02.check +15 -0
- data/lib/audit/checks/SSH_CONFIG_03.check +13 -0
- data/lib/audit/checks/SSH_CONFIG_04.check +11 -0
- data/lib/audit/checks/SSH_CONFIG_05.check +12 -0
- data/lib/audit/checks/SSH_CONFIG_06.check +12 -0
- data/lib/audit/checks/SSH_CONFIG_07.check +11 -0
- data/lib/audit/checks/SSH_CONFIG_08.check +12 -0
- data/lib/audit/checks/SSH_CONFIG_09.check +12 -0
- data/lib/audit/checks/SSH_CONFIG_10.check +15 -0
- data/lib/audit/checks/SSH_CONFIG_11.check +14 -0
- data/lib/audit/checks/SSH_INIT_1.check +9 -0
- data/lib/audit/checks/SSH_INIT_2.check +12 -0
- data/lib/audit/checks/SSH_KEYS_1.check +32 -0
- data/lib/audit/checks/USERS_INIT_1.check +9 -0
- data/lib/audit/checks/USERS_INIT_2.check +5 -0
- data/lib/audit/checks/USERS_INIT_3.check +5 -0
- data/lib/audit/checks/USERS_INIT_4.check +9 -0
- data/lib/audit/checks/USERS_INIT_5.check +10 -0
- data/lib/audit/checks/USER_INFORMATION.check +29 -0
- data/lib/audit/checks/VARIOUS.group +19 -0
- data/lib/audit/checks/VAR_LIST_HOME_DIRECTORIES.check +5 -0
- data/lib/audit/checks/benchmark.group +6 -0
- data/lib/audit/checks/footer.template +12 -0
- data/lib/audit/checks/header.template +10 -0
- data/lib/audit/checks/helpers/head.sh +59 -0
- data/lib/audit/checks/script_header.template +69 -0
- data/lib/audit/create_benchmark.sh +93 -0
- data/lib/audit/lib/audit.rb +136 -0
- data/lib/audit/lib/audit_facade.rb +5 -0
- data/lib/audit/lib/benchmark/audit_benchmark.rb +165 -0
- data/lib/audit/lib/benchmark/automatic_dependencies.rb +13 -0
- data/lib/audit/lib/benchmark/benchmark_factory.rb +23 -0
- data/lib/audit/lib/benchmark/benchmark_result.rb +25 -0
- data/lib/audit/lib/benchmark/check.rb +34 -0
- data/lib/audit/lib/benchmark/group.rb +30 -0
- data/lib/audit/lib/benchmark/item_exception.rb +13 -0
- data/lib/audit/lib/benchmark/result_code.rb +11 -0
- data/lib/audit/lib/benchmark/rule_result.rb +42 -0
- data/lib/audit/lib/benchmark/rule_role.rb +5 -0
- data/lib/audit/lib/benchmark/rule_severity.rb +13 -0
- data/lib/audit/lib/benchmark/yaml_benchmark.rb +133 -0
- data/lib/audit/lib/connection/ami_connection.rb +4 -0
- data/lib/audit/lib/connection/connection_factory.rb +27 -0
- data/lib/audit/lib/connection/ssh_connection.rb +243 -0
- data/lib/audit/lib/ec2_utils.rb +245 -0
- data/lib/audit/lib/http_fingerprint.rb +116 -0
- data/lib/audit/lib/lazy.rb +37 -0
- data/lib/audit/lib/linear_script_generator.rb +31 -0
- data/lib/audit/lib/main.rb +13 -0
- data/lib/audit/lib/my_option_parser.rb +106 -0
- data/lib/audit/lib/nessus_new.rb +290 -0
- data/lib/audit/lib/nessus_utils.rb +102 -0
- data/lib/audit/lib/parser/command/abstract_command.rb +32 -0
- data/lib/audit/lib/parser/command/abstract_command_result.rb +30 -0
- data/lib/audit/lib/parser/command/attach_file_command.rb +63 -0
- data/lib/audit/lib/parser/command/check_finished_command.rb +45 -0
- data/lib/audit/lib/parser/command/cpe_name_command.rb +37 -0
- data/lib/audit/lib/parser/command/data_command.rb +43 -0
- data/lib/audit/lib/parser/command/listening_port_command.rb +46 -0
- data/lib/audit/lib/parser/command/message_command.rb +21 -0
- data/lib/audit/lib/parser/command/program_name_command.rb +42 -0
- data/lib/audit/lib/parser/parse_exception.rb +2 -0
- data/lib/audit/lib/parser/result_type.rb +13 -0
- data/lib/audit/lib/parser/script_output_parser.rb +201 -0
- data/lib/audit/lib/parser/stdout_line_buffer.rb +43 -0
- data/lib/audit/lib/ssh_fingerprint.rb +220 -0
- data/lib/audit/lib/ssh_fingerprint2.rb +170 -0
- data/lib/audit/lib/ssh_utils.rb +292 -0
- data/lib/audit/lib/transformers/web_view_transformer.rb +171 -0
- data/lib/audit/lib/transformers/yaml_transformer.rb +50 -0
- data/lib/audit/lib/util/random_string.rb +22 -0
- data/lib/audit/lib/version.rb +7 -0
- data/lib/help/ec2_helper.rb +65 -2
- data/lib/help/remote_command_handler.rb +17 -0
- data/lib/help/state_transition_helper.rb +8 -0
- data/lib/scripts/ec2/open_port_checker.rb +112 -0
- data/lib/scripts/ec2/port_range_detector.rb +0 -1
- metadata +175 -16
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
# To change this template, choose Tools | Templates
|
|
2
|
+
# and open the template in the editor.
|
|
3
|
+
|
|
4
|
+
# icons taken from http://www.famfamfam.com/lab/icons/silk/
|
|
5
|
+
|
|
6
|
+
require 'benchmark/audit_benchmark'
|
|
7
|
+
require 'parser/result_type'
|
|
8
|
+
require 'logger'
|
|
9
|
+
|
|
10
|
+
class WebViewTransformer
|
|
11
|
+
IMAGE_PREFIX = "/images"
|
|
12
|
+
BENCHMARK_ID = "BENCHMARK"
|
|
13
|
+
|
|
14
|
+
@@LOG = Logger.new(STDOUT)
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
def self.get(audit, id)
|
|
18
|
+
if (id == :root) then
|
|
19
|
+
item = audit.benchmark
|
|
20
|
+
return {
|
|
21
|
+
'data' => {
|
|
22
|
+
'title' => item.name || item.id,
|
|
23
|
+
'attr' => {},
|
|
24
|
+
'icon' => 'folder'},
|
|
25
|
+
'attr' => {
|
|
26
|
+
'id' => BENCHMARK_ID},
|
|
27
|
+
'state' => 'closed'}
|
|
28
|
+
else
|
|
29
|
+
return self.get_children(audit, id)
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def self.get_children(audit, id)
|
|
34
|
+
if id == BENCHMARK_ID then
|
|
35
|
+
item = audit.benchmark
|
|
36
|
+
else
|
|
37
|
+
item = audit.results[id] || audit.benchmark.item_repository[id]
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
if item.kind_of? AuditBenchmark then
|
|
41
|
+
return item.children.map {|x| self.get_item(audit, x.id)}
|
|
42
|
+
elsif item.kind_of? Group then
|
|
43
|
+
return item.children.map {|x| self.get_item(audit, x.id)}
|
|
44
|
+
elsif item.kind_of? RuleResult then
|
|
45
|
+
if item.rule.description then
|
|
46
|
+
results = [{
|
|
47
|
+
'data' => {
|
|
48
|
+
'title' => item.rule.description,
|
|
49
|
+
'icon' => "#{IMAGE_PREFIX}/tag_blue.png"},
|
|
50
|
+
'state' => 'opened',
|
|
51
|
+
'children' => []
|
|
52
|
+
}]
|
|
53
|
+
else
|
|
54
|
+
results = []
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
results = results + item.check.reject do|x|
|
|
58
|
+
x.methods.include?(:visible?) && (!x.visible?())
|
|
59
|
+
end.map do |x|
|
|
60
|
+
case x.type
|
|
61
|
+
when ResultType::MESSAGE then
|
|
62
|
+
{
|
|
63
|
+
'data' => {
|
|
64
|
+
'title' => x.to_string(),
|
|
65
|
+
'icon' => "#{IMAGE_PREFIX}/script.png"},
|
|
66
|
+
'state' => 'opened',
|
|
67
|
+
'children' => []
|
|
68
|
+
}
|
|
69
|
+
when ResultType::DATA then
|
|
70
|
+
{
|
|
71
|
+
'data' => {
|
|
72
|
+
'title' => x.to_string(),
|
|
73
|
+
'icon' => "#{IMAGE_PREFIX}/brick.png"},
|
|
74
|
+
'state' => 'opened',
|
|
75
|
+
'children' => []
|
|
76
|
+
}
|
|
77
|
+
when ResultType::PROGRAM_NAME then
|
|
78
|
+
{
|
|
79
|
+
'data' => {
|
|
80
|
+
'title' => x.to_string(),
|
|
81
|
+
'icon' => "#{IMAGE_PREFIX}/cog.png"},
|
|
82
|
+
'state' => 'opened',
|
|
83
|
+
'children' => []
|
|
84
|
+
}
|
|
85
|
+
else
|
|
86
|
+
{
|
|
87
|
+
'data' => {
|
|
88
|
+
'title' => x.to_string(),
|
|
89
|
+
'icon' => "file"},
|
|
90
|
+
'state' => 'opened',
|
|
91
|
+
'children' => []
|
|
92
|
+
}
|
|
93
|
+
end
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
return results
|
|
97
|
+
elsif item.kind_of? Check then
|
|
98
|
+
#check was not executed, thus no result
|
|
99
|
+
if item.description then
|
|
100
|
+
return [{
|
|
101
|
+
'data' => {
|
|
102
|
+
'title' => item.description,
|
|
103
|
+
'icon' => "#{IMAGE_PREFIX}/tag_blue.png"},
|
|
104
|
+
'state' => 'opened',
|
|
105
|
+
'children' => []
|
|
106
|
+
}]
|
|
107
|
+
else
|
|
108
|
+
return []
|
|
109
|
+
end
|
|
110
|
+
else
|
|
111
|
+
raise "Unknown item type #{item.class.name}"
|
|
112
|
+
end
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
def self.get_item(audit, id)
|
|
116
|
+
item = audit.results[id] || audit.benchmark.item_repository[id]
|
|
117
|
+
|
|
118
|
+
if item.kind_of? AuditBenchmark then
|
|
119
|
+
return {
|
|
120
|
+
'data' => {
|
|
121
|
+
'title' => item.name || item.id,
|
|
122
|
+
'icon' => 'folder'},
|
|
123
|
+
'attr' => {'id' => 'BENCHMARK'},
|
|
124
|
+
'state' => 'closed'}
|
|
125
|
+
elsif item.kind_of? Group then
|
|
126
|
+
return {
|
|
127
|
+
'data' => {
|
|
128
|
+
'title' => item.name || item.id,
|
|
129
|
+
'icon' => 'folder'},
|
|
130
|
+
'attr' => {'id' => item.id},
|
|
131
|
+
'state' => 'closed'}
|
|
132
|
+
elsif item.kind_of? RuleResult then
|
|
133
|
+
return {
|
|
134
|
+
'data' => {
|
|
135
|
+
'title' => item.rule.name || item.rule.id,
|
|
136
|
+
'icon' => case item.result
|
|
137
|
+
when ResultCode::PASS then "#{IMAGE_PREFIX}/tick.png"
|
|
138
|
+
when ResultCode::FAIL then
|
|
139
|
+
if (item.severity == RuleSeverity::LOW || item.severity == RuleSeverity::INFO) then
|
|
140
|
+
"#{IMAGE_PREFIX}/warning.png"
|
|
141
|
+
else
|
|
142
|
+
"#{IMAGE_PREFIX}/fail.png"
|
|
143
|
+
end
|
|
144
|
+
else "#{IMAGE_PREFIX}/question.png"
|
|
145
|
+
end},
|
|
146
|
+
'attr' => { 'id' => item.rule.id},
|
|
147
|
+
'state' => 'closed'}
|
|
148
|
+
elsif item.kind_of? Check then
|
|
149
|
+
if item.description then
|
|
150
|
+
return {
|
|
151
|
+
'data' => {
|
|
152
|
+
'title' => item.name || item.id,
|
|
153
|
+
'icon' => "#{IMAGE_PREFIX}/hourglass.png"},
|
|
154
|
+
'attr' => {'id' => item.id},
|
|
155
|
+
'state' => 'closed'}
|
|
156
|
+
else
|
|
157
|
+
return {
|
|
158
|
+
'data' => {
|
|
159
|
+
'title' => item.name || item.id,
|
|
160
|
+
'icon' => "#{IMAGE_PREFIX}/hourglass.png"},
|
|
161
|
+
'attr' => {'id' => item.id},
|
|
162
|
+
'state' => 'opened',
|
|
163
|
+
'children' => []}
|
|
164
|
+
end
|
|
165
|
+
else
|
|
166
|
+
raise "Unknown item type #{item.class.name} for id #{id}"
|
|
167
|
+
end
|
|
168
|
+
end
|
|
169
|
+
|
|
170
|
+
|
|
171
|
+
end
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
# To change this template, choose Tools | Templates
|
|
2
|
+
# and open the template in the editor.
|
|
3
|
+
|
|
4
|
+
class YamlTransformer
|
|
5
|
+
def initialize
|
|
6
|
+
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def self.transform(report)
|
|
10
|
+
self.transform_node(report, report.get_root)
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def self.transform_node(report, node)
|
|
14
|
+
if node.kind_of? AuditBenchmark then
|
|
15
|
+
return self.transform_benchmark(report, node)
|
|
16
|
+
elsif node.kind_of? Group then
|
|
17
|
+
return self.transform_group(report, node)
|
|
18
|
+
elsif node.kind_of? RuleResult then
|
|
19
|
+
return self.transform_rule_result(report, node)
|
|
20
|
+
else
|
|
21
|
+
raise "Unknown report node type #{node.class.name}"
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def self.transform_benchmark(report, node)
|
|
26
|
+
return {:id => node.id,
|
|
27
|
+
:name => node.name,
|
|
28
|
+
:description => node.description,
|
|
29
|
+
:children => node.children.map {|x| self.transform_node(report, report.get(x.id))}}
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def self.transform_group(report, node)
|
|
33
|
+
return {:id => node.id,
|
|
34
|
+
:name => node.name,
|
|
35
|
+
:description => node.description,
|
|
36
|
+
:children => node.children.map {|x| self.transform_node(report, report.get(x.id))}}
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def self.transform_rule_result(report, node)
|
|
40
|
+
return {:rule_refid => node.rule.id,
|
|
41
|
+
:name => node.rule.name,
|
|
42
|
+
:description => node.rule.description,
|
|
43
|
+
:check => node.check.map {|x| self.transform_check(x)}
|
|
44
|
+
}
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def self.transform_check(check)
|
|
48
|
+
return check.to_hash()
|
|
49
|
+
end
|
|
50
|
+
end
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# To change this template, choose Tools | Templates
|
|
2
|
+
# and open the template in the editor.
|
|
3
|
+
|
|
4
|
+
# Ruby 1.8 does not contains sample() function
|
|
5
|
+
class Array
|
|
6
|
+
def sample()
|
|
7
|
+
return self.choice()
|
|
8
|
+
end
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
class RandomString
|
|
12
|
+
def initialize
|
|
13
|
+
|
|
14
|
+
end
|
|
15
|
+
def self.generate(length = 20, alphabet = ('A' .. 'Z').to_a + ('a' .. 'z').to_a + ('0' .. '9').to_a)
|
|
16
|
+
return (0 .. length).map { alphabet.sample }.join
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def self.generate_name(length = 20)
|
|
20
|
+
return (('A' .. 'Z').to_a + ('a' .. 'z').to_a).sample + generate(length - 1)
|
|
21
|
+
end
|
|
22
|
+
end
|
data/lib/help/ec2_helper.rb
CHANGED
|
@@ -106,8 +106,10 @@ class Ec2Helper
|
|
|
106
106
|
end
|
|
107
107
|
end
|
|
108
108
|
|
|
109
|
-
def instance_prop(instance_id, prop)
|
|
110
|
-
instances
|
|
109
|
+
def instance_prop(instance_id, prop, instances = nil)
|
|
110
|
+
if instances == nil
|
|
111
|
+
instances = @ec2_api.describe_instances(:instance_id => instance_id)
|
|
112
|
+
end
|
|
111
113
|
begin
|
|
112
114
|
if instances['reservationSet']['item'][0]['instancesSet']['item'].size == 0
|
|
113
115
|
raise Exception.new("instance #{instance_id} not found")
|
|
@@ -157,4 +159,65 @@ class Ec2Helper
|
|
|
157
159
|
false
|
|
158
160
|
end
|
|
159
161
|
|
|
162
|
+
# From the information retrieved via EC2::describe_security_groups, look up
|
|
163
|
+
# all open ports for the group specified
|
|
164
|
+
def get_security_group_info(group_name, group_infos)
|
|
165
|
+
group_infos['securityGroupInfo']['item'].each() do |group_info|
|
|
166
|
+
return group_info if group_info['groupName'] == group_name
|
|
167
|
+
end
|
|
168
|
+
nil
|
|
169
|
+
end
|
|
170
|
+
|
|
171
|
+
# From the information retrieved via EC2::describe_instances for a specific
|
|
172
|
+
# instance, retrieve the names of the security groups belonging to that instance.
|
|
173
|
+
def lookup_security_group_names(instance_info)
|
|
174
|
+
group_names = []
|
|
175
|
+
puts "lookup_security_group_names(#{instance_info.inspect})"
|
|
176
|
+
instance_info['groupSet']['item'].each() {|group_info|
|
|
177
|
+
group_name = group_info['groupName'] || group_info['groupId']
|
|
178
|
+
group_names << group_name
|
|
179
|
+
}
|
|
180
|
+
group_names
|
|
181
|
+
end
|
|
182
|
+
|
|
183
|
+
# From the information retrieved via EC2::describe_security_groups, look up
|
|
184
|
+
# all open ports for the group specified
|
|
185
|
+
def lookup_open_ports(group_name, group_infos)
|
|
186
|
+
puts "group_infos = #{group_infos.inspect}"
|
|
187
|
+
group_info = get_security_group_info(group_name, group_infos)
|
|
188
|
+
puts "group_info for #{group_name} = #{group_info.inspect}"
|
|
189
|
+
open_ports = []
|
|
190
|
+
group_info['ipPermissions']['item'].each() {|permission|
|
|
191
|
+
if permission['ipRanges'] == nil
|
|
192
|
+
#no IP-Ranges defined (group based mode): ignore
|
|
193
|
+
next
|
|
194
|
+
end
|
|
195
|
+
prot = permission['ipProtocol']
|
|
196
|
+
from_port = permission['fromPort'].to_i
|
|
197
|
+
to_port = permission['toPort'].to_i
|
|
198
|
+
next if from_port != to_port #ignore port ranges
|
|
199
|
+
permission['ipRanges']['item'].each() {|ipRange|
|
|
200
|
+
if ipRange['cidrIp'] == "0.0.0.0/0"
|
|
201
|
+
#found one
|
|
202
|
+
open_ports << {:protocol => prot, :port => from_port}
|
|
203
|
+
end
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
open_ports
|
|
207
|
+
end
|
|
208
|
+
|
|
209
|
+
# Looks up the instanceId for the output retrieved by EC2::describe_instances(:instance_id => xxx)
|
|
210
|
+
# without the reservation set.
|
|
211
|
+
def get_instance_id(instance_info)
|
|
212
|
+
puts "look up instanceId in #{instance_info.inspect}"
|
|
213
|
+
instance_info['instancesSet']['item'][0]['instanceId']
|
|
214
|
+
end
|
|
215
|
+
|
|
216
|
+
# Looks up the instanceId for the output retrieved by EC2::describe_instances(:instance_id => xxx)
|
|
217
|
+
# without the reservation set.
|
|
218
|
+
def get_instance_prop(instance_info, prop)
|
|
219
|
+
puts "look up #{prop} in #{instance_info.inspect}"
|
|
220
|
+
instance_info['instancesSet']['item'][0][prop.to_s]
|
|
221
|
+
end
|
|
222
|
+
|
|
160
223
|
end
|
|
@@ -11,6 +11,23 @@ class RemoteCommandHandler
|
|
|
11
11
|
@use_sudo = false
|
|
12
12
|
end
|
|
13
13
|
|
|
14
|
+
# Checks for a given IP/port if there's a response on that port.
|
|
15
|
+
def is_port_open?(ip, port)
|
|
16
|
+
begin
|
|
17
|
+
Timeout::timeout(5) do
|
|
18
|
+
begin
|
|
19
|
+
s = TCPSocket.new(ip, port)
|
|
20
|
+
s.close
|
|
21
|
+
return true
|
|
22
|
+
rescue Errno::ECONNREFUSED, Errno::EHOSTUNREACH
|
|
23
|
+
return false
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
rescue Timeout::Error
|
|
27
|
+
return false
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
|
|
14
31
|
# Connect to the machine as root using a keyfile.
|
|
15
32
|
# Params:
|
|
16
33
|
# * ip: ip address of the machine to connect to
|
|
@@ -179,6 +179,14 @@ module StateTransitionHelper
|
|
|
179
179
|
@logger.info("found #{sgs.size} security groups")
|
|
180
180
|
@context[:security_groups] = sgs
|
|
181
181
|
end
|
|
182
|
+
|
|
183
|
+
def retrieve_instances()
|
|
184
|
+
@context[:script].post_message("going to retrieve all instances...")
|
|
185
|
+
inst = @context[:ec2_api_handler].describe_instances()
|
|
186
|
+
@context[:script].post_message("found #{inst.size} instances")
|
|
187
|
+
@logger.info("found #{inst.size} instances")
|
|
188
|
+
@context[:ec2_instances] = inst
|
|
189
|
+
end
|
|
182
190
|
|
|
183
191
|
# Creates a new EBS volume.
|
|
184
192
|
# Input Parameters:
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
require "help/script_execution_state"
|
|
2
|
+
require "scripts/ec2/ec2_script"
|
|
3
|
+
require "help/remote_command_handler"
|
|
4
|
+
#require "help/dm_crypt_helper"
|
|
5
|
+
require "help/ec2_helper"
|
|
6
|
+
require "AWS"
|
|
7
|
+
|
|
8
|
+
# Identifies all server instances with their ports open and checks if
|
|
9
|
+
# there are instances where no service runs on that port. Port ranges are
|
|
10
|
+
# ignored.
|
|
11
|
+
#
|
|
12
|
+
|
|
13
|
+
class OpenPortChecker < Ec2Script
|
|
14
|
+
# Input parameters
|
|
15
|
+
# * ec2_api_handler => object that allows to access the EC2 API
|
|
16
|
+
def initialize(input_params)
|
|
17
|
+
super(input_params)
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def check_input_parameters()
|
|
21
|
+
if @input_params[:ec2_api_handler] == nil
|
|
22
|
+
raise Exception.new("no EC2 handler specified")
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def load_initial_state()
|
|
27
|
+
OpenPortCheckerState.load_state(@input_params)
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
private
|
|
31
|
+
|
|
32
|
+
# Here begins the state machine implementation
|
|
33
|
+
class OpenPortCheckerState < ScriptExecutionState
|
|
34
|
+
def self.load_state(context)
|
|
35
|
+
state = context[:initial_state] == nil ? InitialState.new(context) : context[:initial_state]
|
|
36
|
+
state
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
# Nothing done yet. Retrieve all security groups
|
|
42
|
+
class InitialState < OpenPortCheckerState
|
|
43
|
+
def enter
|
|
44
|
+
retrieve_instances()
|
|
45
|
+
InstancesRetrievedState.new(@context)
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
# Got all instances. If there are some, check security groups
|
|
50
|
+
class InstancesRetrievedState < OpenPortCheckerState
|
|
51
|
+
def enter
|
|
52
|
+
if @context[:ec2_instances].size == 0
|
|
53
|
+
Done.new(@context)
|
|
54
|
+
else
|
|
55
|
+
retrieve_security_groups()
|
|
56
|
+
SecurityGroupsRetrievedState.new(@context)
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
# Got all instances. If there are some, check security groups
|
|
62
|
+
class SecurityGroupsRetrievedState < OpenPortCheckerState
|
|
63
|
+
def enter
|
|
64
|
+
@context[:result][:port_checks] = []
|
|
65
|
+
ec2_helper = Ec2Helper.new(@context[:ec2_api_handler])
|
|
66
|
+
@context[:ec2_instances]['reservationSet']['item'].each() do |instance_info|
|
|
67
|
+
instance_id = ec2_helper.get_instance_id(instance_info)
|
|
68
|
+
@logger.debug("instance_info = #{instance_info.inspect}")
|
|
69
|
+
instance_ip = ec2_helper.get_instance_prop(instance_info, 'dnsName')
|
|
70
|
+
instance_state = ec2_helper.get_instance_prop(instance_info, 'instanceState')['name']
|
|
71
|
+
if instance_state != "running"
|
|
72
|
+
post_message("ignore instance #{instance_id} since not running")
|
|
73
|
+
next
|
|
74
|
+
end
|
|
75
|
+
sec_groups = ec2_helper.lookup_security_group_names(instance_info)
|
|
76
|
+
@logger.debug("group lookup for #{instance_id} => #{sec_groups.inspect}")
|
|
77
|
+
sec_groups.each() do |group_name|
|
|
78
|
+
port_infos = ec2_helper.lookup_open_ports(group_name, @context[:security_groups])
|
|
79
|
+
@logger.debug("port_infos for group #{group_name} #{port_infos.inspect}")
|
|
80
|
+
port_infos.each() do |port_info|
|
|
81
|
+
result = false
|
|
82
|
+
begin
|
|
83
|
+
result = @context[:remote_command_handler].is_port_open?(instance_ip, port_info[:port])
|
|
84
|
+
post_message("check port #{port_info[:port]} for instance #{instance_id} (on #{instance_ip}) #{result ? "successful" : "failed"}")
|
|
85
|
+
rescue Exception => e
|
|
86
|
+
@logger.warn("exception during executing port check: #{e}")
|
|
87
|
+
end
|
|
88
|
+
@context[:result][:port_checks] << {:instance => instance_id, :protocol => port_info[:protocol],
|
|
89
|
+
:port => port_info[:port], :success => result, :group_name => group_name
|
|
90
|
+
}
|
|
91
|
+
end
|
|
92
|
+
end
|
|
93
|
+
end
|
|
94
|
+
AnalysisDone.new(@context)
|
|
95
|
+
end
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
# Nothing done yet. Retrieve all security groups
|
|
99
|
+
class AnalysisDone < OpenPortCheckerState
|
|
100
|
+
def enter
|
|
101
|
+
Done.new(@context)
|
|
102
|
+
end
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
# Script done.
|
|
106
|
+
class Done < OpenPortCheckerState
|
|
107
|
+
def done?
|
|
108
|
+
true
|
|
109
|
+
end
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
end
|