【免费下载链接】floci
Light, fluffy, and always free - The AWS Local Emulator alternative
导读
本文围绕开源 AWS 本地模拟器 Floci 对AWS Security Hub(云安全态势管理 CSPM)的仿真实现展开,重点讲解其 REST JSON 协议的服务端点、组织级治理能力(委托管理员、Finding Aggregator、集中配置、配置策略与关联)以及标签与错误模型。读完本文,你将能够在本地开发环境中使用aws securityhubCLI 或各类 AWS SDK 完整演练 Security Hub 的启用、组织治理与配置策略生命周期,并理解 Floci 如何在本地以持久化状态模型复刻 AWS 的异步收敛行为。
服务概览与接入方式
Floci 对 AWS Security Hub 的仿真覆盖了 CSPM 的组织级与集中配置面,供本地安全治理工作流使用。该服务遵循REST JSON协议,默认端点为:
http://localhost:4566在源码中,该服务通过 ResolvedServiceCatalog.java 注册为securityhub服务,协议类型为REST_JSON,并挂载 SecurityHubController.java 作为 REST 控制器。控制器使用 Jakarta REST 注解定义路由,请求体统一以 JSON 形式消费,响应以application/json输出,这与 AWS Security Hub 的 JSON 协议形态一致。
由于服务采用 REST JSON 协议,本地接入时既可以使用官方 AWS CLI(通过自定义 endpoint 指向http://localhost:4566),也可以直接构造 HTTP 请求进行调试,适合在 CI 流水线与单元测试中嵌入安全治理相关断言。
支持的 Actions 全景
Floci 的 Security Hub 仿真面覆盖组织级管理(CSPM enablement)、委托管理员、Finding Aggregator、组织配置、配置策略、策略关联以及资源标签等七大能力域,共支持 22 个 Action:
| Action | 说明 |
|---|---|
ListOrganizationAdminAccounts | 列出组织级委托管理员账户 |
EnableOrganizationAdminAccount | 启用组织级委托管理员账户 |
DescribeHub | 查询当前账户的 Hub 状态 |
EnableSecurityHub | 为当前账户启用 Security Hub |
UpdateSecurityHubConfiguration | 更新 Security Hub 配置 |
ListFindingAggregators | 列出 Finding Aggregator |
CreateFindingAggregator | 创建 Finding Aggregator |
GetFindingAggregator | 查询指定 Finding Aggregator |
UpdateFindingAggregator | 更新 Finding Aggregator 的区域链接模式 |
DescribeOrganizationConfiguration | 查询组织级配置 |
UpdateOrganizationConfiguration | 更新组织级配置(LOCAL/CENTRAL) |
ListConfigurationPolicies | 分页列出配置策略 |
CreateConfigurationPolicy | 创建配置策略 |
GetConfigurationPolicy | 查询配置策略详情 |
UpdateConfigurationPolicy | 更新配置策略 |
GetConfigurationPolicyAssociation | 查询策略与目标的关联状态 |
StartConfigurationPolicyAssociation | 启动策略关联 |
StartConfigurationPolicyDisassociation | 启动策略解除关联 |
ListConfigurationPolicyAssociations | 分页列出策略关联 |
ListTagsForResource | 列出资源标签 |
TagResource | 为资源打标签 |
UntagResource | 移除资源标签 |
上表所列即官方文档 securityhub.md 中由floci:actions:start/floci:actions:end标记生成的受支持 Action 清单,与控制器中实际实现的路由一一对应。可以看到,仿真重点不在 finding 的写入与查询(GetFindings等数据面操作未列入),而是聚焦CSPM 的组织治理与控制面,这与文档“local security-governance workflows”的定位完全吻合。
委托管理员与组织启用
委托管理员的管理
EnableOrganizationAdminAccount支持 AWS 的SecurityHub与SecurityHubV2两种 Feature 取值。从 SecurityHubService.java 的实现看:
- 未显式指定 Feature 时默认取
SecurityHub; - 传入非法 Feature 值时返回
InvalidInputException(Feature must be SecurityHub or SecurityHubV2.); - 使用
SecurityHub旧版委托时,Floci 会在当前 Region内为委托管理员启用 Security Hub(CSPM),与 AWS 组织行为保持一致——对应代码中if ("SecurityHub".equals(requestedFeature)) { delegated.setEnabled(true); }的分支。
委托启用同时受 Organizations 服务约束(通过注入的OrganizationsService校验调用者身份与目标账户归属):
- 只有组织管理账户(management account)可以执行该操作,否则抛
InvalidAccessException; AdminAccountId必须是 12 位数字账户 ID,且必须属于调用者所在的 AWS 组织;- 若已存在不同的委托管理员账户,重复启用会返回
ResourceConflictException(A different Security Hub administrator account is already configured.)。
列出委托管理员
ListOrganizationAdminAccounts的响应中,只有当当前委托账户的 Feature 与请求的Feature查询参数匹配时,才会在AdminAccounts数组里返回该账户(状态为ENABLED)。该接口还实现了 AWS 的分页约束:MaxResults必须介于 1 与 10 之间,超出即返回InvalidInputException;NextToken在本地仿真中不支持,非空即报错。
Hub 启用与配置更新
启用与查询
EnableSecurityHub为当前账户在当前 Region启用 Security Hub;重复启用会收到ResourceConflictException。DescribeHub在 Hub 未启用时返回ResourceNotFoundException(Security Hub is not enabled for this account.),启用后返回:
HubArn:形如arn:aws:securityhub:{region}:{accountId}:hub/default;AutoEnableControls:默认true;ControlFindingGenerator:默认SECURITY_CONTROL,允许取值为SECURITY_CONTROL或STANDARD_CONTROL。
这些默认值定义在状态模型 SecurityHubState.java 中:autoEnableControls默认true、controlFindingGenerator默认SECURITY_CONTROL。
更新配置
UpdateSecurityHubConfiguration支持修改AutoEnableControls(必须为布尔值)与ControlFindingGenerator(枚举取值校验同上),更新前同样要求 Hub 已启用。从源码看,该接口只允许增量更新,未提交的字段保持原值。
Finding Aggregator:区域链接模式
Finding Aggregator 用于将组织内各区域、各成员账户的 finding 汇聚到聚合区域。Floci 支持四种RegionLinkingMode,与 AWS 完全对齐:
| RegionLinkingMode | 说明 | Regions 约束 |
|---|---|---|
ALL_REGIONS | 链接所有区域 | Regions 必须为空 |
ALL_REGIONS_EXCEPT_SPECIFIED | 链接除指定区域外的所有区域 | 允许指定排除列表 |
SPECIFIED_REGIONS | 仅链接指定区域 | Regions 必填且非空 |
NO_REGIONS | 不链接任何区域 | Regions 必须为空 |
模式校验逻辑位于validateAggregatorRegions(SecurityHubService.java):SPECIFIED_REGIONS强制要求 Regions 数组非空,而ALL_REGIONS/NO_REGIONS下 Regions 必须为空,且数组中每个元素都必须是合法的非空白区域标识符。
创建成功后 Floci 会生成形如arn:aws:securityhub:{region}:{accountId}:finding-aggregator/{uuid}的 ARN 并持久化。账户级限制是:每个账户只允许存在一个 Finding Aggregator,重复创建返回LimitExceededException(HTTP 429)。GetFindingAggregator采用贪婪路径匹配(/findingAggregator/get/{findingAggregatorArn: .+}),可接受完整的 finding-aggregator ARN,且必须与本地持久化的 ARN 精确一致,否则返回ResourceNotFoundException。UpdateFindingAggregator允许切换区域链接模式与区域列表,同样会校验 ARN 与新模式。
ListFindingAggregators支持分页,MaxResults上限为 100,超出即返回InvalidInputException。
组织配置:LOCAL 与 CENTRAL 的异步收敛模型
DescribeOrganizationConfiguration/UpdateOrganizationConfiguration负责组织级安全配置,Floci 在本地建模了 AWS 的异步收敛语义。
状态机
状态模型(SecurityHubState.java)中组织配置的默认值为ConfigurationType = LOCAL、Status = ENABLED。UpdateOrganizationConfiguration的核心行为如下(SecurityHubService.java):
- 请求必须携带布尔型的
AutoEnable,可选的AutoEnableStandards仅允许DEFAULT或NONE; OrganizationConfiguration.ConfigurationType仅允许CENTRAL或LOCAL,未指定时保留当前值,默认LOCAL;- 切换为
CENTRAL:立即将AutoEnable强制置为false、AutoEnableStandards强制置为NONE,同时把组织配置状态置为PENDING并设置一次待收敛轮询(pendingPollsRemaining = 1); - 切换为
LOCAL:直接应用请求中的AutoEnable/AutoEnableStandards,状态置为ENABLED。
轮询收敛
organizationConfiguration(对应DescribeOrganizationConfiguration)实现了收敛逻辑:
- 首次查询(状态为
PENDING且剩余轮询数大于 0):返回仍为 PENDING的快照,同时剩余轮询数减一; - 再次查询:剩余轮询数为 0,状态转为
ENABLED并持久化。
因此在本地工作流中,切换到 CENTRAL 后第一次DescribeOrganizationConfiguration会看到Status: PENDING,第二次轮询后收敛为ENABLED——这一“先 PENDING、再 ENABLED”的行为与文档描述完全一致。此外,该接口还会返回固定的MemberAccountLimitReached: false。
需要注意的是,组织配置类接口(Describe/UpdateOrganizationConfiguration、配置策略与关联的全部接口)都要求调用者是已启用的委托 Security Hub 管理员,否则返回InvalidAccessException(HTTP 401),对应requireAdministrator方法(SecurityHubService.java)。
配置策略(Configuration Policy)与关联生命周期
策略的 CRUD
配置策略是集中配置模式(CENTRAL)的核心载体。Floci 支持创建、查询、更新与分页列出:
CreateConfigurationPolicy:Name必填(最长 128 字符、不能为空白),同名策略返回ResourceConflictException;ConfigurationPolicy必须恰好包含一个SecurityHub子对象,其内部字段包括:ServiceEnabled:布尔值,控制目标账户的启用状态;EnabledStandardIdentifiers:字符串数组,元素必须非空;SecurityControlsConfiguration:对象类型。
- 创建成功后生成 UUID 作为策略 ID,并写入
CreatedAt/UpdatedAt时间戳;策略 ARN 形如arn:aws:securityhub:{region}:{accountId}:configuration-policy/{id}。 GetConfigurationPolicy与UpdateConfigurationPolicy的路径均为贪婪匹配(/configurationPolicy/get/{id: .+}与/configurationPolicy/{id: .+}),因此既可以直接传策略 ID,也可以传完整 ARN(normalizePolicyId会取最后一个/之后的片段)。ListConfigurationPolicies返回ConfigurationPolicySummaries数组(含 Arn、Id、Name、Description、ServiceEnabled、UpdatedAt),分页上限MaxResults为 100。
关联与解除关联
策略需要绑定到组织目标上才会生效,目标支持三类:
| Target 字段 | TargetType | 格式约束 |
|---|---|---|
AccountId | ACCOUNT | 12 位数字 |
OrganizationalUnitId | ORGANIZATIONAL_UNIT | ou-前缀 + 4~32 位小写字母数字 +-+ 8~32 位小写字母数字 |
RootId | ROOT | r-前缀 + 4~32 位小写字母数字 |
Target对象必须恰好包含上述一个标识符,且目标必须与调用者同属一个 AWS 组织。特殊值SELF_MANAGED_SECURITY_HUB可作为ConfigurationPolicyIdentifier,表示“自管理”语义(不应用任何策略)。
关联生命周期同样模拟 AWS 的异步收敛(见associate/association方法):
StartConfigurationPolicyAssociation:创建关联记录,状态为PENDING,设置 1 次待收敛轮询;若目标已关联同一策略,返回ResourceConflictException;- 第一次
GetConfigurationPolicyAssociation:返回PENDING,轮询计数减一; - 第二次查询:状态转为
SUCCESS,并将策略的ServiceEnabled实际应用到目标账户的 Hub 状态(applyPolicyToAccountTarget,仅对ACCOUNT目标且非自管理策略生效)。
StartConfigurationPolicyDisassociation把关联置为PENDING并标记为正在解除(disassociating = true);之后第一次查询仍返回PENDING,第二次查询时该关联记录被移除并返回ResourceNotFoundException,对应文档所述“Disassociation is represented as a pending transition before the association disappears”。
ListConfigurationPolicyAssociations支持按ConfigurationPolicyId、AssociationType(仅APPLIED/INHERITED,当前仿真只产出APPLIED)和AssociationStatus(PENDING/SUCCESS/FAILED)过滤,分页上限 100。响应中的AssociationStatusMessage仅在存在时返回,AssociationType固定为APPLIED。
资源标签:共享 Tagging 路由与 AWS 约束
配置策略与 Hub 的标签通过共享的 Security Hub 标签路由持久化并返回,控制器实现了ListTagsForResource、TagResource、UntagResource,底层委托给 SecurityHubTagHandler.java(serviceKey = "securityhub",走 REST/tags/{ResourceArn}路径,成功状态码为 200,并开启严格标签校验strictTagValidation = true)。
标签语义要点(SecurityHubService.java):
- 标签对象最多50个条目;
- 键最长 128 字符,值最长 256 字符;
- 键必须匹配
[a-zA-Z+\-=._:/]+; - 禁止
aws:前缀(保留前缀限制),违反任一约束即返回InvalidInputException(Tags contain an invalid key or value.); - 可打标签的资源包括 Hub ARN 与配置策略 ARN,资源 ARN 必须属于当前 Region 与账户;Hub 未启用时对 Hub ARN 的打标签/查询返回
ResourceNotFoundException; - 标签写入会持久化到本地状态,
ListTagsForResource返回 Map 形式(仅保留字符串值)。
对应测试 SecurityHubServiceTest.java 中enableSecurityHubPersistsConfigurationAndHubTags与invalidReservedTagPrefixIsRejected分别验证了标签持久化与aws:保留前缀的拒绝逻辑。
AWS 兼容的错误模型
Floci 在本地对 Security Hub 的输入做了系统性校验,涵盖:管理员账户 ID 与 Feature、Finding Aggregator 模式与区域列表、集中配置输入、策略名称与文档、目标标识符、标签以及关联状态。校验失败时使用与 AWS 一致的确定性错误类型:
| 错误类型 | HTTP 状态 | 典型触发场景 |
|---|---|---|
InvalidInputException | 400 | 非法 Feature、非法 RegionLinkingMode、非法标签、分页参数越界、策略文档结构错误等 |
InvalidAccessException | 401 | 非组织管理账户执行委托操作、非委托管理员操作集中配置 |
ResourceNotFoundException | 404 | Hub 未启用、策略/关联/聚合器不存在、资源 ARN 不匹配 |
ResourceConflictException | 409 | Hub 重复启用、委托管理员冲突、同名策略、目标已关联同一策略 |
LimitExceededException | 429 | 每账户仅允许一个 Finding Aggregator |
这些错误通过 SecurityHubService.java 中的invalid/invalidAccess/conflict/notFound辅助方法统一构造,与控制器中的分页校验(PaginatedResult/Pagination工具)共同形成完整的输入验证面。
需要特别说明的是:AWS 还定义了服务端侧的InternalException与限流(rate-limit)失败,Floci 不会在缺少请求或本地状态条件的情况下主动注入这些失败——也就是说,本地仿真只复现可由请求输入触发的确定性错误,不会随机制造 5xx 或节流,从而保证测试的可复现性。
配置项
Security Hub 仿真可通过环境变量开关控制,配置项定义于 EmulatorConfig.java 的SecurityHubServiceConfig:
| 变量 | 默认值 | 说明 |
|---|---|---|
FLOCI_SERVICES_SECURITYHUB_ENABLED | true | 启用或禁用 AWS Security Hub CSPM 仿真 |
将该变量设为false时,服务将不会在本地端点注册(见 ResolvedServiceCatalog.java 中config.services().securityhub().enabled()的条件注册逻辑),适合在多服务环境下按需裁剪启动面。
状态持久化与测试验证
从实现架构看,Floci 的 Security Hub 仿真属于有状态服务:所有配置(Hub 启用状态、委托管理员、聚合器、组织配置、策略、关联、标签)都通过StorageFactory以账户感知的存储后端持久化(存储键securityhub、文件securityhub-state.json,见 SecurityHubService.java),并且实现了Resettable.clear(),可在测试间重置状态。
服务测试覆盖了核心行为:
- SecurityHubServiceTest.java:Hub 启用与配置/标签持久化、
aws:保留前缀拒绝、非法 Feature 拒绝、状态重置; - SecurityHubOrganizationIntegrationTest.java:组织级委托、集中配置与关联的端到端集成验证。
对于本地安全治理工作流的开发者而言,这意味着你可以放心地在测试套件中执行“启用 → 委托 → 聚合 → 集中配置 → 策略关联 → 轮询收敛 → 解除关联”的完整链路,每次运行都得到确定性的结果。
本地演练建议
- 以
FLOCI_SERVICES_SECURITYHUB_ENABLED=true启动 Floci,并将 AWS CLI/SDK 的 endpoint 指向http://localhost:4566; - 依次执行
aws securityhub enable-security-hub、describe-hub验证基础面; - 通过 Organizations 服务建立管理账户/成员账户关系后,演练
enable-organization-admin-account与list-organization-admin-accounts; - 创建 Finding Aggregator 并测试四种
RegionLinkingMode的输入校验; - 将组织配置切换到
CENTRAL,按“先 PENDING、再 ENABLED”的节奏轮询describe-organization-configuration,观察收敛行为; - 创建配置策略并关联到账户/OU/Root 目标,验证
PENDING → SUCCESS收敛与解除关联后关联消失; - 最后验证标签约束(
aws:前缀拒绝)与各错误类型的确定性返回。
通过以上步骤,即可在本地完整复现 AWS Security Hub CSPM 的组织治理控制面,为安全自动化脚本与 CI 流水线提供无需真实 AWS 账号的可重复测试环境。
【免费下载链接】floci
Light, fluffy, and always free - The AWS Local Emulator alternative
相关推荐
在 Floci 本地模拟器中实战 AWS Organizations:组织、账户、策略与邀请全流程指南
在 Floci 本地模拟器中实战 AWS Organizations:组织、账户、策略与邀请全流程指南 本篇指南围绕 Floci(轻量级 AWS 本地模拟器,
Floci AWS CLI 与 SDK 接入指南:零真实账户的本地 AWS 开发环境配置
Floci AWS CLI 与 SDK 接入指南:零真实账户的本地 AWS 开发环境配置 Floci 是一款免费开源的 AWS 本地模拟器,其设计目标之一就是让
Floci 本地模拟 Amazon Inspector:委托管理员、账户启用与组织自动开启配置实战指南
Floci 本地模拟 Amazon Inspector:委托管理员、账户启用与组织自动开启配置实战指南 Floci 作为一款轻量级、免费的 AWS 本地模拟器,
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考