如何识别 AWS 中的禁用区域?
How to identify disabled regions in AWS?
AWS 会定期添加新区域。虽然 "old" 个区域在每个 AWS 账户中默认启用,但新区域默认 禁用 1.
我正在尝试使用以下 Python(伪)代码扫描所有可用区域中的特定资源:
regions = boto3_session.get_available_regions('rds')
for region in regions:
boto_rds_client = boto3_session.client('rds', region_name=region)
r_paginator = boto_rds_client.get_paginator('describe_db_instances')
for rdses in r_paginator.paginate():
for rds in rdses['DBInstances']:
do_stuff(rds)
但是,当访问 "new" 区域时,这会失败并显示一个神秘的 An error occurred (InvalidClientTokenId) when calling the DescribeDBInstances operation: The security token included in the request is invalid
。
其他服务因其他错误而失败:例如Lambda 失败 An error occurred (UnrecognizedClientException) when calling the ListFunctions operation: The security token included in the request is invalid
如何识别某个区域是否启用?似乎没有 API 调用来执行此操作...
我发现了 API 的边缘情况,可以(滥用)用于识别启用的区域:ec2:DescribeRegions API 调用(可能还有其他调用,没有) t tried) 在禁用区域中表现出略微不同的故障模式:
要么调用成功,你知道该区域已启用
调用失败并出现 UnauthorizedOperation
错误。这表明您没有 IAM 权限,但该区域已启用
调用失败 AuthFailure
。这表明该区域已禁用
以下代码成功过滤了我的测试用例中的区域:
def get_enabled_regions(boto3_session: boto3.Session, service: str) -> typing.Set[str]:
regions = boto3_session.get_available_regions(service)
enabled_regions = set()
for region in regions:
ec2_client = boto3_session.client('ec2', region_name=region)
try:
ec2_client.describe_regions()
except botocore.exceptions.ClientError as e:
if e.response['Error']['Code'] == "AuthFailure":
print(f"region {region} seems disabled, skipping")
continue # Account is disabled
elif e.response['Error']['Code'] == "UnauthorizedOperation":
print(f"region {region} seems enabled (but not sure)")
pass # Access denied is good: we have access to the region, just not to the ec2:DescribeRegions call
else:
raise
enabled_regions.add(region)
return enabled_regions
我在这个问题上做了更多工作,找到了一种较少依赖边缘情况行为的方法:使用 sts:GetCallerIdentity
调用。
这比 ec2:DescribeRegions
有几个优点,因为 API 始终启用(不能受 IAM 限制)。您可以为某个区域禁用 STS,但即便如此,GetCallerIdentity 仍然有效(仅禁用临时凭据的颁发 1)。
def get_enabled_regions(boto3_session: boto3.Session, service: str) -> typing.Set[str]:
regions = boto3_session.get_available_regions(service)
enabled_regions = set()
for region in regions:
sts_client = boto3_session.client('sts', region_name=region)
try:
sts_client.get_caller_identity()
enabled_regions.add(region)
except botocore.exceptions.ClientError as e:
if e.response['Error']['Code'] == "InvalidClientTokenId":
# error code received when region is disabled
print(f"region {region} is disabled")
pass
else:
raise
return enabled_regions
AWS 会定期添加新区域。虽然 "old" 个区域在每个 AWS 账户中默认启用,但新区域默认 禁用 1.
我正在尝试使用以下 Python(伪)代码扫描所有可用区域中的特定资源:
regions = boto3_session.get_available_regions('rds')
for region in regions:
boto_rds_client = boto3_session.client('rds', region_name=region)
r_paginator = boto_rds_client.get_paginator('describe_db_instances')
for rdses in r_paginator.paginate():
for rds in rdses['DBInstances']:
do_stuff(rds)
但是,当访问 "new" 区域时,这会失败并显示一个神秘的 An error occurred (InvalidClientTokenId) when calling the DescribeDBInstances operation: The security token included in the request is invalid
。
其他服务因其他错误而失败:例如Lambda 失败 An error occurred (UnrecognizedClientException) when calling the ListFunctions operation: The security token included in the request is invalid
如何识别某个区域是否启用?似乎没有 API 调用来执行此操作...
我发现了 API 的边缘情况,可以(滥用)用于识别启用的区域:ec2:DescribeRegions API 调用(可能还有其他调用,没有) t tried) 在禁用区域中表现出略微不同的故障模式:
要么调用成功,你知道该区域已启用
调用失败并出现
UnauthorizedOperation
错误。这表明您没有 IAM 权限,但该区域已启用调用失败
AuthFailure
。这表明该区域已禁用
以下代码成功过滤了我的测试用例中的区域:
def get_enabled_regions(boto3_session: boto3.Session, service: str) -> typing.Set[str]:
regions = boto3_session.get_available_regions(service)
enabled_regions = set()
for region in regions:
ec2_client = boto3_session.client('ec2', region_name=region)
try:
ec2_client.describe_regions()
except botocore.exceptions.ClientError as e:
if e.response['Error']['Code'] == "AuthFailure":
print(f"region {region} seems disabled, skipping")
continue # Account is disabled
elif e.response['Error']['Code'] == "UnauthorizedOperation":
print(f"region {region} seems enabled (but not sure)")
pass # Access denied is good: we have access to the region, just not to the ec2:DescribeRegions call
else:
raise
enabled_regions.add(region)
return enabled_regions
我在这个问题上做了更多工作,找到了一种较少依赖边缘情况行为的方法:使用 sts:GetCallerIdentity
调用。
这比 ec2:DescribeRegions
有几个优点,因为 API 始终启用(不能受 IAM 限制)。您可以为某个区域禁用 STS,但即便如此,GetCallerIdentity 仍然有效(仅禁用临时凭据的颁发 1)。
def get_enabled_regions(boto3_session: boto3.Session, service: str) -> typing.Set[str]:
regions = boto3_session.get_available_regions(service)
enabled_regions = set()
for region in regions:
sts_client = boto3_session.client('sts', region_name=region)
try:
sts_client.get_caller_identity()
enabled_regions.add(region)
except botocore.exceptions.ClientError as e:
if e.response['Error']['Code'] == "InvalidClientTokenId":
# error code received when region is disabled
print(f"region {region} is disabled")
pass
else:
raise
return enabled_regions