CloudyScripts 2.11.47 → 2.11.48

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 CHANGED
@@ -12,7 +12,7 @@ require 'rake/testtask'
12
12
 
13
13
  spec = Gem::Specification.new do |s|
14
14
  s.name = 'CloudyScripts'
15
- s.version = '2.11.47'
15
+ s.version = '2.11.48'
16
16
  s.has_rdoc = true
17
17
  s.extra_rdoc_files = ['README.rdoc', 'LICENSE']
18
18
  s.summary = 'Scripts to facilitate programming for infrastructure clouds.'
@@ -12,6 +12,34 @@ class AWS::EC2::Base
12
12
  end
13
13
  end
14
14
 
15
+ #XXX: use last AWS EC2 API, add VPC function
16
+ module AWS
17
+ module EC2
18
+ class Base < AWS::Base
19
+
20
+ API_VERSION_HACKED = '2011-11-01'
21
+
22
+ def api_version
23
+ API_VERSION_HACKED
24
+ end
25
+
26
+ def describe_vpcs( options = {} )
27
+ options = { :vpc_id => [] }.merge(options)
28
+ params = pathlist("VpcId", options[:vpc_id])
29
+ return response_generator(:action => "DescribeVpcs", :params => params)
30
+ end
31
+
32
+ def describe_internetgateways( options = {} )
33
+ options = { :interetgateway_id => [] }.merge(options)
34
+ params = pathlist("internetGatewayId", options[:interetgateway_id])
35
+ return response_generator(:action => "DescribeInternetGateways", :params => params)
36
+ end
37
+
38
+ end
39
+ end
40
+ end
41
+
42
+
15
43
  class Ec2Helper
16
44
  # expects an instance of AWS::EC2::Base from the amazon-ec2 gem
17
45
  def initialize(ec2_api)
@@ -1,6 +1,7 @@
1
1
  require 'net/scp'
2
2
  require "AWS"
3
3
 
4
+
4
5
  # Contains methods that are used by the scripts in the state-machines. Since
5
6
  # they are reused by different scripts, they are factored into this module.
6
7
  #
@@ -21,9 +21,9 @@ class CriticalPortsAudit < Ec2Script
21
21
  if @input_params[:ec2_api_handler] == nil
22
22
  raise Exception.new("no EC2 handler specified")
23
23
  end
24
- if @input_params[:critical_ports] == nil
25
- raise Exception.new("no ports specified")
26
- end
24
+ #if @input_params[:critical_ports] == nil
25
+ # raise Exception.new("no ports specified")
26
+ #end
27
27
  end
28
28
 
29
29
  def load_initial_state()
@@ -53,6 +53,7 @@ class CriticalPortsAudit < Ec2Script
53
53
  def enter
54
54
  @context[:result][:affected_groups] = []
55
55
  @context[:security_groups]['securityGroupInfo']['item'].each() do |group_info|
56
+ next if !group_info['vpcId'].nil? && !group_info['vpcId'].empty?
56
57
  post_message("checking group '#{group_info['groupName']}'...")
57
58
  next if group_info['ipPermissions'] == nil || group_info['ipPermissions']['item'] == nil
58
59
  group_info['ipPermissions']['item'].each() do |permission_info|
@@ -60,13 +61,26 @@ class CriticalPortsAudit < Ec2Script
60
61
  next unless permission_info['groups'] == nil #ignore access rights to other groups
61
62
  next unless permission_info['ipRanges']['item'][0]['cidrIp'] == "0.0.0.0/0"
62
63
  #now check if a critical port is within the port-range
