Ver código fonte

Starting to take shape

Gogs 5 anos atrás
commit
0b0de6c8be
11 arquivos alterados com 310 adições e 0 exclusões
  1. 70 0
      Architecture.md
  2. 0 0
      Developer.md
  3. 36 0
      README.md
  4. 7 0
      TODO.md
  5. 15 0
      bootstrap/s3.terraform-state.tf
  6. 21 0
      sample/README.md
  7. 8 0
      sample/backend.tf
  8. 26 0
      sample/cloudwatch.tf
  9. 6 0
      sample/provider.tf
  10. 92 0
      sample/sns.tf
  11. 29 0
      sample/sqs.tf

+ 70 - 0
Architecture.md

@@ -0,0 +1,70 @@
+## Architecture
+```
+Input->SNS->(1 or more) SQS->Analysis Function->Reporting SNS->(1 or more) Reporting SQS->Reporting Function
+                                              |
+                                              +->Remediation SQS->Remediation Function->Reporting SNS->(1 or more) Reporting SQS->Reporting Function
+```
+
+### Inputs
+Inputs put things in motion.
+
+Naming Convention: None
+
+Features:
+  * CloudWatch Events Rules
+    * Can be API calls or responses to AWS Config
+  * "Custom" entry (Message sent to SNS topic), such as a request to scan for an issue.
+
+### SNS Distribution
+There are SNS Topics to distribute from the inputs:
+
+Naming Convention: `fcm-input-[eventName]` or `fcm-input-custom-[typename]`
+
+Features:
+  * For each API eventName, named `fcm-input-[eventName]`
+  * For each custom type, named `fcm-input-custom-[typename]`
+
+### SQS Queues for Analysis:
+SQS queues allow a many-to-one relationship between analysis functions and inputs. A single event/input can fan out to multiple functions.
+
+Naming Convention: `fcm-analysis-[functionname]`.
+
+Function Name:
+  * Each analysis function, there is an sqs queue named `fcm-analysis-[functionname]`.
+  * This SQS queue can be subscribed to one or more SNS topic. It is up to the function to determine what it is able to process.
+
+### Analysis Functions:
+Provide a read-only analysis of the input event.
+
+Naming convention: `fcm-analysis-[functionname]`
+
+  * Lambda functions process the analysis SQS queues.
+  * As output, they report result of analysis to the Reporting SNS Topic.
+  * If remediation is warranted and possible, send entry to appropriate Remediation SQS Topic.
+
+### SQS Queues for Remediation
+Provide a queue for remediation, if applicable.
+
+Naming Convention: `fcm-remediation-[functionname]`
+
+  * Lambda function to process output from analysis function and remediate.
+  * Report output to Reporting SNS Topic.
+
+### Reporting SNS Topic
+Allows fanout of the reporting, or direct subscription based reporting.
+
+Naming Convention: `fcm-reporting`
+
+### Reporter SQS Queue
+One or more queues, subscribed to the reporting SNS topic. Each queue goes to an individual reporter function.
+
+Naming Convention: `fcm-reporting-[functionname]`
+
+### Reporter Function
+A function that formats and records the results.
+
+Naming Convention: `fcm-reporting-[functionname]`
+
+
+
+

+ 0 - 0
Developer.md


+ 36 - 0
README.md

@@ -0,0 +1,36 @@
+# Fred's Cloud Monitor (FCM)
+
+Provides a set of enforced guardrails to AWS configuration changes.
+
+## Goals
+* Widely decoupled design.
+* Serverless.
+* Receive input events from cloudtrail, AWS config, or manual sources.
+* Provide standard libraries to easily add additional functionality.
+* Encryption throughout
+* Simple configuration through command-line files.
+
+## Principal #1
+The _right_ way to protect your assets is to prevent them in the first place. While FCM provides automated remediation for a variety of possible misconfigurations, the better way to handle things is to prevent them in the first place through appropriate IAM policies. 
+
+FCM is _reactive_, which is always a worse solution than proactive prevention. That said, FCM can find and fix security issues that may have slipped through the cracks.
+
+## Dependencies
+Requires python3 and terraform.
+
+## Bootstrapping
+To get started, terraform needs a centralized S3 bucket to store its state. This allows you to store FCM in git and allow updates from multiple individuals on their own workstations.
+
+1. Ensure you have valid credentials for AWS in one of the API's supported methods.
+1. Edit `bootstrap/s3.terraform-state.tf` and set your preferred region and a unique bucket name.
+1. Run the following to initialize a new S3 bucket in your account.
+
+```
+cd bootstrap
+terraform init
+terraform apply
+```
+
+## Sample
+Review the files in `sample/` for an example of what a generated function from event to remediation might look like.
+

