一款用 Ruby 编写的多线程 AWS 安全清单收集工具。
该工具旨在高效收集大量 AWS 资源属性与元数据。它目标是收集与 AWS 环境安全配置及状态相关的几乎所有内容。
现有工具(例如 AWS Config)虽然能执行某些资源收集,但在覆盖范围和特异性上不足以准确衡量安全状态(例如详细的资源属性数据、完整解析的策略文档以及嵌套的资源关系)。
AWS Recon 通过利用自动重试(无论是网络可靠性问题还是 API 限流)、自动分页处理大型响应(每次 API 调用超过 100 个资源)以及多线程并行请求来加速收集,从而处理大型账户的收集工作。
** 使用并不表示认可
AWS Recon 需要一个具有 ReadOnlyAccess 权限的 AWS 账户角色或凭证。完整的 AdministratorAccess 权限过高,但也可以使用。SecurityAudit 策略不足,因为它缺少对许多服务的访问权限。
使用 Docker 19.x 或更高版本运行预构建的镜像,无需安装任何东西。
如果您已安装 Ruby(2.6.x 或 2.7.x),则可能需要安装 Ruby gem。
AWS Recon 可以通过 Docker 容器本地运行,也可以通过安装 Ruby gem 运行。
要通过 Docker 容器运行,请将必要的 AWS 凭证传递给 Docker run 命令。例如:
$ docker run -t --rm \
-e AWS_REGION \
-e AWS_ACCESS_KEY_ID \
-e AWS_SECRET_ACCESS_KEY \
-e AWS_SESSION_TOKEN \
-v $(pwd)/output.json:/recon/output.json \
darkbitio/aws_recon:latest \
aws_recon -v -s EC2 -r global,us-east-1,us-east-2
要在本地运行,首先安装 gem:
$ gem install aws_recon
Fetching aws_recon-0.5.17.gem
Fetching aws-sdk-3.0.1.gem
Fetching parallel-1.20.1.gem
...
Successfully installed aws-sdk-3.0.1
Successfully installed parallel-1.20.1
Successfully installed aws_recon-0.5.17
或者使用 bundle 将其添加到 Gemfile:
$ bundle add aws_recon
Fetching gem metadata from https://rubygems.org/
Resolving dependencies...
...
Using aws-sdk 3.0.1
Using parallel-1.20.1
Using aws_recon 0.5.17
AWS Recon 将利用运行环境当前可用的任何 AWS 凭证(参见 要求)。如果您要从多个账户收集数据,可能需要使用类似 aws-vault 的工具来管理不同的凭证。
$ aws-vault exec profile -- aws_recon
普通的环境变量也可以正常工作。
$ AWS_PROFILE=<profile> aws_recon
从 Docker 容器使用 aws-vault 管理的凭证运行(输出到标准输出):
$ aws-vault exec <vault_profile> -- docker run -t --rm \
-e AWS_REGION \
-e AWS_ACCESS_KEY_ID \
-e AWS_SECRET_ACCESS_KEY \
-e AWS_SESSION_TOKEN \
darkbitio/aws_recon:latest \
aws_recon -j -s EC2 -r global,us-east-1,us-east-2
从 Docker 容器使用 aws-vault 管理的凭证并将输出写入文件,您需要满足几个要求。首先,Docker 需要能够绑定挂载您指定的路径(或其父路径)。其次,您需要创建一个空文件来保存输出(例如 output.json)。这是因为在运行时只有该文件被挂载到 Docker 容器中。例如:
创建一个空文件。
$ touch output.json
运行 aws_recon 容器,指定输出文件。
$ aws-vault exec <vault_profile> -- docker run -t --rm \
-e AWS_REGION \
-e AWS_ACCESS_KEY_ID \
-e AWS_SECRET_ACCESS_KEY \
-e AWS_SESSION_TOKEN \
-v $(pwd)/output.json:/recon/output.json \
darkbitio/aws_recon:latest \
aws_recon -s EC2 -v -r global,us-east-1,us-east-2
您可能希望最初使用 -v 或 --verbose 标志来查看收集运行时的状态和活动。
在详细模式下,控制台输出将显示:
<thread>.<region>.<service>.<operation>
t 前缀表示特定请求正在哪个线程下运行。Region、service 和 operation 指示当前正在进行的请求操作及其位置。
$ aws_recon -v
t0.global.EC2.describe_account_attributes
t2.global.S3.list_buckets
t3.global.Support.describe_trusted_advisor_checks
t2.global.S3.list_buckets.acl
t5.ap-southeast-1.WorkSpaces.describe_workspaces
t6.ap-northeast-1.Lightsail.get_instances
...
t2.us-west-2.WorkSpaces.describe_workspaces
t1.us-east-2.Lightsail.get_instances
t4.ap-southeast-1.Firehose.list_delivery_streams
t7.ap-southeast-1.Lightsail.get_instances
t0.ap-south-1.Lightsail.get_instances
t1.us-east-2.Lightsail.get_load_balancers
t7.ap-southeast-2.WorkSpaces.describe_workspaces
t2.eu-west-3.SageMaker.list_notebook_instances
t3.eu-west-2.SageMaker.list_notebook_instances
Finished in 46 seconds. Saving resources to output.json.
# 收集 S3 和 EC2 全局资源,以及 us-east-1 和 us-east-2
$ AWS_PROFILE=<profile> aws_recon -s S3,EC2 -r global,us-east-1,us-east-2
# 收集 S3 和 EC2 全局资源,以及 us-east-1 和 us-east-2
$ AWS_PROFILE=<profile> aws_recon --services S3,EC2 --regions global,us-east-1,us-east-2
# 将输出保存到 S3 存储桶
$ AWS_PROFILE=<profile> aws_recon \
--services S3,EC2 \
--regions global,us-east-1,us-east-2 \
--verbose \
--s3-bucket my-recon-bucket
# 将输出保存到 S3 存储桶,并指定非 us-east-1 的主区域
$ AWS_PROFILE=<profile> aws_recon \
--services S3,EC2 \
--regions global,us-east-1,us-east-2 \
--verbose \
--s3-bucket my-recon-bucket:us-west-2
示例 OpenCSPM 格式(NDJSON)输出。
$ AWS_PROFILE=<profile> aws_recon -l \
-s S3,EC2 \
-r global,us-east-1,us-east-2 \
-f custom
或
$ AWS_PROFILE=<profile> aws_recon -j \
-s S3,EC2 \
-r global,us-east-1,us-east-2 \
-f custom > output.json
大多数情况下,与权限相关的 API 异常会被静默忽略。这些错误通常由以下原因引起:
在 verbose 模式下,您会在输出中看到异常日志:
t2.us-east-1.EC2.describe_subnets.0
t4.us-east-1.SSM.describe_instance_information.0
t6.us-east-1.SecurityHub.InvalidAccessException <-----
t2.us-east-1.EC2.describe_addresses.0
t4.us-east-1.SSM.describe_parameters.0
t1.us-east-1.GuardDuty.list_detectors.0
使用 -q 命令行选项可以重新抛出这些异常,从而更容易排查访问问题。
Traceback (most recent call last):
arn:aws:sts::1234567890:assumed-role/role/my-audit-role is not authorized to perform:
codepipeline:GetPipeline on resource: arn:aws:codepipeline:us-west-2:1234567890:pipeline
(Aws::CodePipeline::Errors::AccessDeniedException)
堆栈跟踪的最后一行显示了触发异常的准确 API 操作。如果您无法解决必要的访问问题,应使用 -x 或 --not-services 排除这些服务,或者省略 -q 选项以便收集可以继续。
AWS Recon 使用多线程来克服向全球各地端点执行大量 API 调用时面临的 I/O 挑战。
对于全局服务(如 IAM、Shield 和 Support),请求不会多线程处理。S3 模块是多线程的,因为每个存储桶需要多次额外的调用来收集完整的元数据。
对于区域服务,每个区域的服务都会生成一个线程(不超过线程数限制)。默认情况下,最多使用 8 个线程。如果您的账户资源分布在多个区域,可以通过 -t X 增加线程数(其中 X 是线程数)来提升速度。
在新/空账户中,AWS Recon 至少会进行约 2,000 次 API 调用,以便查询所有 20 个标准(非 GovCloud、非中国)区域中支持的服务。在大型账户中,如果启用的线程数超过默认值(8),很可能遇到 API 速率限制(限流)。
Recon 会自动退避并尊重 API 响应中的重试限制。如果您在收集过程中观察到长时间停顿,很可能就是这个原因。使用 -d 或 --debug 选项重新收集以观察线路跟踪,查看是否被限流。如果您经常被限流,请考虑减少线程数或向 AWS 申请提高速率限制。
大多数用户会希望将收集范围限制在相关的服务和区域内。不进行任何排除运行将尝试收集账户中所有已启用区域的所有资源。
$ aws_recon -h
AWS Recon - AWS Inventory Collector (0.5.17)