63
- @context[:critical_ports].each() do |port|
64
- if permission_info['fromPort'].to_i <= port && permission_info['toPort'].to_i >= port
65
- @context[:result][:affected_groups] << {:name => group_info['groupName'],
66
- :from => permission_info['fromPort'], :to => permission_info['toPort'],
67
- :concerned => port, :prot => permission_info['protocol']}
68
- post_message("=> found publically accessible port range that contains "+
69
- "critical port for group #{group_info['groupName']}: #{permission_info['fromPort']}-#{permission_info['toPort']}")
64
+ #XXX: allow to skip the 'critical port' options if nil
65
+ if @context[:critical_ports] == nil || @context[:critical_ports].empty?
66
+ port = nil
67
+ if permission_info['fromPort'].to_i == permission_info['toPort'].to_i
68
+ port = permission_info['fromPort'].to_i
69
+ post_message("=> found unique port #{port}")
70
+ end
71
+ @context[:result][:affected_groups] << {:name => group_info['groupName'],
72
+ :from => permission_info['fromPort'], :to => permission_info['toPort'],
73
+ :concerned => port, :prot => permission_info['ipProtocol']}
74
+ post_message("=> found at least one port publicly opened")
75
+ else
76
+ @context[:critical_ports].each() do |port|
77
+ if permission_info['fromPort'].to_i <= port && permission_info['toPort'].to_i >= port
78
+ @context[:result][:affected_groups] << {:name => group_info['groupName'],
79
+ :from => permission_info['fromPort'], :to => permission_info['toPort'],
80
+ :concerned => port, :prot => permission_info['ipProtocol']}
81
+ post_message("=> found publically accessible port range that contains "+
82
+ "critical port for group #{group_info['groupName']}: #{permission_info['fromPort']}-#{permission_info['toPort']}")
83
+ end
70
84
  end
71
85
  end
72
86
  end
@@ -67,6 +67,11 @@ class OpenPortChecker < Ec2Script
67
67
  @context[:ec2_instances]['reservationSet']['item'].each() do |instance_info|
68
68
  instance_id = ec2_helper.get_instance_id(instance_info)
69
69
  @logger.debug("instance_info = #{instance_info.inspect}")
70
+ vpc_instance = ec2_helper.get_instance_prop(instance_info, 'vpcId')
71
+ if !vpc_instance.nil? && !vpc_instance.empty?
72
+ post_message("ignore VPC instance #{instance_id}")
73
+ next
74
+ end
70
75
  instance_ip = ec2_helper.get_instance_prop(instance_info, 'dnsName')
71
76
  instance_state = ec2_helper.get_instance_prop(instance_info, 'instanceState')['name']
72
77
  if instance_state != "running"
