aws_recon 0.2.1 → 0.2.6
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.
- checksums.yaml +4 -4
- data/.github/stale.yml +17 -0
- data/.gitignore +1 -0
- data/aws_recon.gemspec +4 -4
- data/bin/aws_recon +3 -0
- data/lib/aws_recon.rb +1 -2
- data/lib/aws_recon/aws_recon.rb +35 -33
- data/lib/aws_recon/collectors.rb +2 -0
- data/lib/aws_recon/collectors/ec2.rb +17 -0
- data/lib/aws_recon/collectors/elasticache.rb +22 -0
- data/lib/aws_recon/collectors/lambda.rb +0 -1
- data/lib/aws_recon/collectors/s3.rb +8 -6
- data/lib/aws_recon/lib/mapper.rb +9 -2
- data/lib/aws_recon/options.rb +10 -3
- data/lib/aws_recon/services.yaml +2 -0
- data/lib/aws_recon/version.rb +1 -1
- data/readme.md +52 -16
- metadata +14 -13
- data/Gemfile.lock +0 -1000
- data/lib/aws_recon/collectors/collectors.rb +0 -2
- data/readme_gem.md +0 -39
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 2707134a4d4be23f0f1cd3320fda7e75463aae49113b2f4b802257aa02b0de52
|
|
4
|
+
data.tar.gz: 85452e37a3657d315fae2b67852bc521786a95fc386db53f4a3212801e140ee4
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 5e1a919375c34b51a72a3bb470ce178b39c178e8e3a569fb47f618c8ac122512e14c2564e42bd72aab3e5a550041f8e9490c3f3d6245ac2d3c933e77a9053d18
|
|
7
|
+
data.tar.gz: e93eaad39853ffdd5c934572b2d9fb2add88efc0150bc48cbc3cf7cef542c25a98a2ebd1c92e6b64404dde122d86d8d2d38638f6bd5fde0e11974c2c52e5cdc1
|
data/.github/stale.yml
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# Number of days of inactivity before an issue becomes stale
|
|
2
|
+
daysUntilStale: 30
|
|
3
|
+
# Number of days of inactivity before a stale issue is closed
|
|
4
|
+
daysUntilClose: 5
|
|
5
|
+
# Issues with these labels will never be considered stale
|
|
6
|
+
exemptLabels:
|
|
7
|
+
- pinned
|
|
8
|
+
- security
|
|
9
|
+
# Label to use when marking an issue as stale
|
|
10
|
+
staleLabel: wontfix
|
|
11
|
+
# Comment to post when marking an issue as stale. Set to `false` to disable
|
|
12
|
+
markComment: >
|
|
13
|
+
This issue has been automatically marked as stale because it has not had
|
|
14
|
+
recent activity. It will be closed if no further activity occurs. Thank you
|
|
15
|
+
for your contributions.
|
|
16
|
+
# Comment to post when closing a stale issue. Set to `false` to disable
|
|
17
|
+
closeComment: false
|
data/.gitignore
CHANGED
data/aws_recon.gemspec
CHANGED
|
@@ -7,10 +7,10 @@ require 'aws_recon/version'
|
|
|
7
7
|
Gem::Specification.new do |spec|
|
|
8
8
|
spec.name = 'aws_recon'
|
|
9
9
|
spec.version = AwsRecon::VERSION
|
|
10
|
-
spec.authors = ['Josh Larsen']
|
|
10
|
+
spec.authors = ['Josh Larsen', 'Darkbit']
|
|
11
11
|
spec.required_ruby_version = '>= 2.5.0'
|
|
12
|
-
spec.summary = 'A multi-threaded AWS inventory collection tool.'
|
|
13
|
-
spec.description =
|
|
12
|
+
spec.summary = 'A multi-threaded AWS inventory collection cli tool.'
|
|
13
|
+
spec.description = 'AWS Recon is a command line tool to collect resources from an Amazon Web Services (AWS) account. The tool outputs JSON suitable for processing with other tools.'
|
|
14
14
|
spec.homepage = 'https://github.com/darkbitio/aws-recon'
|
|
15
15
|
spec.license = 'MIT'
|
|
16
16
|
|
|
@@ -28,7 +28,7 @@ Gem::Specification.new do |spec|
|
|
|
28
28
|
|
|
29
29
|
spec.add_development_dependency 'bundler', '~> 1.17'
|
|
30
30
|
spec.add_development_dependency 'gem-release', '~> 2.1'
|
|
31
|
-
spec.add_development_dependency 'rake', '
|
|
31
|
+
spec.add_development_dependency 'rake', '>= 12.3.3'
|
|
32
32
|
spec.add_development_dependency 'minitest', '~> 5.0'
|
|
33
33
|
spec.add_development_dependency 'solargraph', '~> 0.39.11'
|
|
34
34
|
spec.add_development_dependency 'rubocop', '~> 0.87.1'
|
data/bin/aws_recon
CHANGED
data/lib/aws_recon.rb
CHANGED
|
@@ -8,12 +8,11 @@ require 'ostruct'
|
|
|
8
8
|
require 'optparse'
|
|
9
9
|
require 'yaml'
|
|
10
10
|
require 'csv'
|
|
11
|
-
require 'pry'
|
|
12
11
|
require 'aws-sdk'
|
|
13
12
|
require 'aws_recon/options.rb'
|
|
14
13
|
require 'aws_recon/lib/mapper.rb'
|
|
15
14
|
require 'aws_recon/lib/formatter.rb'
|
|
16
|
-
require 'aws_recon/collectors
|
|
15
|
+
require 'aws_recon/collectors.rb'
|
|
17
16
|
|
|
18
17
|
require 'aws_recon/version'
|
|
19
18
|
require 'aws_recon/aws_recon'
|
data/lib/aws_recon/aws_recon.rb
CHANGED
|
@@ -4,37 +4,39 @@ SERVICES_CONFIG_FILE = File.join(File.dirname(__FILE__), 'services.yaml').freeze
|
|
|
4
4
|
|
|
5
5
|
module AwsRecon
|
|
6
6
|
class CLI
|
|
7
|
-
|
|
8
|
-
|
|
7
|
+
def initialize
|
|
8
|
+
# parse options
|
|
9
|
+
@options = Parser.parse ARGV.length < 1 ? %w[-h] : ARGV
|
|
9
10
|
|
|
10
|
-
|
|
11
|
-
|
|
11
|
+
# timing
|
|
12
|
+
@starting = Process.clock_gettime(Process::CLOCK_MONOTONIC)
|
|
12
13
|
|
|
13
|
-
|
|
14
|
-
|
|
14
|
+
# AWS account id
|
|
15
|
+
@account_id = Aws::STS::Client.new.get_caller_identity.account
|
|
15
16
|
|
|
16
|
-
|
|
17
|
-
|
|
17
|
+
# AWS services
|
|
18
|
+
@aws_services = YAML.load(File.read(SERVICES_CONFIG_FILE), symbolize_names: true)
|
|
18
19
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
20
|
+
# User config services
|
|
21
|
+
if @options.config_file
|
|
22
|
+
user_config = YAML.load(File.read(@options.config_file), symbolize_names: true)
|
|
22
23
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
24
|
+
@services = user_config[:services]
|
|
25
|
+
@regions = user_config[:regions]
|
|
26
|
+
else
|
|
27
|
+
@regions = @options.regions
|
|
28
|
+
@services = @options.services
|
|
29
|
+
end
|
|
29
30
|
|
|
30
|
-
|
|
31
|
-
|
|
31
|
+
# collection
|
|
32
|
+
@resources = []
|
|
32
33
|
|
|
33
|
-
|
|
34
|
-
|
|
34
|
+
# formatter
|
|
35
|
+
@formatter = Formatter.new
|
|
35
36
|
|
|
36
|
-
|
|
37
|
-
|
|
37
|
+
unless @options.stream_output
|
|
38
|
+
puts "\nStarting collection with #{@options.threads} threads...\n"
|
|
39
|
+
end
|
|
38
40
|
end
|
|
39
41
|
|
|
40
42
|
#
|
|
@@ -66,16 +68,16 @@ module AwsRecon
|
|
|
66
68
|
#
|
|
67
69
|
# main wrapper
|
|
68
70
|
#
|
|
69
|
-
def start
|
|
71
|
+
def start(_args)
|
|
70
72
|
#
|
|
71
73
|
# global services
|
|
72
74
|
#
|
|
73
|
-
aws_services.map { |x| OpenStruct.new(x) }.filter { |s| s.global }.each do |service|
|
|
75
|
+
@aws_services.map { |x| OpenStruct.new(x) }.filter { |s| s.global }.each do |service|
|
|
74
76
|
# user included this service in the args
|
|
75
|
-
next unless services.include?(service.name)
|
|
77
|
+
next unless @services.include?(service.name)
|
|
76
78
|
|
|
77
79
|
# user did not exclude 'global'
|
|
78
|
-
next unless regions.include?('global')
|
|
80
|
+
next unless @regions.include?('global')
|
|
79
81
|
|
|
80
82
|
collect(service, 'global')
|
|
81
83
|
end
|
|
@@ -83,28 +85,28 @@ module AwsRecon
|
|
|
83
85
|
#
|
|
84
86
|
# regional services
|
|
85
87
|
#
|
|
86
|
-
regions.filter { |x| x != 'global' }.each do |region|
|
|
87
|
-
Parallel.map(aws_services.map { |x| OpenStruct.new(x) }.filter { |s| !s.global }.each, in_threads: @options.threads) do |service|
|
|
88
|
+
@regions.filter { |x| x != 'global' }.each do |region|
|
|
89
|
+
Parallel.map(@aws_services.map { |x| OpenStruct.new(x) }.filter { |s| !s.global }.each, in_threads: @options.threads) do |service|
|
|
88
90
|
# some services aren't available in some regions
|
|
89
91
|
skip_region = service&.excluded_regions&.include?(region)
|
|
90
92
|
|
|
91
93
|
# user included this region in the args
|
|
92
|
-
next unless regions.include?(region) && !skip_region
|
|
94
|
+
next unless @regions.include?(region) && !skip_region
|
|
93
95
|
|
|
94
96
|
# user included this service in the args
|
|
95
|
-
next unless services.include?(service.name) || services.include?(service.alias) # rubocop:disable Layout/LineLength
|
|
97
|
+
next unless @services.include?(service.name) || @services.include?(service.alias) # rubocop:disable Layout/LineLength
|
|
96
98
|
|
|
97
99
|
collect(service, region)
|
|
98
100
|
end
|
|
99
101
|
end
|
|
100
102
|
rescue Interrupt # ctrl-c
|
|
101
|
-
elapsed = Process.clock_gettime(Process::CLOCK_MONOTONIC) - starting
|
|
103
|
+
elapsed = Process.clock_gettime(Process::CLOCK_MONOTONIC) - @starting
|
|
102
104
|
|
|
103
105
|
puts "\nStopped early after \x1b[32m#{elapsed.to_i}\x1b[0m seconds.\n"
|
|
104
106
|
ensure
|
|
105
107
|
# write output file
|
|
106
108
|
if @options.output_file
|
|
107
|
-
elapsed = Process.clock_gettime(Process::CLOCK_MONOTONIC) - starting
|
|
109
|
+
elapsed = Process.clock_gettime(Process::CLOCK_MONOTONIC) - @starting
|
|
108
110
|
|
|
109
111
|
puts "\nFinished in \x1b[32m#{elapsed.to_i}\x1b[0m seconds. Saving resources to \x1b[32m#{@options.output_file}\x1b[0m.\n\n"
|
|
110
112
|
|
|
@@ -48,6 +48,23 @@ class EC2 < Mapper
|
|
|
48
48
|
struct.arn = instance.instance_id # no true ARN
|
|
49
49
|
struct.reservation_id = reservation.reservation_id
|
|
50
50
|
|
|
51
|
+
# collect instance user_data
|
|
52
|
+
if @options.collect_user_data
|
|
53
|
+
user_data_raw = @client.describe_instance_attribute({
|
|
54
|
+
attribute: 'userData',
|
|
55
|
+
instance_id: instance.instance_id
|
|
56
|
+
}).user_data.to_h[:value]
|
|
57
|
+
|
|
58
|
+
# don't save non-string user_data
|
|
59
|
+
if user_data_raw
|
|
60
|
+
user_data = Base64.decode64(user_data_raw)
|
|
61
|
+
|
|
62
|
+
if user_data.force_encoding('UTF-8').ascii_only?
|
|
63
|
+
struct.user_data = user_data
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
|
|
51
68
|
resources.push(struct.to_h)
|
|
52
69
|
end
|
|
53
70
|
end
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
class ElastiCache < Mapper
|
|
2
|
+
def collect
|
|
3
|
+
resources = []
|
|
4
|
+
|
|
5
|
+
#
|
|
6
|
+
# describe_cache_clusters
|
|
7
|
+
#
|
|
8
|
+
@client.describe_cache_clusters.each_with_index do |response, page|
|
|
9
|
+
log(response.context.operation_name, page)
|
|
10
|
+
|
|
11
|
+
response.cache_clusters.each do |cluster|
|
|
12
|
+
struct = OpenStruct.new(cluster.to_h)
|
|
13
|
+
struct.type = 'cluster'
|
|
14
|
+
struct.arn = cluster.arn
|
|
15
|
+
|
|
16
|
+
resources.push(struct.to_h)
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
resources
|
|
21
|
+
end
|
|
22
|
+
end
|
|
@@ -15,8 +15,6 @@ class S3 < Mapper
|
|
|
15
15
|
log(response.context.operation_name, page)
|
|
16
16
|
|
|
17
17
|
Parallel.map(response.buckets.each, in_threads: @options.threads) do |bucket|
|
|
18
|
-
# use shared client instance
|
|
19
|
-
client = @client
|
|
20
18
|
@thread = Parallel.worker_number
|
|
21
19
|
log(response.context.operation_name, bucket.name)
|
|
22
20
|
|
|
@@ -27,10 +25,14 @@ class S3 < Mapper
|
|
|
27
25
|
# check bucket region constraint
|
|
28
26
|
location = @client.get_bucket_location({ bucket: bucket.name }).location_constraint
|
|
29
27
|
|
|
30
|
-
#
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
28
|
+
# if you use a region other than the us-east-1 endpoint
|
|
29
|
+
# to create a bucket, you must set the location_constraint
|
|
30
|
+
# bucket parameter to the same region. (https://docs.aws.amazon.com/general/latest/gr/s3.html)
|
|
31
|
+
client = if location.empty?
|
|
32
|
+
@client
|
|
33
|
+
else
|
|
34
|
+
Aws::S3::Client.new({ region: location })
|
|
35
|
+
end
|
|
34
36
|
|
|
35
37
|
operations = [
|
|
36
38
|
{ func: 'get_bucket_acl', key: 'acl', field: nil },
|
data/lib/aws_recon/lib/mapper.rb
CHANGED
|
@@ -15,6 +15,13 @@
|
|
|
15
15
|
# to add 5 seconds delay on each retry for a total max of 55 seconds.
|
|
16
16
|
#
|
|
17
17
|
class Mapper
|
|
18
|
+
# Services that use us-east-1 endpoint only:
|
|
19
|
+
# Organizations
|
|
20
|
+
# Route53Domains
|
|
21
|
+
# Shield
|
|
22
|
+
# S3 (unless the bucket was created in another region)
|
|
23
|
+
SINGLE_REGION_SERVICES = %w[route53domains s3 shield support organizations].freeze
|
|
24
|
+
|
|
18
25
|
def initialize(service, region, options)
|
|
19
26
|
@service = service
|
|
20
27
|
@region = region
|
|
@@ -39,8 +46,8 @@ class Mapper
|
|
|
39
46
|
# regional service
|
|
40
47
|
client_options.merge!({ region: region }) unless region == 'global'
|
|
41
48
|
|
|
42
|
-
#
|
|
43
|
-
client_options.merge!({ region: 'us-east-1' }) if service.downcase
|
|
49
|
+
# single region services
|
|
50
|
+
client_options.merge!({ region: 'us-east-1' }) if SINGLE_REGION_SERVICES.include?(service.downcase) # rubocop:disable Layout/LineLength
|
|
44
51
|
|
|
45
52
|
# debug with wire trace
|
|
46
53
|
client_options.merge!({ http_wire_trace: true }) if @options.debug
|
data/lib/aws_recon/options.rb
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
class Parser
|
|
4
4
|
DEFAULT_CONFIG_FILE = nil
|
|
5
|
-
DEFAULT_OUTPUT_FILE = File.
|
|
5
|
+
DEFAULT_OUTPUT_FILE = File.expand_path(File.join(Dir.pwd, 'output.json')).freeze
|
|
6
6
|
SERVICES_CONFIG_FILE = File.join(File.dirname(__FILE__), 'services.yaml').freeze
|
|
7
7
|
DEFAULT_FORMAT = 'aws'
|
|
8
8
|
DEFAULT_THREADS = 8
|
|
@@ -15,6 +15,7 @@ class Parser
|
|
|
15
15
|
:output_file,
|
|
16
16
|
:output_format,
|
|
17
17
|
:threads,
|
|
18
|
+
:collect_user_data,
|
|
18
19
|
:skip_slow,
|
|
19
20
|
:stream_output,
|
|
20
21
|
:verbose,
|
|
@@ -43,11 +44,12 @@ class Parser
|
|
|
43
44
|
false,
|
|
44
45
|
false,
|
|
45
46
|
false,
|
|
47
|
+
false,
|
|
46
48
|
false
|
|
47
49
|
)
|
|
48
50
|
|
|
49
51
|
opt_parser = OptionParser.new do |opts|
|
|
50
|
-
opts.banner = "\n\x1b[32mAWS Recon\x1b[0m - AWS Inventory Collector\n\nUsage: aws_recon [options]"
|
|
52
|
+
opts.banner = "\n\x1b[32mAWS Recon\x1b[0m - AWS Inventory Collector (#{AwsRecon::VERSION})\n\nUsage: aws_recon [options]"
|
|
51
53
|
|
|
52
54
|
# regions
|
|
53
55
|
opts.on('-r', '--regions [REGIONS]', 'Regions to scan, separated by comma (default: all)') do |regions|
|
|
@@ -86,7 +88,7 @@ class Parser
|
|
|
86
88
|
|
|
87
89
|
# output file
|
|
88
90
|
opts.on('-o', '--output [OUTPUT]', 'Specify output file (default: output.json)') do |output|
|
|
89
|
-
args.output_file = output
|
|
91
|
+
args.output_file = File.expand_path(File.join(Dir.pwd, output))
|
|
90
92
|
end
|
|
91
93
|
|
|
92
94
|
# output format
|
|
@@ -103,6 +105,11 @@ class Parser
|
|
|
103
105
|
end
|
|
104
106
|
end
|
|
105
107
|
|
|
108
|
+
# collect EC2 instance user data
|
|
109
|
+
opts.on('-u', '--user-data', 'Collect EC2 instance user data (default: false)') do
|
|
110
|
+
args.collect_user_data = true
|
|
111
|
+
end
|
|
112
|
+
|
|
106
113
|
# skip slow operations
|
|
107
114
|
opts.on('-z', '--skip-slow', 'Skip slow operations (default: false)') do
|
|
108
115
|
args.skip_slow = true
|
data/lib/aws_recon/services.yaml
CHANGED
data/lib/aws_recon/version.rb
CHANGED
data/readme.md
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
[](https://badge.fury.io/rb/aws_recon)
|
|
2
|
+
|
|
1
3
|
# AWS Recon
|
|
2
4
|
|
|
3
5
|
A multi-threaded AWS inventory collection tool.
|
|
@@ -24,17 +26,30 @@ Ruby 2.5.x or 2.6.x (developed and tested with 2.6.5)
|
|
|
24
26
|
|
|
25
27
|
### Installation
|
|
26
28
|
|
|
27
|
-
|
|
29
|
+
Install the gem:
|
|
28
30
|
|
|
29
31
|
```
|
|
30
|
-
$
|
|
31
|
-
|
|
32
|
-
|
|
32
|
+
$ gem install aws_recon
|
|
33
|
+
Fetching aws_recon-0.2.6.gem
|
|
34
|
+
Fetching aws-sdk-resources-3.76.0.gem
|
|
35
|
+
Fetching aws-sdk-3.0.1.gem
|
|
36
|
+
Fetching parallel-1.19.2.gem
|
|
33
37
|
...
|
|
34
|
-
|
|
38
|
+
Successfully installed aws-sdk-3.0.1
|
|
39
|
+
Successfully installed parallel-1.19.2
|
|
40
|
+
Successfully installed aws_recon-0.2.6
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
Or add it to your Gemfile using `bundle`:
|
|
44
|
+
|
|
45
|
+
```
|
|
46
|
+
$ bundle add aws_recon
|
|
47
|
+
Fetching gem metadata from https://rubygems.org/
|
|
48
|
+
Resolving dependencies...
|
|
35
49
|
...
|
|
36
|
-
|
|
37
|
-
|
|
50
|
+
Using aws-sdk 3.0.1
|
|
51
|
+
Using parallel 1.19.2
|
|
52
|
+
Using aws_recon 0.2.2
|
|
38
53
|
```
|
|
39
54
|
|
|
40
55
|
## Usage
|
|
@@ -42,13 +57,13 @@ Use `bundle info [gemname]` to see where a bundled gem is installed.
|
|
|
42
57
|
AWS Recon will leverage any AWS credentials currently available to the environment it runs in. If you are collecting from multiple accounts, you may want to leverage something like [aws-vault](https://github.com/99designs/aws-vault) to manage different credentials.
|
|
43
58
|
|
|
44
59
|
```
|
|
45
|
-
$ aws-vault exec profile --
|
|
60
|
+
$ aws-vault exec profile -- aws_recon
|
|
46
61
|
```
|
|
47
62
|
|
|
48
63
|
Plain environment variables will work fine too.
|
|
49
64
|
|
|
50
65
|
```
|
|
51
|
-
$ AWS_PROFILE=<profile>
|
|
66
|
+
$ AWS_PROFILE=<profile> aws_recon
|
|
52
67
|
```
|
|
53
68
|
|
|
54
69
|
You may want to use the `-v` or `--verbose` flag initially to see status and activity while collection is running.
|
|
@@ -62,7 +77,7 @@ In verbose mode, the console output will show:
|
|
|
62
77
|
The `t` prefix indicates which thread a particular request is running under. Region, service, and operation indicate which request operation is currently in progress and where.
|
|
63
78
|
|
|
64
79
|
```
|
|
65
|
-
$
|
|
80
|
+
$ aws_recon -v
|
|
66
81
|
|
|
67
82
|
t0.global.EC2.describe_account_attributes
|
|
68
83
|
t2.global.S3.list_buckets
|
|
@@ -87,11 +102,11 @@ Finished in 46 seconds. Saving resources to output.json.
|
|
|
87
102
|
#### Example command line options
|
|
88
103
|
|
|
89
104
|
```
|
|
90
|
-
$ AWS_PROFILE=<profile>
|
|
105
|
+
$ AWS_PROFILE=<profile> aws_recon -s S3,EC2 -r global,us-east-1,us-east-2
|
|
91
106
|
```
|
|
92
107
|
|
|
93
108
|
```
|
|
94
|
-
$ AWS_PROFILE=<profile>
|
|
109
|
+
$ AWS_PROFILE=<profile> aws_recon --services S3,EC2 --regions global,us-east-1,us-east-2
|
|
95
110
|
```
|
|
96
111
|
|
|
97
112
|
#### Errors
|
|
@@ -118,11 +133,11 @@ For regional services, a thread (up to the thread limit) is spawned for each ser
|
|
|
118
133
|
Most users will want to limit collection to relevant services and regions. Running without any options will attempt to collect all resources from all 16 regular regions.
|
|
119
134
|
|
|
120
135
|
```
|
|
121
|
-
$
|
|
136
|
+
$ aws_recon -h
|
|
122
137
|
|
|
123
|
-
AWS Recon - AWS Inventory Collector
|
|
138
|
+
AWS Recon - AWS Inventory Collector (0.2.6)
|
|
124
139
|
|
|
125
|
-
Usage:
|
|
140
|
+
Usage: aws_recon [options]
|
|
126
141
|
-r, --regions [REGIONS] Regions to scan, separated by comma (default: all)
|
|
127
142
|
-n, --not-regions [REGIONS] Regions to skip, separated by comma (default: none)
|
|
128
143
|
-s, --services [SERVICES] Services to scan, separated by comma (default: all)
|
|
@@ -131,6 +146,7 @@ Usage: ./recon.rb [options]
|
|
|
131
146
|
-o, --output [OUTPUT] Specify output file (default: output.json)
|
|
132
147
|
-f, --format [FORMAT] Specify output format (default: aws)
|
|
133
148
|
-t, --threads [THREADS] Specify max threads (default: 8, max: 128)
|
|
149
|
+
-u, --user-data Collect EC2 instance user data (default: false)
|
|
134
150
|
-z, --skip-slow Skip slow operations (default: false)
|
|
135
151
|
-j, --stream-output Stream JSON lines to stdout (default: false)
|
|
136
152
|
-v, --verbose Output client progress and current operation
|
|
@@ -178,6 +194,7 @@ AWS Recon aims to collect all resources and metadata that are relevant in determ
|
|
|
178
194
|
- [x] ELB
|
|
179
195
|
- [x] EKS
|
|
180
196
|
- [x] Elasticsearch
|
|
197
|
+
- [x] ElastiCache
|
|
181
198
|
- [x] Firehose
|
|
182
199
|
- [ ] FMS
|
|
183
200
|
- [ ] Glacier
|
|
@@ -210,10 +227,29 @@ AWS Recon aims to collect all resources and metadata that are relevant in determ
|
|
|
210
227
|
|
|
211
228
|
One of the primary motivations for AWS Recon was to build a tool that is easy to maintain and extend. If you feel like coverage could be improved for a particular service, we would welcome PRs to that effect. Anyone with a moderate familiarity with Ruby will be able to mimic the pattern used by the existing collectors to query a specific service and add the results to the resource collection.
|
|
212
229
|
|
|
230
|
+
### Development
|
|
231
|
+
|
|
232
|
+
Clone this repository:
|
|
233
|
+
|
|
234
|
+
```
|
|
235
|
+
$ git clone git@github.com:darkbitio/aws-recon.git
|
|
236
|
+
$ cd aws-recon
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
Create a sticky gemset if using RVM:
|
|
240
|
+
|
|
241
|
+
```
|
|
242
|
+
$ rvm use 2.6.5@aws_recon_dev --create --ruby-version
|
|
243
|
+
```
|
|
244
|
+
|
|
245
|
+
Run `bin/setup` to install dependencies. Then, run `rake test` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
|
246
|
+
|
|
247
|
+
To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
|
|
248
|
+
|
|
213
249
|
### TODO
|
|
214
250
|
|
|
215
251
|
- [ ] Optionally suppress AWS API errors instead of re-raising them
|
|
216
|
-
- [
|
|
252
|
+
- [x] Package as a gem
|
|
217
253
|
- [ ] Test coverage with AWS SDK stubbed resources
|
|
218
254
|
|
|
219
255
|
|