+ 7 - 0
TODO.md

@@ -0,0 +1,7 @@
+# SNS
+* Allow use of custom key
+
+# SQS
+* Allow use of custom key
+
+

+ 15 - 0
bootstrap/s3.terraform-state.tf

@@ -0,0 +1,15 @@
+provider "aws" {
+  region = "us-east-2"
+}
+
+resource "aws_s3_bucket" "fcm_terraform_state" {
+  bucket = "fcm-terraform-state"
+
+  versioning {
+    enabled = true
+  }
+
+  lifecycle {
+    prevent_destroy = true
+  }
+}

+ 21 - 0
sample/README.md

@@ -0,0 +1,21 @@
+# Sample
+
+This is a sample of what the generated terraform files will look like.
+
+## Sample Function
+
+This sample function detects and remediates EBS Encryption by Default.
+
+Responds to the events `DisableEbsEncryptionByDefault`, `EnableEbsEncryptionByDefault`.
+Responds to a custom trigger `EbsEncryptionByDefault`
+
+## Files
+- backend.tf - Configuration for the centralized storage
+- sns.tf - SNS Topics
+
+## TODO
+besides finish, of course
+
+* SNS - Use custom key for multiaccount access
+
+

+ 8 - 0
sample/backend.tf

@@ -0,0 +1,8 @@
+terraform {
+  backend "s3" {
+    bucket = "fcm-terraform-state"
+    key    = "global/s3/terraform.tfstate"
+    region = "us-east-2"
+    encrypt = true
+  }
+}

+ 26 - 0
sample/cloudwatch.tf

@@ -0,0 +1,26 @@
+resource "aws_cloudwatch_event_rule" "fcm-event-DisableEbsEncryptionByDefault" {
+  name        = "fcm-event-DisableEbsEncryptionByDefault"
+  description = "FCM Compliance for EbsEncryptionByDefault Event"
+
+  event_pattern = <<PATTERN
+{
+  "detail": {
+    "eventSource": [
+      "ec2.amazonaws.com"
+    ],
+    "eventName": [
+      "DisableEbsEncryptionByDefault"
+    ]
+  },
+  "source": [
+    "aws.ec2"
+  ]
+}
+PATTERN
+}
+
+resource "aws_cloudwatch_event_target" "fcm-event-DisableEbsEncryptionByDefault" {
+  rule      = "${aws_cloudwatch_event_rule.fcm-event-DisableEbsEncryptionByDefault.name}"
+  target_id = "SendToSNS"
+  arn       = "${aws_sns_topic.fcm-input-DisableEbsEncryptionByDefault.arn}"
+}

+ 6 - 0
sample/provider.tf

@@ -0,0 +1,6 @@
+provider "aws" {
+  # Specify keys if not provided by shared crednentials file
+  #  access_key = "${var.access_key}"
+  #  secret_key = "${var.secret_key}"
+  region     = "us-east-2"
+}

+ 92 - 0
sample/sns.tf

