aws_recon 0.2.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +13 -0
- data/.rubocop.yml +12 -0
- data/.ruby-gemset +1 -0
- data/.ruby-version +1 -0
- data/.travis.yml +7 -0
- data/Gemfile +6 -0
- data/Gemfile.lock +1000 -0
- data/LICENSE.txt +21 -0
- data/Rakefile +10 -0
- data/aws_recon.gemspec +36 -0
- data/bin/aws_recon +5 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/lib/aws_recon.rb +19 -0
- data/lib/aws_recon/aws_recon.rb +115 -0
- data/lib/aws_recon/collectors/acm.rb +32 -0
- data/lib/aws_recon/collectors/apigateway.rb +50 -0
- data/lib/aws_recon/collectors/apigatewayv2.rb +37 -0
- data/lib/aws_recon/collectors/athena.rb +28 -0
- data/lib/aws_recon/collectors/autoscaling.rb +35 -0
- data/lib/aws_recon/collectors/cloudformation.rb +29 -0
- data/lib/aws_recon/collectors/cloudfront.rb +28 -0
- data/lib/aws_recon/collectors/cloudtrail.rb +33 -0
- data/lib/aws_recon/collectors/cloudwatch.rb +33 -0
- data/lib/aws_recon/collectors/cloudwatchlogs.rb +36 -0
- data/lib/aws_recon/collectors/codebuild.rb +29 -0
- data/lib/aws_recon/collectors/codepipeline.rb +27 -0
- data/lib/aws_recon/collectors/collectors.rb +2 -0
- data/lib/aws_recon/collectors/configservice.rb +80 -0
- data/lib/aws_recon/collectors/directconnect.rb +25 -0
- data/lib/aws_recon/collectors/directyservice.rb +27 -0
- data/lib/aws_recon/collectors/dms.rb +25 -0
- data/lib/aws_recon/collectors/dynamodb.rb +26 -0
- data/lib/aws_recon/collectors/ec2.rb +257 -0
- data/lib/aws_recon/collectors/ecr.rb +39 -0
- data/lib/aws_recon/collectors/ecs.rb +40 -0
- data/lib/aws_recon/collectors/efs.rb +25 -0
- data/lib/aws_recon/collectors/eks.rb +36 -0
- data/lib/aws_recon/collectors/elasticloadbalancing.rb +41 -0
- data/lib/aws_recon/collectors/elasticloadbalancingv2.rb +63 -0
- data/lib/aws_recon/collectors/elasticsearch.rb +27 -0
- data/lib/aws_recon/collectors/firehose.rb +29 -0
- data/lib/aws_recon/collectors/guardduty.rb +33 -0
- data/lib/aws_recon/collectors/iam.rb +136 -0
- data/lib/aws_recon/collectors/kafka.rb +27 -0
- data/lib/aws_recon/collectors/kinesis.rb +26 -0
- data/lib/aws_recon/collectors/kms.rb +71 -0
- data/lib/aws_recon/collectors/lambda.rb +42 -0
- data/lib/aws_recon/collectors/lightsail.rb +38 -0
- data/lib/aws_recon/collectors/organizations.rb +36 -0
- data/lib/aws_recon/collectors/rds.rb +81 -0
- data/lib/aws_recon/collectors/redshift.rb +40 -0
- data/lib/aws_recon/collectors/route53.rb +28 -0
- data/lib/aws_recon/collectors/route53domains.rb +25 -0
- data/lib/aws_recon/collectors/s3.rb +80 -0
- data/lib/aws_recon/collectors/sagemaker.rb +25 -0
- data/lib/aws_recon/collectors/servicequotas.rb +44 -0
- data/lib/aws_recon/collectors/ses.rb +28 -0
- data/lib/aws_recon/collectors/shield.rb +67 -0
- data/lib/aws_recon/collectors/sns.rb +38 -0
- data/lib/aws_recon/collectors/sqs.rb +28 -0
- data/lib/aws_recon/collectors/ssm.rb +41 -0
- data/lib/aws_recon/collectors/support.rb +43 -0
- data/lib/aws_recon/collectors/transfer.rb +24 -0
- data/lib/aws_recon/collectors/wafv2.rb +49 -0
- data/lib/aws_recon/collectors/workspaces.rb +24 -0
- data/lib/aws_recon/collectors/xray.rb +19 -0
- data/lib/aws_recon/lib/formatter.rb +32 -0
- data/lib/aws_recon/lib/mapper.rb +69 -0
- data/lib/aws_recon/options.rb +141 -0
- data/lib/aws_recon/services.yaml +134 -0
- data/lib/aws_recon/version.rb +3 -0
- data/readme.md +226 -0
- data/readme_gem.md +39 -0
- metadata +245 -0
@@ -0,0 +1,25 @@
|
|
1
|
+
class SageMaker < Mapper
|
2
|
+
#
|
3
|
+
# Returns an array of resources.
|
4
|
+
#
|
5
|
+
def collect
|
6
|
+
resources = []
|
7
|
+
|
8
|
+
#
|
9
|
+
# list_notebook_instances
|
10
|
+
#
|
11
|
+
@client.list_notebook_instances.each_with_index do |response, page|
|
12
|
+
log(response.context.operation_name, page)
|
13
|
+
|
14
|
+
response.notebook_instances.each do |instance|
|
15
|
+
struct = OpenStruct.new(instance.to_h)
|
16
|
+
struct.type = 'notebook_instance'
|
17
|
+
struct.arn = instance.notebook_instance_arn
|
18
|
+
|
19
|
+
resources.push(struct.to_h)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
resources
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
class ServiceQuotas < Mapper
|
2
|
+
#
|
3
|
+
# Returns an array of resources.
|
4
|
+
#
|
5
|
+
def collect
|
6
|
+
resources = []
|
7
|
+
|
8
|
+
#
|
9
|
+
# list_service_quotas
|
10
|
+
#
|
11
|
+
# TODO: expand to more services as needed
|
12
|
+
#
|
13
|
+
# service_codes = %w[autoscaling ec2 ecr eks elasticloadbalancing fargate iam vpc]
|
14
|
+
service_codes = %w[ec2 eks iam]
|
15
|
+
|
16
|
+
service_codes.each do |service|
|
17
|
+
@client.list_service_quotas({ service_code: service }).each_with_index do |response, page|
|
18
|
+
log(response.context.operation_name, service, page)
|
19
|
+
|
20
|
+
response.quotas.each do |quota|
|
21
|
+
struct = OpenStruct.new(quota.to_h)
|
22
|
+
struct.type = 'quota'
|
23
|
+
struct.arn = quota.quota_arn
|
24
|
+
|
25
|
+
resources.push(struct.to_h)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
rescue Aws::ServiceQuotas::Errors::ServiceError => e
|
29
|
+
log_error(e.code, service)
|
30
|
+
raise e unless suppressed_errors.include?(e.code)
|
31
|
+
end
|
32
|
+
|
33
|
+
resources
|
34
|
+
end
|
35
|
+
|
36
|
+
private
|
37
|
+
|
38
|
+
# not an error
|
39
|
+
def suppressed_errors
|
40
|
+
%w[
|
41
|
+
NoSuchResourceException
|
42
|
+
]
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
class SES < Mapper
|
2
|
+
#
|
3
|
+
# Returns an array of resources.
|
4
|
+
#
|
5
|
+
def collect
|
6
|
+
resources = []
|
7
|
+
|
8
|
+
#
|
9
|
+
# list_identities
|
10
|
+
#
|
11
|
+
@client.list_identities.each_with_index do |response, page|
|
12
|
+
log(response.context.operation_name, page)
|
13
|
+
|
14
|
+
response.identities.each do |identity|
|
15
|
+
struct = OpenStruct.new
|
16
|
+
struct.type = 'identity'
|
17
|
+
struct.arn = "aws:ses:#{@region}::identity/#{identity}"
|
18
|
+
|
19
|
+
# get_identity_dkim_attributes
|
20
|
+
struct.dkim_attributes = @client.get_identity_dkim_attributes({ identities: [identity] }).dkim_attributes[identity].to_h
|
21
|
+
|
22
|
+
resources.push(struct.to_h)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
resources
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,67 @@
|
|
1
|
+
class Shield < Mapper
|
2
|
+
#
|
3
|
+
# Returns an array of resources.
|
4
|
+
#
|
5
|
+
def collect
|
6
|
+
resources = []
|
7
|
+
|
8
|
+
#
|
9
|
+
# describe_subscription
|
10
|
+
#
|
11
|
+
@client.describe_subscription.each do |response|
|
12
|
+
log(response.context.operation_name)
|
13
|
+
|
14
|
+
struct = OpenStruct.new(response.subscription.to_h)
|
15
|
+
struct.type = 'subscription'
|
16
|
+
struct.arn = "arn:aws:shield:#{@region}:#{account}:subscription"
|
17
|
+
|
18
|
+
resources.push(struct.to_h)
|
19
|
+
end
|
20
|
+
|
21
|
+
#
|
22
|
+
# describe_emergency_contact_settings
|
23
|
+
#
|
24
|
+
@client.describe_emergency_contact_settings.each do |response|
|
25
|
+
log(response.context.operation_name)
|
26
|
+
|
27
|
+
struct = OpenStruct.new
|
28
|
+
struct.type = 'contact_list'
|
29
|
+
struct.arn = "arn:aws:shield:#{@region}:#{account}:contact_list"
|
30
|
+
struct.contacts = response.emergency_contact_list.map(&:to_h)
|
31
|
+
|
32
|
+
resources.push(struct.to_h)
|
33
|
+
end
|
34
|
+
|
35
|
+
#
|
36
|
+
# list_protections
|
37
|
+
#
|
38
|
+
@client.list_protections.each_with_index do |response, page|
|
39
|
+
log(response.context.operation_name, page)
|
40
|
+
|
41
|
+
# describe_protection
|
42
|
+
response.protections.each do |protection|
|
43
|
+
struct = OpenStruct.new(@client.describe_protection({ protection_id: protection.id }).protection.to_h)
|
44
|
+
struct.type = 'protection'
|
45
|
+
struct.arn = protection.resource_arn
|
46
|
+
|
47
|
+
resources.push(struct.to_h)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
resources
|
52
|
+
rescue Aws::Shield::Errors::ServiceError => e
|
53
|
+
log_error(e.code)
|
54
|
+
raise e unless suppressed_errors.include?(e.code)
|
55
|
+
|
56
|
+
[] # no access or service isn't enabled
|
57
|
+
end
|
58
|
+
|
59
|
+
private
|
60
|
+
|
61
|
+
# not an error
|
62
|
+
def suppressed_errors
|
63
|
+
%w[
|
64
|
+
ResourceNotFoundException
|
65
|
+
]
|
66
|
+
end
|
67
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
class SNS < Mapper
|
2
|
+
#
|
3
|
+
# Returns an array of resources.
|
4
|
+
#
|
5
|
+
def collect
|
6
|
+
resources = []
|
7
|
+
|
8
|
+
#
|
9
|
+
# list_topics
|
10
|
+
#
|
11
|
+
@client.list_topics.each_with_index do |response, page|
|
12
|
+
log(response.context.operation_name, page)
|
13
|
+
|
14
|
+
response.topics.each do |topic|
|
15
|
+
log(response.context.operation_name, topic.topic_arn, page)
|
16
|
+
|
17
|
+
# get_topic_attributes
|
18
|
+
struct = OpenStruct.new(@client.get_topic_attributes({ topic_arn: topic.topic_arn }).attributes.to_h)
|
19
|
+
struct.type = 'topic'
|
20
|
+
struct.arn = topic.topic_arn
|
21
|
+
struct.subscriptions = []
|
22
|
+
|
23
|
+
# list_subscriptions_by_topic
|
24
|
+
@client.list_subscriptions_by_topic({ topic_arn: topic.topic_arn }).each_with_index do |response, page|
|
25
|
+
log(response.context.operation_name, topic.topic_arn, page)
|
26
|
+
|
27
|
+
response.subscriptions.each do |sub|
|
28
|
+
struct.subscriptions.push(sub.to_h)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
resources.push(struct.to_h)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
resources
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
class SQS < Mapper
|
2
|
+
#
|
3
|
+
# Returns an array of resources.
|
4
|
+
#
|
5
|
+
def collect
|
6
|
+
resources = []
|
7
|
+
|
8
|
+
#
|
9
|
+
# list_queues
|
10
|
+
#
|
11
|
+
@client.list_queues.each_with_index do |response, page|
|
12
|
+
log(response.context.operation_name, page)
|
13
|
+
|
14
|
+
response.queue_urls.each do |queue|
|
15
|
+
log(response.context.operation_name, queue.downcase.split('/').last, page)
|
16
|
+
|
17
|
+
# get_queue_attributes
|
18
|
+
struct = OpenStruct.new(@client.get_queue_attributes({ queue_url: queue, attribute_names: ['All'] }).attributes.to_h)
|
19
|
+
struct.type = 'queue'
|
20
|
+
struct.arn = struct.QueueArn
|
21
|
+
|
22
|
+
resources.push(struct.to_h)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
resources
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
class SSM < Mapper
|
2
|
+
#
|
3
|
+
# Returns an array of resources.
|
4
|
+
#
|
5
|
+
def collect
|
6
|
+
resources = []
|
7
|
+
|
8
|
+
#
|
9
|
+
# describe_instance_information
|
10
|
+
#
|
11
|
+
@client.describe_instance_information.each_with_index do |response, page|
|
12
|
+
log(response.context.operation_name, page)
|
13
|
+
|
14
|
+
response.instance_information_list.each do |instance|
|
15
|
+
struct = OpenStruct.new(instance.to_h)
|
16
|
+
struct.type = 'instance'
|
17
|
+
struct.arn = instance.instance_id
|
18
|
+
|
19
|
+
resources.push(struct.to_h)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
#
|
24
|
+
# describe_parameters
|
25
|
+
#
|
26
|
+
@client.describe_parameters.each_with_index do |response, page|
|
27
|
+
log(response.context.operation_name, page)
|
28
|
+
|
29
|
+
response.parameters.each do |parameter|
|
30
|
+
struct = OpenStruct.new(parameter.to_h)
|
31
|
+
struct.string_type = parameter.type
|
32
|
+
struct.type = 'parameter'
|
33
|
+
struct.arn = "arn:aws:#{@service}:#{@region}::parameter/#{parameter.name}"
|
34
|
+
|
35
|
+
resources.push(struct.to_h)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
resources
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
class Support < Mapper
|
2
|
+
#
|
3
|
+
# Returns an array of resources.
|
4
|
+
#
|
5
|
+
def collect
|
6
|
+
resources = []
|
7
|
+
|
8
|
+
#
|
9
|
+
# describe_trusted_advisor_checks
|
10
|
+
#
|
11
|
+
@client.describe_trusted_advisor_checks({ language: 'en' }).each_with_index do |response, page|
|
12
|
+
log(response.context.operation_name, page)
|
13
|
+
|
14
|
+
response.checks.each do |check|
|
15
|
+
struct = OpenStruct.new(check.to_h)
|
16
|
+
struct.type = 'trusted_advisor_check'
|
17
|
+
struct.arn = "arn:aws:support::trusted_advisor_check/#{check.id}"
|
18
|
+
|
19
|
+
# describe_trusted_advisor_check_result
|
20
|
+
struct.result = @client.describe_trusted_advisor_check_result({ check_id: check.id }).result.to_h
|
21
|
+
log(response.context.operation_name, 'describe_trusted_advisor_check_result', check.id)
|
22
|
+
|
23
|
+
resources.push(struct.to_h)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
resources
|
28
|
+
rescue Aws::Support::Errors::ServiceError => e
|
29
|
+
log_error(e.code)
|
30
|
+
raise e unless suppressed_errors.include?(e.code)
|
31
|
+
|
32
|
+
[] # no Support subscription
|
33
|
+
end
|
34
|
+
|
35
|
+
private
|
36
|
+
|
37
|
+
# not an error
|
38
|
+
def suppressed_errors
|
39
|
+
%w[
|
40
|
+
SubscriptionRequiredException
|
41
|
+
]
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
class Transfer < Mapper
|
2
|
+
#
|
3
|
+
# Returns an array of resources.
|
4
|
+
#
|
5
|
+
def collect
|
6
|
+
resources = []
|
7
|
+
|
8
|
+
#
|
9
|
+
# list_servers
|
10
|
+
#
|
11
|
+
@client.list_servers.each_with_index do |response, page|
|
12
|
+
log(response.context.operation_name, page)
|
13
|
+
|
14
|
+
response.servers.each do |server|
|
15
|
+
struct = OpenStruct.new(server.to_h)
|
16
|
+
struct.type = 'server'
|
17
|
+
|
18
|
+
resources.push(struct.to_h)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
resources
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
class WAFV2 < Mapper
|
2
|
+
#
|
3
|
+
# Returns an array of resources.
|
4
|
+
#
|
5
|
+
# TODO: test live
|
6
|
+
# TODO: resolve scope (e.g. CLOUDFRONT supported?)
|
7
|
+
# TODO: confirm paging behavior
|
8
|
+
#
|
9
|
+
def collect
|
10
|
+
resources = []
|
11
|
+
|
12
|
+
#
|
13
|
+
# list_web_acls
|
14
|
+
#
|
15
|
+
# %w[CLOUDFRONT REGIONAL].each do |scope|
|
16
|
+
%w[REGIONAL].each do |scope|
|
17
|
+
@client.list_web_acls({ scope: scope }).each_with_index do |response, page|
|
18
|
+
log(response.context.operation_name, page)
|
19
|
+
|
20
|
+
response.web_acls.each do |acl|
|
21
|
+
struct = OpenStruct.new(acl.to_h)
|
22
|
+
struct.type = 'web_acl'
|
23
|
+
# struct.arn = "arn:aws:#{@service}:#{@region}::web_acl/#{acl.id}"
|
24
|
+
|
25
|
+
params = {
|
26
|
+
name: acl.name,
|
27
|
+
scope: scope,
|
28
|
+
id: acl.id
|
29
|
+
}
|
30
|
+
|
31
|
+
# get_web_acl
|
32
|
+
@client.get_web_acl(params).each do |response|
|
33
|
+
struct.arn = response.web_acl.arn
|
34
|
+
struct.details = response.web_acl
|
35
|
+
end
|
36
|
+
|
37
|
+
# list_resources_for_web_acl
|
38
|
+
@client.list_resources_for_web_acl({ web_acl_arn: 'ResourceArn' }).each do |response|
|
39
|
+
struct.resources = response.resource_arns.map(&:to_h)
|
40
|
+
end
|
41
|
+
|
42
|
+
resources.push(struct.to_h)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
resources
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
class WorkSpaces < Mapper
|
2
|
+
#
|
3
|
+
# Returns an array of resources.
|
4
|
+
#
|
5
|
+
def collect
|
6
|
+
resources = []
|
7
|
+
#
|
8
|
+
# describe_workspaces
|
9
|
+
#
|
10
|
+
@client.describe_workspaces.each_with_index do |response, page|
|
11
|
+
log(response.context.operation_name, page)
|
12
|
+
|
13
|
+
response.workspaces.each do |workspace|
|
14
|
+
struct = OpenStruct.new(workspace.to_h)
|
15
|
+
struct.type = 'workspace'
|
16
|
+
struct.arn = "arn:aws:workspaces:#{@region}::workspace/#{workspace.workspace_id}"
|
17
|
+
|
18
|
+
resources.push(struct.to_h)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
resources
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
class XRay < Mapper
|
2
|
+
#
|
3
|
+
# Returns an array of resources.
|
4
|
+
#
|
5
|
+
def collect
|
6
|
+
resources = []
|
7
|
+
|
8
|
+
#
|
9
|
+
# get_encryption_config
|
10
|
+
#
|
11
|
+
struct = OpenStruct.new
|
12
|
+
struct.config = @client.get_encryption_config.encryption_config.to_h
|
13
|
+
struct.type = 'config'
|
14
|
+
|
15
|
+
resources.push(struct.to_h)
|
16
|
+
|
17
|
+
resources
|
18
|
+
end
|
19
|
+
end
|