aws_recon 0.2.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (76) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +13 -0
  3. data/.rubocop.yml +12 -0
  4. data/.ruby-gemset +1 -0
  5. data/.ruby-version +1 -0
  6. data/.travis.yml +7 -0
  7. data/Gemfile +6 -0
  8. data/Gemfile.lock +1000 -0
  9. data/LICENSE.txt +21 -0
  10. data/Rakefile +10 -0
  11. data/aws_recon.gemspec +36 -0
  12. data/bin/aws_recon +5 -0
  13. data/bin/console +14 -0
  14. data/bin/setup +8 -0
  15. data/lib/aws_recon.rb +19 -0
  16. data/lib/aws_recon/aws_recon.rb +115 -0
  17. data/lib/aws_recon/collectors/acm.rb +32 -0
  18. data/lib/aws_recon/collectors/apigateway.rb +50 -0
  19. data/lib/aws_recon/collectors/apigatewayv2.rb +37 -0
  20. data/lib/aws_recon/collectors/athena.rb +28 -0
  21. data/lib/aws_recon/collectors/autoscaling.rb +35 -0
  22. data/lib/aws_recon/collectors/cloudformation.rb +29 -0
  23. data/lib/aws_recon/collectors/cloudfront.rb +28 -0
  24. data/lib/aws_recon/collectors/cloudtrail.rb +33 -0
  25. data/lib/aws_recon/collectors/cloudwatch.rb +33 -0
  26. data/lib/aws_recon/collectors/cloudwatchlogs.rb +36 -0
  27. data/lib/aws_recon/collectors/codebuild.rb +29 -0
  28. data/lib/aws_recon/collectors/codepipeline.rb +27 -0
  29. data/lib/aws_recon/collectors/collectors.rb +2 -0
  30. data/lib/aws_recon/collectors/configservice.rb +80 -0
  31. data/lib/aws_recon/collectors/directconnect.rb +25 -0
  32. data/lib/aws_recon/collectors/directyservice.rb +27 -0
  33. data/lib/aws_recon/collectors/dms.rb +25 -0
  34. data/lib/aws_recon/collectors/dynamodb.rb +26 -0
  35. data/lib/aws_recon/collectors/ec2.rb +257 -0
  36. data/lib/aws_recon/collectors/ecr.rb +39 -0
  37. data/lib/aws_recon/collectors/ecs.rb +40 -0
  38. data/lib/aws_recon/collectors/efs.rb +25 -0
  39. data/lib/aws_recon/collectors/eks.rb +36 -0
  40. data/lib/aws_recon/collectors/elasticloadbalancing.rb +41 -0
  41. data/lib/aws_recon/collectors/elasticloadbalancingv2.rb +63 -0
  42. data/lib/aws_recon/collectors/elasticsearch.rb +27 -0
  43. data/lib/aws_recon/collectors/firehose.rb +29 -0
  44. data/lib/aws_recon/collectors/guardduty.rb +33 -0
  45. data/lib/aws_recon/collectors/iam.rb +136 -0
  46. data/lib/aws_recon/collectors/kafka.rb +27 -0
  47. data/lib/aws_recon/collectors/kinesis.rb +26 -0
  48. data/lib/aws_recon/collectors/kms.rb +71 -0
  49. data/lib/aws_recon/collectors/lambda.rb +42 -0
  50. data/lib/aws_recon/collectors/lightsail.rb +38 -0
  51. data/lib/aws_recon/collectors/organizations.rb +36 -0
  52. data/lib/aws_recon/collectors/rds.rb +81 -0
  53. data/lib/aws_recon/collectors/redshift.rb +40 -0
  54. data/lib/aws_recon/collectors/route53.rb +28 -0
  55. data/lib/aws_recon/collectors/route53domains.rb +25 -0
  56. data/lib/aws_recon/collectors/s3.rb +80 -0
  57. data/lib/aws_recon/collectors/sagemaker.rb +25 -0
  58. data/lib/aws_recon/collectors/servicequotas.rb +44 -0
  59. data/lib/aws_recon/collectors/ses.rb +28 -0
  60. data/lib/aws_recon/collectors/shield.rb +67 -0
  61. data/lib/aws_recon/collectors/sns.rb +38 -0
  62. data/lib/aws_recon/collectors/sqs.rb +28 -0
  63. data/lib/aws_recon/collectors/ssm.rb +41 -0
  64. data/lib/aws_recon/collectors/support.rb +43 -0
  65. data/lib/aws_recon/collectors/transfer.rb +24 -0
  66. data/lib/aws_recon/collectors/wafv2.rb +49 -0
  67. data/lib/aws_recon/collectors/workspaces.rb +24 -0
  68. data/lib/aws_recon/collectors/xray.rb +19 -0
  69. data/lib/aws_recon/lib/formatter.rb +32 -0
  70. data/lib/aws_recon/lib/mapper.rb +69 -0
  71. data/lib/aws_recon/options.rb +141 -0
  72. data/lib/aws_recon/services.yaml +134 -0
  73. data/lib/aws_recon/version.rb +3 -0
  74. data/readme.md +226 -0
  75. data/readme_gem.md +39 -0
  76. metadata +245 -0
