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.
Files changed (176) hide show
  1. data/Rakefile +1 -1
  2. data/lib/audit/checks/APACHE2.group +6 -0
  3. data/lib/audit/checks/APACHE2_CONFIG_01.check +36 -0
  4. data/lib/audit/checks/APACHE2_CONFIG_02.check +34 -0
  5. data/lib/audit/checks/APACHE2_CONFIG_03.check +60 -0
  6. data/lib/audit/checks/APACHE2_CONFIG_04.check +23 -0
  7. data/lib/audit/checks/APACHE2_CONFIG_05.check +23 -0
  8. data/lib/audit/checks/APACHE2_CONFIG_06.check +30 -0
  9. data/lib/audit/checks/APACHE2_INIT_1.check +14 -0
  10. data/lib/audit/checks/APACHE2_INIT_2.check +66 -0
  11. data/lib/audit/checks/APACHE2_INIT_3.check +13 -0
  12. data/lib/audit/checks/APACHE2_USER_7.check +17 -0
  13. data/lib/audit/checks/BACKUP_HOME_DOTFILES.check +26 -0
  14. data/lib/audit/checks/BACKUP_LOG.check +24 -0
  15. data/lib/audit/checks/BACKUP_MAIL.check +19 -0
  16. data/lib/audit/checks/BACKUP_WEB.check +12 -0
  17. data/lib/audit/checks/CONFIGURATION_BACKUP.check +14 -0
  18. data/lib/audit/checks/DIRECTORY_LISTING.check +14 -0
  19. data/lib/audit/checks/DISTRIBUTION_FACTS.check +60 -0
  20. data/lib/audit/checks/DMESG_OUTPUT.check +14 -0
  21. data/lib/audit/checks/FIND_GROUP_FILE.check +6 -0
  22. data/lib/audit/checks/FIND_PASSWD_FILE.check +8 -0
  23. data/lib/audit/checks/FIND_SHADOW_FILE.check +5 -0
  24. data/lib/audit/checks/FIND_SUDOERS_FILE.check +6 -0
  25. data/lib/audit/checks/FREE_SPACE.check +26 -0
  26. data/lib/audit/checks/HAS_AWK.check +30 -0
  27. data/lib/audit/checks/HAS_BASE.check +21 -0
  28. data/lib/audit/checks/HAS_CAT.check +18 -0
  29. data/lib/audit/checks/HAS_COMPRESSOR.check +30 -0
  30. data/lib/audit/checks/HAS_CUT.check +18 -0
  31. data/lib/audit/checks/HAS_DF.check +19 -0
  32. data/lib/audit/checks/HAS_DPKG.check +18 -0
  33. data/lib/audit/checks/HAS_FILE_DOWNLOADER.check +32 -0
  34. data/lib/audit/checks/HAS_FIND.check +18 -0
  35. data/lib/audit/checks/HAS_GREP.check +19 -0
  36. data/lib/audit/checks/HAS_GROUPCHECK.check +23 -0
  37. data/lib/audit/checks/HAS_GROUPS.check +19 -0
  38. data/lib/audit/checks/HAS_HOSTNAME.check +7 -0
  39. data/lib/audit/checks/HAS_ID.check +7 -0
  40. data/lib/audit/checks/HAS_LSB_RELEASE.check +16 -0
  41. data/lib/audit/checks/HAS_MOUNT.check +19 -0
  42. data/lib/audit/checks/HAS_NETSTAT.check +20 -0
  43. data/lib/audit/checks/HAS_PASSWD_CHECK.check +17 -0
  44. data/lib/audit/checks/HAS_PS.check +19 -0
  45. data/lib/audit/checks/HAS_ROUTE.check +19 -0
  46. data/lib/audit/checks/HAS_SH.check +19 -0
  47. data/lib/audit/checks/HAS_SORT.check +17 -0
  48. data/lib/audit/checks/HAS_STAT.check +17 -0
  49. data/lib/audit/checks/HAS_SUPERUSER.check +11 -0
  50. data/lib/audit/checks/HAS_TAIL.check +16 -0
  51. data/lib/audit/checks/HAS_TAR.check +7 -0
  52. data/lib/audit/checks/HAS_TR.check +22 -0
  53. data/lib/audit/checks/HAS_UNAME.check +7 -0
  54. data/lib/audit/checks/HAS_UNIQ.check +17 -0
  55. data/lib/audit/checks/HAS_WC.check +16 -0
  56. data/lib/audit/checks/HAS_WHO.check +18 -0
  57. data/lib/audit/checks/HAS_YUM.check +18 -0
  58. data/lib/audit/checks/LASTLOG.check +28 -0
  59. data/lib/audit/checks/LIST_ROUTES.check +33 -0
  60. data/lib/audit/checks/LIST_USER_ACCOUNTS.check +25 -0
  61. data/lib/audit/checks/LOADED_MODULES.check +22 -0
  62. data/lib/audit/checks/LOCAL_NMAP.check +97 -0
  63. data/lib/audit/checks/LOGGED_USERS.check +28 -0
  64. data/lib/audit/checks/LYNIS_AUTH.group +9 -0
  65. data/lib/audit/checks/LYNIS_AUTH_9204.check +43 -0
  66. data/lib/audit/checks/LYNIS_AUTH_9208.check +35 -0
  67. data/lib/audit/checks/LYNIS_AUTH_9216.check +24 -0
  68. data/lib/audit/checks/LYNIS_AUTH_9222.check +25 -0
  69. data/lib/audit/checks/LYNIS_AUTH_9226.check +24 -0
  70. data/lib/audit/checks/LYNIS_AUTH_9228.check +24 -0
  71. data/lib/audit/checks/LYNIS_AUTH_9252.check +19 -0
  72. data/lib/audit/checks/MAYBE_HAS_BZIP2.check +17 -0
  73. data/lib/audit/checks/MAYBE_HAS_CURL.check +17 -0
  74. data/lib/audit/checks/MAYBE_HAS_DU.check +17 -0
  75. data/lib/audit/checks/MAYBE_HAS_HOSTNAME.check +17 -0
  76. data/lib/audit/checks/MAYBE_HAS_ID.check +17 -0
  77. data/lib/audit/checks/MAYBE_HAS_LSB_RELEASE.check +15 -0
  78. data/lib/audit/checks/MAYBE_HAS_SUPERUSER.check +36 -0
  79. data/lib/audit/checks/MAYBE_HAS_TAR.check +19 -0
  80. data/lib/audit/checks/MAYBE_HAS_UNAME.check +17 -0
  81. data/lib/audit/checks/MAYBE_HAS_WGET.check +17 -0
  82. data/lib/audit/checks/MOUNTED_DEVICES.check +22 -0
  83. data/lib/audit/checks/MYSQL_HISTORY_1.check +29 -0
  84. data/lib/audit/checks/MYSQL_INIT_1.check +9 -0
  85. data/lib/audit/checks/MYSQL_INIT_2.check +12 -0
  86. data/lib/audit/checks/MYSQL_INIT_3.check +7 -0
  87. data/lib/audit/checks/PACKAGES_INSTALLED_DPKG.check +38 -0
  88. data/lib/audit/checks/PACKAGES_INSTALLED_YUM.check +36 -0
  89. data/lib/audit/checks/PASSWORD_INFORMATION.check +33 -0
  90. data/lib/audit/checks/PLATFORM_FACTS.check +35 -0
  91. data/lib/audit/checks/PORTS_OPEN_NETSTAT.check +121 -0
  92. data/lib/audit/checks/PROCESS_LIST.check +87 -0
  93. data/lib/audit/checks/SLOW.group +7 -0
  94. data/lib/audit/checks/SLOW_1.check +4 -0
  95. data/lib/audit/checks/SLOW_2.check +4 -0
  96. data/lib/audit/checks/SLOW_3.check +4 -0
  97. data/lib/audit/checks/SSH.group +14 -0
  98. data/lib/audit/checks/SSH_CONFIG_01.check +12 -0
  99. data/lib/audit/checks/SSH_CONFIG_02.check +15 -0
  100. data/lib/audit/checks/SSH_CONFIG_03.check +13 -0
  101. data/lib/audit/checks/SSH_CONFIG_04.check +11 -0
  102. data/lib/audit/checks/SSH_CONFIG_05.check +12 -0
  103. data/lib/audit/checks/SSH_CONFIG_06.check +12 -0
  104. data/lib/audit/checks/SSH_CONFIG_07.check +11 -0
  105. data/lib/audit/checks/SSH_CONFIG_08.check +12 -0
  106. data/lib/audit/checks/SSH_CONFIG_09.check +12 -0
  107. data/lib/audit/checks/SSH_CONFIG_10.check +15 -0
  108. data/lib/audit/checks/SSH_CONFIG_11.check +14 -0
  109. data/lib/audit/checks/SSH_INIT_1.check +9 -0
  110. data/lib/audit/checks/SSH_INIT_2.check +12 -0
  111. data/lib/audit/checks/SSH_KEYS_1.check +32 -0
  112. data/lib/audit/checks/USERS_INIT_1.check +9 -0
  113. data/lib/audit/checks/USERS_INIT_2.check +5 -0
  114. data/lib/audit/checks/USERS_INIT_3.check +5 -0
  115. data/lib/audit/checks/USERS_INIT_4.check +9 -0
  116. data/lib/audit/checks/USERS_INIT_5.check +10 -0
  117. data/lib/audit/checks/USER_INFORMATION.check +29 -0
  118. data/lib/audit/checks/VARIOUS.group +19 -0
  119. data/lib/audit/checks/VAR_LIST_HOME_DIRECTORIES.check +5 -0
  120. data/lib/audit/checks/benchmark.group +6 -0
  121. data/lib/audit/checks/footer.template +12 -0
  122. data/lib/audit/checks/header.template +10 -0
  123. data/lib/audit/checks/helpers/head.sh +59 -0
  124. data/lib/audit/checks/script_header.template +69 -0
  125. data/lib/audit/create_benchmark.sh +93 -0
  126. data/lib/audit/lib/audit.rb +136 -0
  127. data/lib/audit/lib/audit_facade.rb +5 -0
  128. data/lib/audit/lib/benchmark/audit_benchmark.rb +165 -0
  129. data/lib/audit/lib/benchmark/automatic_dependencies.rb +13 -0
  130. data/lib/audit/lib/benchmark/benchmark_factory.rb +23 -0
  131. data/lib/audit/lib/benchmark/benchmark_result.rb +25 -0
  132. data/lib/audit/lib/benchmark/check.rb +34 -0
  133. data/lib/audit/lib/benchmark/group.rb +30 -0
  134. data/lib/audit/lib/benchmark/item_exception.rb +13 -0
  135. data/lib/audit/lib/benchmark/result_code.rb +11 -0
  136. data/lib/audit/lib/benchmark/rule_result.rb +42 -0
  137. data/lib/audit/lib/benchmark/rule_role.rb +5 -0
  138. data/lib/audit/lib/benchmark/rule_severity.rb +13 -0
  139. data/lib/audit/lib/benchmark/yaml_benchmark.rb +133 -0
  140. data/lib/audit/lib/connection/ami_connection.rb +4 -0
  141. data/lib/audit/lib/connection/connection_factory.rb +27 -0
  142. data/lib/audit/lib/connection/ssh_connection.rb +243 -0
  143. data/lib/audit/lib/ec2_utils.rb +245 -0
  144. data/lib/audit/lib/http_fingerprint.rb +116 -0
  145. data/lib/audit/lib/lazy.rb +37 -0
  146. data/lib/audit/lib/linear_script_generator.rb +31 -0
  147. data/lib/audit/lib/main.rb +13 -0
  148. data/lib/audit/lib/my_option_parser.rb +106 -0
  149. data/lib/audit/lib/nessus_new.rb +290 -0
  150. data/lib/audit/lib/nessus_utils.rb +102 -0
  151. data/lib/audit/lib/parser/command/abstract_command.rb +32 -0
  152. data/lib/audit/lib/parser/command/abstract_command_result.rb +30 -0
  153. data/lib/audit/lib/parser/command/attach_file_command.rb +63 -0
  154. data/lib/audit/lib/parser/command/check_finished_command.rb +45 -0
  155. data/lib/audit/lib/parser/command/cpe_name_command.rb +37 -0
  156. data/lib/audit/lib/parser/command/data_command.rb +43 -0
  157. data/lib/audit/lib/parser/command/listening_port_command.rb +46 -0
  158. data/lib/audit/lib/parser/command/message_command.rb +21 -0
  159. data/lib/audit/lib/parser/command/program_name_command.rb +42 -0
  160. data/lib/audit/lib/parser/parse_exception.rb +2 -0
  161. data/lib/audit/lib/parser/result_type.rb +13 -0
  162. data/lib/audit/lib/parser/script_output_parser.rb +201 -0
  163. data/lib/audit/lib/parser/stdout_line_buffer.rb +43 -0
  164. data/lib/audit/lib/ssh_fingerprint.rb +220 -0
  165. data/lib/audit/lib/ssh_fingerprint2.rb +170 -0
  166. data/lib/audit/lib/ssh_utils.rb +292 -0
  167. data/lib/audit/lib/transformers/web_view_transformer.rb +171 -0
  168. data/lib/audit/lib/transformers/yaml_transformer.rb +50 -0
  169. data/lib/audit/lib/util/random_string.rb +22 -0
  170. data/lib/audit/lib/version.rb +7 -0
  171. data/lib/help/ec2_helper.rb +65 -2
  172. data/lib/help/remote_command_handler.rb +17 -0
  173. data/lib/help/state_transition_helper.rb +8 -0
  174. data/lib/scripts/ec2/open_port_checker.rb +112 -0
  175. data/lib/scripts/ec2/port_range_detector.rb +0 -1
  176. 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
@@ -0,0 +1,7 @@
1
+ require 'uri'
2
+
3
+ class Version
4
+ attr_accessor :description
5
+ attr_accessor :timestamp
6
+ attr_accessor :updateUri
7
+ end
@@ -106,8 +106,10 @@ class Ec2Helper
106
106
  end
107
107
  end
108
108
 
109
- def instance_prop(instance_id, prop)
110
- instances = @ec2_api.describe_instances(:instance_id => instance_id)
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