Skip to content

Commit

Permalink
Merge pull request #157 from Cloud-Architects/develop
Browse files Browse the repository at this point in the history
v 2.2.4
  • Loading branch information
meshuga committed Oct 15, 2020
2 parents 1f155d6 + bc8c4f4 commit 2777a6b
Show file tree
Hide file tree
Showing 25 changed files with 1,022 additions and 392 deletions.
101 changes: 18 additions & 83 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,12 @@ cloudiscovery aws-all --region-name xx-xxxx-xxx [--profile-name profile] [--serv
cloudiscovery aws-limit --region-name xx-xxxx-xxx [--profile-name profile] [--services xxx,xxx] [--usage 0-100] [--verbose]
```
1.6 To run AWS security controls (experimental feature):
```sh
cloudiscovery aws-security --region-name xx-xxxx-xxx [--profile-name profile] [--commands x] [--verbose]
```
2. For help use:
```sh
Expand Down Expand Up @@ -113,89 +119,10 @@ More on credentials configuration: [Configuration basics](https://docs.aws.amazo
#### AWS Permissions
The configured credentials must be associated to a user or role with proper permissions to do all checks. If you want to use a role with narrowed set of permissions just to perform cloud discovery, use a role from the following CF template shown below. To further increase security, you can add a block to check `aws:MultiFactorAuthPresent` condition in `AssumeRolePolicyDocument`. More on using IAM roles in the [configuration file](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-role.html).
```json
{
"AWSTemplateFormatVersion": "2010-09-09",
"Description": "Setups a role for diagram builder for all resources within an account",
"Resources": {
"cloudiscoveryRole": {
"Type": "AWS::IAM::Role",
"Properties": {
"AssumeRolePolicyDocument" : {
"Statement" : [
{
"Effect" : "Allow",
"Principal" : {
"AWS": { "Fn::Join" : [ "", [
"arn:aws:iam::", { "Ref" : "AWS::AccountId" }, ":root"
]]}
},
"Action" : [ "sts:AssumeRole" ]
}
]
},
"Policies": [{
"PolicyName": "additional-permissions",
"PolicyDocument": {
"Version": "2012-10-17",
"Statement" : [
{
"Effect" : "Allow",
"Action" : [
"kafka:ListClusters",
"synthetics:DescribeCanaries",
"medialive:ListInputs",
"cloudhsm:DescribeClusters",
"ssm:GetParametersByPath",
"servicequotas:Get*",
"amplify:ListApps",
"autoscaling-plans:DescribeScalingPlans",
"medialive:ListChannels",
"medialive:ListInputDevices",
"mediapackage:ListChannels",
"qldb:ListLedgers",
"transcribe:ListVocabularies",
"glue:GetDatabases",
"glue:GetUserDefinedFunctions",
"glue:GetSecurityConfigurations",
"glue:GetTriggers",
"glue:GetCrawlers",
"glue:ListWorkflows",
"glue:ListMLTransforms",
"codeguru-reviewer:ListCodeReviews",
"servicediscovery:ListNamespaces",
"apigateway:GET",
"forecast:ListPredictors",
"frauddetector:GetDetectors",
"forecast:ListDatasetImportJobs",
"frauddetector:GetModels",
"frauddetector:GetOutcomes",
"networkmanager:DescribeGlobalNetworks",
"codeartifact:ListDomains",
"ses:GetSendQuota"
],
"Resource": [ "*" ]
}
]
}
}],
"Path" : "/",
"ManagedPolicyArns" : [
"arn:aws:iam::aws:policy/job-function/ViewOnlyAccess",
"arn:aws:iam::aws:policy/SecurityAudit"
]
}
}
},
"Outputs" : {
"cloudiscoveryRoleArn" : {
"Value" : { "Fn::GetAtt": [ "cloudiscoveryRole", "Arn" ]}
}
}
}
```
The configured credentials must be associated to a user or role with proper permissions to do all checks. If you want to use a role with narrowed set of permissions just to perform cloud discovery, use a role from the following the [CF template maintained by our team](docs/assets/role-template.json).
To further increase security, you can add a block to check `aws:MultiFactorAuthPresent` condition in `AssumeRolePolicyDocument`. More on using IAM roles in the [configuration file](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-role.html).
(Optional) If you want to be able to switch between multiple AWS credentials and settings, you can configure [named profiles](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-profiles.html) and later pass profile name when running the tool.
Expand Down Expand Up @@ -379,6 +306,14 @@ An administrator can ask to increase the quota value of a certain service via ti
More information: [AWS WA, REL 1 How do you manage service limits?](https://wa.aws.amazon.com/wat.question.REL_1.en.html)
### AWS Security
This features is experimental, but now you can run commands to check and analyze some security issues. The following commands are available now:
* Access key age
* EBS Encryption enabled
* EC2 IMDSV2 Check
* DynamoDB PITR Enabled
## Using a Docker container
To build docker container using Dockerfile
Expand Down
23 changes: 22 additions & 1 deletion cloudiscovery/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
from provider.iot.command import Iot
from provider.all.command import All
from provider.limit.command import Limit
from provider.security.command import Security

from shared.common import (
exit_critical,
Expand All @@ -46,7 +47,7 @@
print("Python 3.6 or newer is required", file=sys.stderr)
sys.exit(1)

__version__ = "2.2.3"
__version__ = "2.2.4"

AVAILABLE_LANGUAGES = ["en_US", "pt_BR"]
DEFAULT_REGION = "us-east-1"
Expand Down Expand Up @@ -107,6 +108,20 @@ def generate_parser():
For example: --threshold 50 will report all resources with more than 50%% threshold.",
)

security_parser = subparsers.add_parser(
"aws-security", help="Analyze aws several security checks."
)
add_default_arguments(security_parser, diagram_enabled=False, filters_enabled=False)
security_parser.add_argument(
"-c",
"--commands",
action="append",
required=False,
help='Select the security check command that you want to run. \
To see available commands, please type "-c list". \
If not passed, command will check all services.',
)

return parser


Expand Down Expand Up @@ -262,12 +277,18 @@ def main():
command = Limit(
region_names=region_names, session=session, threshold=args.threshold,
)
elif args.command == "aws-security":
command = Security(
region_names=region_names, session=session, commands=args.commands,
)
else:
raise NotImplementedError("Unknown command")

if "services" in args and args.services is not None:
services = args.services.split(",")
else:
services = []

command.run(diagram, args.verbose, services, filters)


Expand Down
2 changes: 1 addition & 1 deletion cloudiscovery/provider/all/command.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ def run(
services=services,
)

command_runner = AwsCommandRunner(filters)
command_runner = AwsCommandRunner(filters=filters)
command_runner.run(
provider="all",
options=options,
Expand Down
Empty file.
102 changes: 102 additions & 0 deletions cloudiscovery/provider/all/data/omitted_resources.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
OMITTED_RESOURCES = [
"aws_cloudhsm_available_zone",
"aws_cloudhsm_hapg",
"aws_cloudhsm_hsm",
"aws_cloudhsm_luna_client",
"aws_dax_default_parameter",
"aws_dax_parameter_group",
"aws_ec2_reserved_instances_offering",
"aws_ec2_snapshot",
"aws_ec2_spot_price_history",
"aws_ssm_available_patch",
"aws_ssm_document",
"aws_polly_voice",
"aws_lightsail_blueprint",
"aws_lightsail_bundle",
"aws_lightsail_region",
"aws_elastictranscoder_preset",
"aws_ec2_vpc_endpoint_service",
"aws_dms_endpoint_type",
"aws_elasticache_service_update",
"aws_elasticache_cache_parameter_group",
"aws_rds_source_region",
"aws_ssm_association",
"aws_ssm_patch_baseline",
"aws_ec2_prefix",
"aws_ec2_image",
"aws_ec2_region",
"aws_opsworks_operating_system",
"aws_rds_account_attribute",
"aws_route53_geo_location",
"aws_redshift_cluster_track",
"aws_redshift_reserved_node_offering",
"aws_directconnect_location",
"aws_dms_account_attribute",
"aws_securityhub_standard",
"aws_ram_resource_type",
"aws_ram_permission",
"aws_ec2_account_attribute",
"aws_elasticbeanstalk_available_solution_stack",
"aws_redshift_account_attribute",
"aws_opsworks_user_profile",
"aws_directconnect_direct_connect_gateway_association", # DirectConnect resources endpoint are complicated
"aws_directconnect_direct_connect_gateway_attachment",
"aws_directconnect_interconnect",
"aws_dms_replication_task_assessment_result",
"aws_ec2_fpga_image",
"aws_ec2_launch_template_version",
"aws_ec2_reserved_instancesing",
"aws_ec2_spot_datafeed_subscription",
"aws_ec2_transit_gateway_multicast_domain",
"aws_elasticbeanstalk_configuration_option",
"aws_elasticbeanstalk_platform_version",
"aws_iam_credential_report",
"aws_iam_account_password_policy",
"aws_importexport_job",
"aws_iot_o_taupdate",
"aws_iot_default_authorizer",
"aws_workspaces_account",
"aws_workspaces_account_modification",
"aws_rds_export_task",
"aws_rds_custom_availability_zone",
"aws_rds_installation_media",
"aws_rds_d_bsecurity_group",
"aws_rds_reserved_db_instances_offering",
"aws_translate_text_translation_job",
"aws_rekognition_project",
"aws_rekognition_stream_processor",
"aws_sdb_domain",
"aws_redshift_table_restore_status",
"aws_iot_v2_logging_level",
"aws_license_manager_resource_inventory",
"aws_license_manager_license_configuration",
"aws_logs_query_definition",
"aws_autoscaling_scaling_activity",
"aws_autoscaling_auto_scaling_notification_type",
"aws_autoscaling_scaling_process_type",
"aws_autoscaling_termination_policy_type",
"aws_ec2_host_reservation_offering",
"aws_ec2_availability_zone",
"aws_cloudwatch_metric",
"aws_organizations_handshakes_for_organization",
"aws_config_organization_config_rule",
"aws_organizations_root",
"aws_organizations_delegated_administrator",
"aws_organizations_create_account_status",
"aws_config_organization_conformance_pack_status",
"aws_config_organization_conformance_pack",
"aws_ec2_reserved_instances_listing",
"aws_redshift_cluster_security_group",
"aws_guardduty_organization_admin_account",
"aws_elasticache_cache_security_group",
"aws_elasticache_reserved_cache_nodes_offering",
"aws_organizations_aws_service_access_for_organization",
"aws_organizations_account",
"aws_config_organization_config_rule_status",
"aws_dynamodb_backup",
"aws_ec2_prefix_list",
"aws_route53_hosted_zones_by_name",
"aws_es_reserved_elasticsearch_instance_offering",
"aws_ssm_automation_execution",
"aws_route53_checker_ip_range",
]
34 changes: 34 additions & 0 deletions cloudiscovery/provider/all/data/on_top_policies.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
ON_TOP_POLICIES = [
"kafka:ListClusters",
"synthetics:DescribeCanaries",
"medialive:ListInputs",
"cloudhsm:DescribeClusters",
"ssm:GetParametersByPath",
"servicequotas:Get*",
"amplify:ListApps",
"autoscaling-plans:DescribeScalingPlans",
"medialive:ListChannels",
"medialive:ListInputDevices",
"mediapackage:ListChannels",
"qldb:ListLedgers",
"transcribe:ListVocabularies",
"glue:GetDatabases",
"glue:GetUserDefinedFunctions",
"glue:GetSecurityConfigurations",
"glue:GetTriggers",
"glue:GetCrawlers",
"glue:ListWorkflows",
"glue:ListMLTransforms",
"codeguru-reviewer:ListCodeReviews",
"servicediscovery:ListNamespaces",
"apigateway:GET",
"forecast:ListPredictors",
"frauddetector:GetDetectors",
"forecast:ListDatasetImportJobs",
"frauddetector:GetModels",
"frauddetector:GetOutcomes",
"networkmanager:DescribeGlobalNetworks",
"codeartifact:ListDomains",
"ses:GetSendQuota",
"codeguru-profiler:ListProfilingGroups",
]
65 changes: 65 additions & 0 deletions cloudiscovery/provider/all/data/required_params_override.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
# Trying to fix documentation errors or its lack made by "happy pirates" at AWS
REQUIRED_PARAMS_OVERRIDE = {
"batch": {"ListJobs": ["jobQueue"]},
"cloudformation": {
"DescribeStackEvents": ["stackName"],
"DescribeStackResources": ["stackName"],
"GetTemplate": ["stackName"],
"ListTypeVersions": ["arn"],
},
"codecommit": {"GetBranch": ["repositoryName"]},
"codedeploy": {
"GetDeploymentTarget": ["deploymentId"],
"ListDeploymentTargets": ["deploymentId"],
},
"ecs": {
"ListTasks": ["cluster"],
"ListServices": ["cluster"],
"ListContainerInstances": ["cluster"],
"DescribeTasks": ["cluster", "tasks"],
"DescribeServices": ["cluster", "services"],
"DescribeContainerInstances": ["cluster", "containerInstances"],
},
"elasticbeanstalk": {
"DescribeEnvironmentHealth": ["environmentName"],
"DescribeEnvironmentManagedActionHistory": ["environmentName"],
"DescribeEnvironmentManagedActions": ["environmentName"],
"DescribeEnvironmentResources": ["environmentName"],
"DescribeInstancesHealth": ["environmentName"],
},
"iam": {
"GetUser": ["userName"],
"ListAccessKeys": ["userName"],
"ListServiceSpecificCredentials": ["userName"],
"ListSigningCertificates": ["userName"],
"ListMFADevices": ["userName"],
"ListSSHPublicKeys": ["userName"],
},
"iot": {"ListAuditFindings": ["taskId"]},
"opsworks": {
"ListAuditFindings": ["taskId"],
"DescribeAgentVersions": ["stackId"],
"DescribeApps": ["stackId"],
"DescribeCommands": ["deploymentId"],
"DescribeDeployments": ["appId"],
"DescribeEcsClusters": ["ecsClusterArns"],
"DescribeElasticIps": ["stackId"],
"DescribeElasticLoadBalancers": ["stackId"],
"DescribeInstances": ["stackId"],
"DescribeLayers": ["stackId"],
"DescribePermissions": ["stackId"],
"DescribeRaidArrays": ["stackId"],
"DescribeVolumes": ["stackId"],
},
"ssm": {"DescribeMaintenanceWindowSchedule": ["windowId"],},
"shield": {"DescribeProtection": ["protectionId"],},
"waf": {
"ListActivatedRulesInRuleGroup": ["ruleGroupId"],
"ListLoggingConfigurations": ["limit"],
},
"waf-regional": {
"ListActivatedRulesInRuleGroup": ["ruleGroupId"],
"ListLoggingConfigurations": ["limit"],
},
"wafv2": {"ListLoggingConfigurations": ["limit"],},
}
Loading

0 comments on commit 2777a6b

Please sign in to comment.