@@ -0,0 +1,32 @@
1
+ #
2
+ # Customize resource format/shape
3
+ #
4
+ class Formatter
5
+ #
6
+ # Custom
7
+ #
8
+ def custom(account_id, region, service, resource)
9
+ {
10
+ account: account_id,
11
+ name: resource[:arn] || "#{account_id}_#{region}_#{service.name}_#{resource[:type]}",
12
+ service: service.name,
13
+ region: region,
14
+ asset_type: resource[:type],
15
+ resource: { data: resource, version: 'v1' },
16
+ timestamp: Time.now.utc
17
+ }
18
+ end
19
+
20
+ #
21
+ # Standard AWS
22
+ #
23
+ def aws(account_id, region, service, resource)
24
+ {
25
+ account: account_id,
26
+ service: service.name,
27
+ region: region,
28
+ resource: resource,
29
+ timestamp: Time.now.utc
30
+ }
31
+ end
32
+ end
@@ -0,0 +1,69 @@
1
+ #
2
+ # Generic wrapper for service clients.
3
+ #
4
+ # Paging
5
+ # ------
6
+ # The AWS Ruby SDK has a built-in enumerator in the client response
7
+ # object that automatically handles paging large requests. Confirm
8
+ # the AWS SDK client call returns a Aws::PageableResponse to take
9
+ # advantage of automatic paging.
10
+ #
11
+ # Retries
12
+ # -------
13
+ # The AWS Ruby SDK performs retries automatically. We change the
14
+ # retry_limit to 9 (10 total requests) and the retry_backoff
15
+ # to add 5 seconds delay on each retry for a total max of 55 seconds.
16
+ #
17
+ class Mapper
18
+ def initialize(service, region, options)
19
+ @service = service
20
+ @region = region
21
+ @options = options
22
+ @thread = Parallel.worker_number || 0
23
+
24
+ # build the client interface
25
+ module_name = "Aws::#{service}::Client"
26
+
27
+ # incremental delay on retries (seconds)
28
+ retry_delay = 5
29
+
30
+ # default is 3 retries, with 15 second sleep in between
31
+ # reset to 9 retries, with incremental backoff
32
+ client_options = {
33
+ retry_mode: 'legacy', # legacy, standard, or adaptive
34
+ retry_limit: 9, # only legacy
35
+ retry_backoff: ->(context) { sleep(retry_delay * context.retries + 1) }, # only legacy
36
+ http_read_timeout: 10
37
+ }
38
+
39
+ # regional service
40
+ client_options.merge!({ region: region }) unless region == 'global'
41
+
42
+ # organizations only uses us-east-1 in non cn/gov regions
43
+ client_options.merge!({ region: 'us-east-1' }) if service.downcase == 'organizations' # rubocop:disable Layout/LineLength
44
+
45
+ # debug with wire trace
46
+ client_options.merge!({ http_wire_trace: true }) if @options.debug
47
+
48
+ @client = Object.const_get(module_name).new(client_options)
49
+ end
50
+
51
+ private
52
+
53
+ def _msg(msg)
54
+ base_msg = ["t#{@thread}", @region, @service]
55
+ base_msg.concat(msg)
56
+ end
57
+
58
+ def log(*msg)
59
+ if @options.verbose
60
+ puts _msg(msg).map { |x| "\x1b[32m#{x}\x1b[0m" }.join("\x1b[35m.\x1b[0m")
61
+ end
62
+ end
63
+
64
+ def log_error(*msg)
65
+ if @options.verbose
66
+ puts _msg(msg).map { |x| "\x1b[35m#{x}\x1b[0m" }.join("\x1b[32m.\x1b[0m")
67
+ end
68
+ end
69
+ end
@@ -0,0 +1,141 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Parser
4
+ DEFAULT_CONFIG_FILE = nil
5
+ DEFAULT_OUTPUT_FILE = File.join(File.dirname(__FILE__), '../output.json').freeze
6
+ SERVICES_CONFIG_FILE = File.join(File.dirname(__FILE__), 'services.yaml').freeze
7
+ DEFAULT_FORMAT = 'aws'
8
+ DEFAULT_THREADS = 8
9
+ MAX_THREADS = 128
10
+
11
+ Options = Struct.new(
12
+ :regions,
13
+ :services,
14
+ :config_file,
15
+ :output_file,
16
+ :output_format,
17
+ :threads,
18
+ :skip_slow,
19
+ :stream_output,
20
+ :verbose,
21
+ :debug
22
+ )
23
+
24
+ def self.parse(options)
25
+ begin
26
+ unless (options & ['-h', '--help']).any?
27
+ aws_regions = ['global'].concat(Aws::EC2::Client.new.describe_regions.regions.map(&:region_name))
28
+ end
29
+ rescue Aws::Errors::ServiceError => e
30
+ puts "\nAWS Error: #{e.code}\n\n"
31
+ exit
32
+ end
33
+
34
+ aws_services = YAML.load(File.read(SERVICES_CONFIG_FILE), symbolize_names: true)
35
+
36
+ args = Options.new(
37
+ aws_regions,
38
+ aws_services.map { |service| service[:name] },
39
+ DEFAULT_CONFIG_FILE,
40
+ DEFAULT_OUTPUT_FILE,
41
+ DEFAULT_FORMAT,
42
+ DEFAULT_THREADS,
43
+ false,
44
+ false,
45
+ false,
46
+ false
47
+ )
48
+
49
+ opt_parser = OptionParser.new do |opts|
50
+ opts.banner = "\n\x1b[32mAWS Recon\x1b[0m - AWS Inventory Collector\n\nUsage: aws_recon [options]"
51
+
52
+ # regions
53
+ opts.on('-r', '--regions [REGIONS]', 'Regions to scan, separated by comma (default: all)') do |regions|
54
+ next if regions.downcase == 'all'
55
+
56
+ args.regions = args.regions.filter { |region| regions.split(',').include?(region) }
57
+ end
58
+
59
+ # regions to skip
60
+ opts.on('-n', '--not-regions [REGIONS]', 'Regions to skip, separated by comma (default: none)') do |regions|
61
+ next if regions.downcase == 'all'
62
+
63
+ args.regions = args.regions.filter { |region| !regions.split(',').include?(region) }
64
+ end
65
+
66
+ # services
67
+ opts.on('-s', '--services [SERVICES]', 'Services to scan, separated by comma (default: all)') do |services|
68
+ next if services.downcase == 'all'
69
+
70
+ svcs = services.split(',')
71
+ args.services = aws_services.map { |service| service[:name] if svcs.include?(service[:name]) || svcs.include?(service[:alias]) }.compact # rubocop:disable Layout/LineLength
72
+ end
73
+
74
+ # services to skip
75
+ opts.on('-x', '--not-services [SERVICES]', 'Services to skip, separated by comma (default: none)') do |services|
76
+ next if services.downcase == 'all'
77
+
78
+ svcs = services.split(',')
79
+ args.services = aws_services.map { |service| service[:name] unless svcs.include?(service[:name]) || svcs.include?(service[:alias]) }.compact # rubocop:disable Layout/LineLength
80
+ end
81
+
82
+ # config file
83
+ opts.on('-c', '--config [CONFIG]', 'Specify config file for services & regions (e.g. config.yaml)') do |config|
84
+ args.config_file = config
85
+ end
86
+
87
+ # output file
88
+ opts.on('-o', '--output [OUTPUT]', 'Specify output file (default: output.json)') do |output|
89
+ args.output_file = output
90
+ end
91
+
92
+ # output format
93
+ opts.on('-f', '--format [FORMAT]', 'Specify output format (default: aws)') do |file|
94
+ if %w[aws custom].include?(file.downcase)
95
+ args.output_format = file.downcase
96
+ end
97
+ end
98
+
99
+ # threads
100
+ opts.on('-t', '--threads [THREADS]', "Specify max threads (default: #{Parser::DEFAULT_THREADS}, max: 128)") do |threads|
101
+ if (0..Parser::MAX_THREADS).include?(threads.to_i)
102
+ args.threads = threads.to_i
103
+ end
104
+ end
105
+
106
+ # skip slow operations
107
+ opts.on('-z', '--skip-slow', 'Skip slow operations (default: false)') do
108
+ args.skip_slow = true
109
+ end
110
+
111
+ # stream output (forces JSON lines, doesn't output handled warnings or errors )
112
+ opts.on('-j', '--stream-output', 'Stream JSON lines to stdout (default: false)') do
113
+ args.output_file = nil
114
+ args.verbose = false
115
+ args.debug = false
116
+ args.stream_output = true
117
+ end
118
+
119
+ # verbose
120
+ opts.on('-v', '--verbose', 'Output client progress and current operation') do
121
+ args.verbose = true unless args.stream_output
122
+ end
123
+
124
+ # debug
125
+ opts.on('-d', '--debug', 'Output debug with wire trace info') do
126
+ unless args.stream_output
127
+ args.debug = true
128
+ args.verbose = true
129
+ end
130
+ end
131
+
132
+ opts.on('-h', '--help', 'Print this help information') do
133
+ puts opts
134
+ exit
135
+ end
136
+ end
137
+
138
+ opt_parser.parse!(options)
139
+ args
140
+ end
141
+ end
@@ -0,0 +1,134 @@
1
+ ---
2
+ - name: Organizations
3
+ global: true
4
+ alias: organizations
5
+ - name: ConfigService
6
+ alias: config
7
+ - name: CodeBuild
8
+ alias: codebuild
9
+ - name: CodePipeline
10
+ alias: codepipeline
11
+ - name: AutoScaling
12
+ alias: autoscaling
13
+ - name: CloudTrail
14
+ alias: cloudtrail
15
+ - name: CloudFront
16
+ alias: cloudfront
17
+ - name: EC2
18
+ global: true
19
+ alias: ec2
20
+ - name: EC2
21
+ alias: ec2
22
+ - name: EKS
23
+ alias: eks
24
+ excluded_regions:
25
+ - us-west-1
26
+ - name: ECS
27
+ alias: ecs
28
+ - name: ElasticLoadBalancing
29
+ alias: elb
30
+ excluded_regions:
31
+ - ap-southeast-1
32
+ - name: ElasticLoadBalancingV2
33
+ alias: elbv2
34
+ excluded_regions:
35
+ - ap-southeast-1
36
+ - name: IAM
37
+ global: true
38
+ alias: iam
39
+ - name: Lambda
40
+ alias: lambda
41
+ - name: S3
42
+ global: true
43
+ alias: s3
44
+ - name: RDS
45
+ alias: rds
46
+ - name: ECR
47
+ alias: ecr
48
+ - name: DynamoDB
49
+ alias: ddb
50
+ - name: KMS
51
+ alias: kms
52
+ - name: Kinesis
53
+ alias: kinesis
54
+ - name: Redshift
55
+ alias: redshift
56
+ - name: ElasticsearchService
57
+ alias: es
58
+ - name: APIGateway
59
+ alias: apigateway
60
+ - name: ApiGatewayV2
61
+ alias: apigatewayv2
62
+ - name: Route53
63
+ alias: route53
64
+ - name: Route53Domains
65
+ global: true
66
+ alias: route53domains
67
+ - name: SQS
68
+ alias: sqs
69
+ - name: ACM
70
+ alias: acm
71
+ - name: SNS
72
+ alias: sns
73
+ - name: Shield
74
+ global: true
75
+ alias: shield
76
+ - name: CloudFormation
77
+ alias: cloudformation
78
+ - name: SES
79
+ alias: ses
80
+ excluded_regions:
81
+ - eu-north-1
82
+ - eu-west-3
83
+ - us-west-1
84
+ - name: CloudWatch
85
+ alias: cloudwatch
86
+ - name: CloudWatchLogs
87
+ alias: cloudwatchlogs
88
+ - name: Kafka
89
+ alias: kafka
90
+ - name: Support
91
+ global: true
92
+ alias: support
93
+ - name: SSM
94
+ alias: ssm
95
+ excluded_regions:
96
+ - ap-southeast-1
97
+ - name: GuardDuty
98
+ alias: guardduty
99
+ - name: Athena
100
+ alias: athena
101
+ - name: EFS
102
+ alias: efs
103
+ - name: Firehose
104
+ alias: firehose
105
+ - name: Lightsail
106
+ alias: lightsail
107
+ excluded_regions:
108
+ - eu-north-1
109
+ - us-west-1
110
+ - sa-east-1
111
+ - name: WorkSpaces
112
+ alias: workspaces
113
+ excluded_regions:
114
+ - eu-north-1
115
+ - ap-south-1
116
+ - eu-west-3
117
+ - us-east-2
118
+ - us-west-1
119
+ - name: SageMaker
120
+ alias: sagemaker
121
+ - name: ServiceQuotas
122
+ alias: servicequotas
123
+ - name: Transfer
124
+ alias: transfer
125
+ - name: DirectConnect
126
+ alias: dc
127
+ - name: DirectoryService
128
+ alias: ds
129
+ - name: DatabaseMigrationService
130
+ alias: dms
131
+ - name: XRay
132
+ alias: xray
133
+ - name: WAFV2
134
+ alias: wafv2
@@ -0,0 +1,3 @@
1
+ module AwsRecon
2
+ VERSION = "0.2.1"
3
+ end
data/readme.md ADDED
@@ -0,0 +1,226 @@
1
+ # AWS Recon
2
+
3
+ A multi-threaded AWS inventory collection tool.
4
+
5
+ The [creators](https://darkbit.io) of this tool have a recurring need to be able to efficiently collect a large amount of AWS resource attributes and metadata to help clients understand their cloud security posture.
6
+
7
+ There are a handful of tools (e.g. [AWS Config](https://aws.amazon.com/config), [CloudMapper](https://github.com/duo-labs/cloudmapper), [CloudSploit](https://github.com/cloudsploit/scans), [Prowler](https://github.com/toniblyx/prowler)) that do some form of resource collection to support other functions. But we found we needed broader coverage and more details at a per-service level. We also needed a consistent and structured format that allowed for integration with our other systems and tooling.
8
+
9
+ Enter AWS Recon, multi-threaded AWS inventory collection tool written in plain Ruby. Though most AWS tooling tends to be dominated by Python, the [Ruby SDK](https://aws.amazon.com/sdk-for-ruby/) is quite mature and capable. The maintainers of the Ruby SDK have done a fantastic job making it easy to handle automatic retries, paging of large responses, and threading huge numbers of requests.
10
+
11
+ ## Project Goals
12
+
13
+ - More complete resource coverage than available tools (especially for ECS & EKS)
14
+ - More granular resource detail, including nested related resources in the output
15
+ - Flexible output (console, JSON lines, plain JSON, file, standard out)
16
+ - Efficient (multi-threaded, rate limited, automatic retries, and automatic result paging)
17
+ - Easy to maintain and extend
18
+
19
+ ## Setup
20
+
21
+ ### Requirements
22
+
23
+ Ruby 2.5.x or 2.6.x (developed and tested with 2.6.5)
24
+
25
+ ### Installation
26
+
27
+ Clone this repository, then install the required gems using `bundle`:
28
+
29
+ ```
30
+ $ git clone git@github.com:darkbitio/aws-recon.git
31
+ $ cd aws-recon
32
+ $ bundle
33
+ ...
34
+ Using aws-sdk-core 3.103.0
35
+ ...
36
+ Bundle complete! 5 Gemfile dependencies, 259 gems now installed.
37
+ Use `bundle info [gemname]` to see where a bundled gem is installed.
38
+ ```
39
+
40
+ ## Usage
41
+
42
+ 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
+
44
+ ```
45
+ $ aws-vault exec profile -- ./recon.rb
46
+ ```
47
+
48
+ Plain environment variables will work fine too.
49
+
50
+ ```
51
+ $ AWS_PROFILE=<profile> ./recon.rb
52
+ ```
53
+
54
+ You may want to use the `-v` or `--verbose` flag initially to see status and activity while collection is running.
55
+
56
+ In verbose mode, the console output will show:
57
+
58
+ ```
59
+ <thread>.<region>.<service>.<operation>
60
+ ```
61
+
62
+ 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
+
64
+ ```
65
+ $ ./recon.rb -v
66
+
67
+ t0.global.EC2.describe_account_attributes
68
+ t2.global.S3.list_buckets
69
+ t3.global.Support.describe_trusted_advisor_checks
70
+ t2.global.S3.list_buckets.acl
71
+ t5.ap-southeast-1.WorkSpaces.describe_workspaces
72
+ t6.ap-northeast-1.Lightsail.get_instances
73
+ ...
74
+ t2.us-west-2.WorkSpaces.describe_workspaces
75
+ t1.us-east-2.Lightsail.get_instances
76
+ t4.ap-southeast-1.Firehose.list_delivery_streams
77
+ t7.ap-southeast-1.Lightsail.get_instances
78
+ t0.ap-south-1.Lightsail.get_instances
79
+ t1.us-east-2.Lightsail.get_load_balancers
80
+ t7.ap-southeast-2.WorkSpaces.describe_workspaces
81
+ t2.eu-west-3.SageMaker.list_notebook_instances
82
+ t3.eu-west-2.SageMaker.list_notebook_instances
83
+
84
+ Finished in 46 seconds. Saving resources to output.json.
85
+ ```
86
+
87
+ #### Example command line options
88
+
89
+ ```
90
+ $ AWS_PROFILE=<profile> ./recon.rb -s S3,EC2 -r global,us-east-1,us-east-2
91
+ ```
92
+
93
+ ```
94
+ $ AWS_PROFILE=<profile> ./recon.rb --services S3,EC2 --regions global,us-east-1,us-east-2
95
+ ```
96
+
97
+ #### Errors
98
+
99
+ An exception will be raised on `AccessDeniedException` errors. This typically means your user/role doesn't have the necessary permissions to get/list/describe for that service. These exceptions are raised so troubleshooting access issues is easier.
100
+
101
+ ```
102
+ Traceback (most recent call last):
103
+ arn:aws:sts::1234567890:assumed-role/role/9876543210 is not authorized to perform: codepipeline:GetPipeline on resource: arn:aws:codepipeline:us-west-2:876543210123:pipeline (Aws::CodePipeline::Errors::AccessDeniedException)
104
+ ```
105
+
106
+ The exact API operation that triggered the exception is indicated on the last line of the stack trace. If you can't resolve the necessary access, you should exclude those services with `-x` or `--not-services` so the collection can continue.
107
+
108
+ ### Threads
109
+
110
+ AWS Recon uses multiple threads to try to overcome some of the I/O challenges of performing many API calls to endpoints all over the world.
111
+
112
+ For global services like IAM, Shield, and Support, requests are not multi-threaded. The S3 module is multi-threaded since each bucket requires several additional calls to collect complete metadata.
113
+
114
+ For regional services, a thread (up to the thread limit) is spawned for each service in a region. By default, up to 8 threads will be used. If your account has resources spread across many regions, you may see a speed improvement by increasing threads with `-t X`, where `X` is the number of threads.
115
+
116
+ ### Options
117
+
118
+ 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
+
120
+ ```
121
+ $ ./recon.rb -h
122
+
123
+ AWS Recon - AWS Inventory Collector
124
+
125
+ Usage: ./recon.rb [options]
126
+ -r, --regions [REGIONS] Regions to scan, separated by comma (default: all)
127
+ -n, --not-regions [REGIONS] Regions to skip, separated by comma (default: none)
128
+ -s, --services [SERVICES] Services to scan, separated by comma (default: all)
129
+ -x, --not-services [SERVICES] Services to skip, separated by comma (default: none)
130
+ -c, --config [CONFIG] Specify config file for services & regions (e.g. config.yaml)
131
+ -o, --output [OUTPUT] Specify output file (default: output.json)
132
+ -f, --format [FORMAT] Specify output format (default: aws)
133
+ -t, --threads [THREADS] Specify max threads (default: 8, max: 128)
134
+ -z, --skip-slow Skip slow operations (default: false)
135
+ -j, --stream-output Stream JSON lines to stdout (default: false)
136
+ -v, --verbose Output client progress and current operation
137
+ -d, --debug Output debug with wire trace info
138
+ -h, --help Print this help information
139
+
140
+ ```
141
+
142
+ #### Output
143
+
144
+ Output is always some form of JSON - either JSON lines or plain JSON. The output is either written to a file (the default), or written to stdout (with `-j`).
145
+
146
+
147
+ ## Supported Services & Resources
148
+
149
+ Current "coverage" by service is listed below. The services without coverage will eventually be added. PRs are certainly welcome. :)
150
+
151
+ AWS Recon aims to collect all resources and metadata that are relevant in determining the security posture of your AWS account(s). However, it does not actually examine the resources for security posture - that is the job of other tools that take the output of AWS Recon as input.
152
+
153
+ - [x] AdvancedShield
154
+ - [x] Athena
155
+ - [x] GuardDuty
156
+ - [ ] Macie
157
+ - [x] Systems Manager
158
+ - [x] Trusted Advisor
159
+ - [x] ACM
160
+ - [x] API Gateway
161
+ - [x] AutoScaling
162
+ - [x] CodePipeline
163
+ - [x] CodeBuild
164
+ - [x] CloudFormation
165
+ - [x] CloudFront
166
+ - [x] CloudWatch
167
+ - [x] CloudWatch Logs
168
+ - [x] CloudTrail
169
+ - [x] Config
170
+ - [x] DirectoryService
171
+ - [x] DirectConnect
172
+ - [x] DMS
173
+ - [x] DynamoDB
174
+ - [x] EC2
175
+ - [x] ECR
176
+ - [x] ECS
177
+ - [x] EFS
178
+ - [x] ELB
179
+ - [x] EKS
180
+ - [x] Elasticsearch
181
+ - [x] Firehose
182
+ - [ ] FMS
183
+ - [ ] Glacier
184
+ - [x] IAM
185
+ - [x] KMS
186
+ - [x] Kafka
187
+ - [x] Kinesis
188
+ - [x] Lambda
189
+ - [x] Lightsail
190
+ - [x] Organizations
191
+ - [x] RDS
192
+ - [x] Redshift
193
+ - [x] Route53
194
+ - [x] Route53Domains
195
+ - [x] S3
196
+ - [x] SageMaker
197
+ - [x] SES
198
+ - [x] ServiceQuotas
199
+ - [x] Shield
200
+ - [x] SNS
201
+ - [x] SQS
202
+ - [x] Transfer
203
+ - [x] VPC
204
+ - [ ] WAF
205
+ - [x] WAFv2
206
+ - [x] Workspaces
207
+ - [x] Xray
208
+
209
+ ### Additional Coverage
210
+
211
+ 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
+
213
+ ### TODO
214
+
215
+ - [ ] Optionally suppress AWS API errors instead of re-raising them
216
+ - [ ] Package as a gem
217
+ - [ ] Test coverage with AWS SDK stubbed resources
218
+
219
+
220
+ ## Kudos
221
+
222
+ AWS Recon was inspired by the excellent work of the people and teams behind these tools:
223
+
224
+ - CloudMapper [https://github.com/duo-labs/cloudmapper](https://github.com/duo-labs/cloudmapper)
225
+ - Prowler [https://github.com/toniblyx/prowler](https://github.com/toniblyx/prowler)
226
+ - CloudSploit [https://github.com/cloudsploit/scans](https://github.com/cloudsploit/scans)