@@ -0,0 +1,92 @@
+#### DisableEbsEncryptionByDefault
+resource "aws_sns_topic" "fcm-input-DisableEbsEncryptionByDefault" {
+  name = "fcm-input-DisableEbsEncryptionByDefault"
+  kms_master_key_id = "alias/aws/sns"
+
+  tags = {
+    Project = "FredsCloudMonitor"
+  }
+}
+
+data "aws_iam_policy_document" "fcm-input-DisableEbsEncryptionByDefault" {
+  statement {
+    effect  = "Allow"
+    actions = ["SNS:Publish"]
+
+    principals {
+      type        = "Service"
+      identifiers = ["events.amazonaws.com"]
+    }
+
+    resources = [
+      "${aws_sns_topic.fcm-input-DisableEbsEncryptionByDefault.arn}"
+    ]
+  }
+}
+
+resource "aws_sns_topic_policy" "fcm-input-DisableEbsEncryptionByDefault" {
+  arn    = "${aws_sns_topic.fcm-input-DisableEbsEncryptionByDefault.arn}"
+  policy = "${data.aws_iam_policy_document.fcm-input-DisableEbsEncryptionByDefault.json}"
+}
+
+#### EnableEbsEncryptionByDefault
+resource "aws_sns_topic" "fcm-input-EnableEbsEncryptionByDefault" {
+  name = "fcm-input-EnableEbsEncryptionByDefault"
+  kms_master_key_id = "alias/aws/sns"
+
+  tags = {
+    Project = "FredsCloudMonitor"
+  }
+}
+
+data "aws_iam_policy_document" "fcm-input-EnableEbsEncryptionByDefault" {
+  statement {
+    effect  = "Allow"
+    actions = ["SNS:Publish"]
+
+    principals {
+      type        = "Service"
+      identifiers = ["events.amazonaws.com"]
+    }
+
+    resources = [
+      "${aws_sns_topic.fcm-input-EnableEbsEncryptionByDefault.arn}"
+    ]
+  }
+}
+
+resource "aws_sns_topic_policy" "fcm-input-EnableEbsEncryptionByDefault" {
+  arn    = "${aws_sns_topic.fcm-input-EnableEbsEncryptionByDefault.arn}"
+  policy = "${data.aws_iam_policy_document.fcm-input-EnableEbsEncryptionByDefault.json}"
+}
+
+#### Custom: EbsEncryptionByDefault
+resource "aws_sns_topic" "fcm-custom-EbsEncryptionByDefault" {
+  name = "fcm-custom_EbsEncryptionByDefault"
+  kms_master_key_id = "alias/aws/sns"
+
+  tags = {
+    Project = "FredsCloudMonitor"
+  }
+}
+
+data "aws_iam_policy_document" "fcm-custom-EbsEncryptionByDefault" {
+  statement {
+    effect  = "Allow"
+    actions = ["SNS:Publish"]
+
+    principals {
+      type        = "Service"
+      identifiers = ["events.amazonaws.com"]
+    }
+
+    resources = [
+      "${aws_sns_topic.fcm-custom-EbsEncryptionByDefault.arn}"
+    ]
+  }
+}
+
+resource "aws_sns_topic_policy" "fcm-custom-EbsEncryptionByDefault" {
+  arn    = "${aws_sns_topic.fcm-custom-EbsEncryptionByDefault.arn}"
+  policy = "${data.aws_iam_policy_document.fcm-custom-EbsEncryptionByDefault.json}"
+}

+ 29 - 0
sample/sqs.tf

@@ -0,0 +1,29 @@
+resource "aws_sqs_queue" "fcm-analysis-EbsEncryptionByDefault-deadletter" {
+  name                      = "fcm-analysis-EbsEncryptionByDefault-deadletter"
+  visibility_timeout_seconds = 900 # How long before the item can be retried if something went wrong, should match processing time
+  delay_seconds             = 0 # Delay before message is delivered. This can be increased if resources take longer to be active.
+  max_message_size          = 262144 # How big messages can get. 256KB is the max for SNS and SQS
+  message_retention_seconds = 1209600 # Better handle it with 14 days!
+  kms_master_key_id         = "alias/aws/sqs" 
+  kms_data_key_reuse_period_seconds = 300 # keep using the same data key for up to 5 minutes
+
+  tags = {
+    Project = "FredsCloudMonitor"
+  }
+}
+
+resource "aws_sqs_queue" "fcm-analysis-EbsEncryptionByDefault" {
+  name                      = "fcm-analysis-EbsEncryptionByDefault"
+  visibility_timeout_seconds = 900 # How long before the item can be retried if something went wrong, should match processing time
+  delay_seconds             = 0 # Delay before message is delivered. This can be increased if resources take longer to be active.
+  max_message_size          = 262144 # How big messages can get. 256KB is the max for SNS and SQS
+  message_retention_seconds = 86400 # How long to keep the message
+  redrive_policy            = "{\"deadLetterTargetArn\":\"${aws_sqs_queue.fcm-analysis-EbsEncryptionByDefault-deadletter.arn}\",\"maxReceiveCount\":4}" # maxReceiveCount is how many times to attempt processing
+  kms_master_key_id         = "alias/aws/sqs" 
+  kms_data_key_reuse_period_seconds = 300 # keep using the same data key for up to 5 minutes
+
+  tags = {
+    Project = "FredsCloudMonitor"
+  }
+}
+