@@ -0,0 +1,126 @@
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
+ require 'pp'
8
+
9
+ # Checks for all security groups if sensible ports are opened for the wide
10
+ # public.
11
+ #
12
+
13
+ class VpcCriticalPortsAudit < Ec2Script
14
+ # Input parameters
15
+ # * ec2_api_handler => object that allows to access the EC2 API
16
+ # * :critical_ports => arrays of ports to be checked
17
+ def initialize(input_params)
18
+ super(input_params)
19
+ end
20
+
21
+ def check_input_parameters()
22
+ if @input_params[:ec2_api_handler] == nil
23
+ raise Exception.new("no EC2 handler specified")
24
+ end
25
+ #if @input_params[:critical_ports] == nil
26
+ # raise Exception.new("no ports specified")
27
+ #end
28
+ end
29
+
30
+ def load_initial_state()
31
+ CriticalPortsAuditState.load_state(@input_params)
32
+ end
33
+
34
+ private
35
+
36
+ # Here begins the state machine implementation
37
+ class CriticalPortsAuditState < ScriptExecutionState
38
+ def self.load_state(context)
39
+ state = context[:initial_state] == nil ? RetrievingSecurityGroups.new(context) : context[:initial_state]
40
+ state
41
+ end
42
+ end
43
+
44
+ # Nothing done yet. Retrieve all security groups
45
+ class RetrievingSecurityGroups < CriticalPortsAuditState
46
+ def enter
47
+ retrieve_security_groups()
48
+ CheckingSensiblePorts.new(@context)
49
+ end
50
+ end
51
+
52
+ # Security groups retrieved. Start analysing them.
53
+ class CheckingSensiblePorts< CriticalPortsAuditState
54
+ def enter
55
+ @context[:result][:affected_groups] = []
56
+ @context[:security_groups]['securityGroupInfo']['item'].each() do |group_info|
57
+ #check only VPC SecurityGroups
58
+ next if group_info['vpcId'].nil? || group_info['vpcId'].empty?
59
+ post_message("checking VPC SecurityGroup '#{group_info['groupName']}'...")
60
+ vpc = @context[:ec2_api_handler].describe_vpcs(:vpc_id => group_info['vpcId'])
61
+ vpc_ref = ""
62
+ vpc_item = vpc['vpcSet']['item'][0]
63
+ if !vpc_item['name'].nil? && !vpc_item['name'].empty?
64
+ vpc_ref = vpc_item['name']
65
+ else
66
+ #XXX: shold be the same as "group_info['vpcId']"
67
+ vpc_ref = vpc_item['vpcId']
68
+ end
69
+ igw = @context[:ec2_api_handler].describe_internetgateways()
70
+ igw_ref = ""
71
+ found = false
72
+ igw['internetGatewaySet']['item'].each {|igw_item|
73
+ break if found == true
74
+ igw_id = igw_item['internetGatewayId']
75
+ igw_item['attachmentSet']['item'].each {|vpc_item|
76
+ if vpc_item['vpcId'].eql?("#{group_info['vpcId']}")
77
+ igw_ref = igw_id
78
+ found = true
79
+ break
80
+ end
81
+ }
82
+ }
83
+ next if group_info['ipPermissions'] == nil || group_info['ipPermissions']['item'] == nil
84
+ group_info['ipPermissions']['item'].each() do |permission_info|
85
+ logger.debug("permission_info = #{permission_info.inspect}")
86
+ next unless permission_info['groups'] == nil #ignore access rights to other groups
87
+ next unless permission_info['ipRanges']['item'][0]['cidrIp'] == "0.0.0.0/0"
88
+ #now check if a critical port is within the port-range
89
+ #XXX: allow to skip the 'critical port' options if nil
90
+ if @context[:critical_ports] == nil || @context[:critical_ports].empty?
91
+ port = nil
92
+ if permission_info['fromPort'].to_i == permission_info['toPort'].to_i
93
+ port = permission_info['fromPort'].to_i
94
+ post_message("=> found unique port: #{port}")
95
+ end
96
+ @context[:result][:affected_groups] << {:name => group_info['groupName'],
97
+ :from => permission_info['fromPort'], :to => permission_info['toPort'],
98
+ :concerned => port, :prot => permission_info['ipProtocol'],
99
+ :vpc_ref => vpc_ref, :igw_ref => igw_ref}
100
+ post_message("=> found at least one port publicly opened")
101
+ else
102
+ @context[:critical_ports].each() do |port|
103
+ if permission_info['fromPort'].to_i <= port && permission_info['toPort'].to_i >= port
104
+ @context[:result][:affected_groups] << {:name => group_info['groupName'],
105
+ :from => permission_info['fromPort'], :to => permission_info['toPort'],
106
+ :concerned => port, :prot => permission_info['ipProtocol'],
107
+ :vpc_ref => vpc_ref, :igw_ref => igw_ref}
108
+ post_message("=> found publically accessible port range that contains "+
109
+ "critical port for group #{group_info['groupName']}: #{permission_info['fromPort']}-#{permission_info['toPort']}")
110
+ end
111
+ end
112
+ end
113
+ end
114
+ end
115
+ Done.new(@context)
116
+ end
117
+ end
118
+
119
+ # Script done.
120
+ class Done < CriticalPortsAuditState
121
+ def done?
122
+ true
123
+ end
124
+ end
125
+
126
+ end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: CloudyScripts
3
3
  version: !ruby/object:Gem::Version
4
- hash: 125
4
+ hash: 67
5
5
  prerelease: false
6
6
  segments:
7
7
  - 2
8
8
  - 11
9
- - 47
10
- version: 2.11.47
9
+ - 48
10
+ version: 2.11.48
11
11
  platform: ruby
12
12
  authors:
13
13
  - Matthias Jung
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2011-11-17 00:00:00 +00:00
18
+ date: 2011-11-29 00:00:00 +00:00
19
19
  default_executable:
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency
@@ -253,6 +253,7 @@ files:
253
253
  - lib/scripts/vCloud/open_port_checker_vm.rb
254
254
  - lib/scripts/ec2/port_range_detector.rb
255
255
  - lib/scripts/ec2/dm_encrypt.rb
256
+ - lib/scripts/ec2/vpc_critical_ports_audit.rb
256
257
  - lib/scripts/ec2/ami2_ebs_conversion.rb
257
258
  - lib/scripts/ec2/audit_via_ssh.rb
258
259
  - lib/scripts/ec2/open_port_checker.rb