CloudTrail 與 GuardDuty

🔥 Vibe Prompt

"為所有帳戶設定 CloudTrail,建立組織追蹤。啟用 GuardDuty 並設定自動化回應。"


為什麼需要 CloudTrail 與 GuardDuty?

| 服務 | 功能 | 比喻 | |:----:|:----:|:----:| | CloudTrail | 記錄所有 AWS API 呼叫 | 監視器 — 記錄誰在什麼時候做了什麼 | | GuardDuty | 智慧威脅偵測 | 警衛 — 分析行為模式,發現異常 |

兩者相輔相成:CloudTrail 提供原始資料,GuardDuty 提供智慧分析。


CloudTrail 設定

resource "aws_cloudtrail" "org_trail" {
  name                          = "org-trail"
  s3_bucket_name                = aws_s3_bucket.cloudtrail.id
  include_global_service_events = true
  is_multi_region_trail         = true
  enable_log_file_validation    = true
  is_organization_trail         = true
  
  event_selector {
    read_write_type           = "All"
    include_management_events = true
  }
}

resource "aws_s3_bucket" "cloudtrail" {
  bucket = "myorg-cloudtrail-logs"
  force_destroy = true
}

關鍵 CloudTrail 事件監控

| 事件 | 風險等級 | 說明 | |:----:|:--------:|------| | ConsoleLogin | 🔴 高 | 尤其注意 root 登入或無 MFA 登入 | | CreateUser / CreateAccessKey | 🔴 高 | 異常的 IAM 建立行為 | | PutRolePolicy | 🔴 高 | IAM 權限變更,可能是權限提升 | | PutBucketAcl / PutBucketPolicy | 🟡 中 | S3 權限變更,可能導致資料外洩 | | AuthorizeSecurityGroupIngress | 🟡 中 | 安全群組開放,可能暴露服務 | | CreateNetworkAcl | 🟢 低 | 網路 ACL 變更 |

CloudTrail 最佳實踐

  1. 開啟組織追蹤:一次啟用,自動涵蓋所有帳戶
  2. 啟用日誌驗證:確保日誌未被竄改
  3. 啟用多區域追蹤:涵蓋所有 AWS 區域
  4. 日誌加密:使用 KMS 加密 S3 中的日誌
  5. 設定生命週期:30 天後移至 IA,1 年後移至 Glacier
# 使用 AWS CLI 查詢 CloudTrail 事件
# 找出所有 root 登入事件
aws cloudtrail lookup-events \
  --lookup-attributes AttributeKey=EventName,AttributeValue=ConsoleLogin \
  --query 'Events[?UserIdentity.Type=="Root"]'

GuardDuty 威脅偵測

GuardDuty 使用機器學習和威脅情報來偵測異常行為。以下是它會告警的典型場景:

| 偵測類型 | 範例行為 | 嚴重程度 | |:--------:|---------|:--------:| | Backdoor | EC2 實例與已知惡意 IP 通訊 | 🔴 高 | | CryptoCurrency | EC2 連接到加密貨幣礦池 | 🔴 高 | | Recon | 來自陌生 IP 的大量 port scanning | 🟡 中 | | UnauthorizedAccess | IAM 使用者在異常時間/地點登入 | 🟡 中 | | Stealth | 關閉 CloudTrail 或 GuardDuty 本身 | 🔴 高 | | Discovery | 列出 S3 Bucket、IAM Role 等資源 | 🟢 低 |

自動化回應

resource "aws_cloudwatch_event_rule" "guardduty_finding" {
  name        = "guardduty-auto-response"
  description = "Trigger on GuardDuty findings"
  
  event_pattern = jsonencode({
    source      = ["aws.guardduty"]
    detail-type = ["GuardDuty Finding"]
    detail = {
      severity = [4, 5, 6, 7, 8, 8.9, 9]  # Medium to Critical
    }
  })
}

resource "aws_cloudwatch_event_target" "lambda_response" {
  rule      = aws_cloudwatch_event_rule.guardduty_finding.name
  arn       = aws_lambda_function.auto_response.arn
}

GuardDuty 成本估算

| 資料來源 | 百萬事件成本 | |:--------:|:-----------:| | CloudTrail 事件 | ~$4.00 | | VPC Flow Logs (1B) | ~$1.00 | | DNS 日誌 | ~$2.00 | | EKS 審計日誌 | ~$3.00 |


實戰:完整安全監控架構

AWS 帳戶
    │
    ├── CloudTrail ──▶ S3 (加密) ──▶ Athena (查詢)
    │                              └── Glacier (封存)
    │
    ├── GuardDuty ──▶ EventBridge ──▶ Lambda (自動回應)
    │                                 ├── Slack 通知
    │                                 ├── 隔離 EC2 (SG change)
    │                                 └── 建立 Jira Ticket
    │
    └── Security Hub ──▶ 統一儀表板
                         ├── GuardDuty 發現
                         ├── Inspector 掃描
                         └── Config 合規檢查

關鍵要點

  • ✅ CloudTrail = AWS 的 CCTV,記錄所有 API 呼叫
  • ✅ GuardDuty = AI 警衛,自動分析異常行為
  • ✅ 開啟組織追蹤 = 一次設定涵蓋所有帳戶
  • ✅ GuardDuty 發現可透過 EventBridge 自動觸發回應
  • ✅ Security Hub 統一顯示所有安全服務的發現
  • ✅ 日誌加密與生命週期管理是不可忽略的成本控制
resource "aws_cloudtrail" "org_trail" {
  name                          = "org-trail"
  s3_bucket_name                = aws_s3_bucket.cloudtrail.id
  include_global_service_events = true
  is_multi_region_trail         = true
  enable_log_file_validation    = true
  is_organization_trail         = true
  
  event_selector {
    read_write_type           = "All"
    include_management_events = true
  }
}

resource "aws_s3_bucket" "cloudtrail" {
  bucket = "myorg-cloudtrail-logs"
}

resource "aws_s3_bucket_policy" "cloudtrail" {
  bucket = aws_s3_bucket.cloudtrail.id
  policy = jsonencode({
    Statement = [{
      Effect = "Allow"
      Principal = { Service = "cloudtrail.amazonaws.com" }
      Action = "s3:PutObject"
      Resource = "${aws_s3_bucket.cloudtrail.arn}/AWSLogs/*"
      Condition = {
        StringEquals = { "s3:x-amz-acl" = "bucket-owner-full-control" }
      }
    }]
  })
}

Key CloudTrail Events

# Console login (without MFA)
{ "eventName": "ConsoleLogin", "userIdentity": { ... }, "responseElements": { "ConsoleLogin": "Failure" } }

# Root activity
{ "userIdentity": { "type": "Root" }, "eventName": "..." }

# IAM policy change
{ "eventSource": "iam.amazonaws.com", "eventName": "PutRolePolicy" }

# S3 public access change
{ "eventSource": "s3.amazonaws.com", "eventName": "PutBucketAcl" }

GuardDuty

resource "aws_guardduty_detector" "main" {
  enable = true
  datasources {
    s3_logs {
      enable = true
    }
    kubernetes {
      audit_logs {
        enable = true
      }
    }
  }
}

GuardDuty Finding Types

| Finding | Severity | What It Means | |---------|----------|---------------| | CryptoCurrency:EC2/BitcoinTool.B!DNS | High | EC2 mining crypto | | Backdoor:EC2/C&CActivity.B!DNS | High | Malware C&C | | UnauthorizedAccess:IAM/User.IAMUser | Medium | Suspicious IAM | | Policy:IAM/User/RootCredentialUsage | High | Root user activity | | Recon:EC2/PortProbeUnprotected | Low | Port scanning |

Automated Response

import boto3

def lambda_handler(event, context):
    finding = event['detail']['finding']
    finding_type = finding['type']
    resource_arn = finding['resource']['arn']
    severity = finding['severity']
    
    if severity >= 7:  # HIGH or CRITICAL
        if 'EC2' in finding_type:
            # Isolate the instance
            ec2 = boto3.client('ec2')
            instance_id = resource_arn.split('/')[-1]
            ec2.modify_instance_attribute(
                InstanceId=instance_id,
                Groups=['sg-quarantine']
            )
            print(f"Isolated {instance_id} in quarantine SG")
        
        elif 'IAM' in finding_type:
            # Disable the key
            iam = boto3.client('iam')
            iam.update_access_key(
                UserName=finding['resource']['accessKeyDetails']['userName'],
                AccessKeyId=finding['resource']['accessKeyDetails']['accessKeyId'],
                Status='Inactive'
            )
            print("Disabled compromised access key")

GuardDuty + Security Hub

GuardDuty → Security Hub → EventBridge → Lambda (auto-remediate)
                                            ↓
                                       Slack notification
                                            ↓
                                       PagerDuty (SEV-1/2)

Best Practices

  • Enable CloudTrail in all regions
  • Create organization trail (single log bucket)
  • Enable log file validation (integrity)
  • Enable GuardDuty in all accounts
  • Set up automated response for critical findings
  • Integrate with Security Hub for dashboard

為什麼要學CloudTrail 與 GuardDuty?

CloudTrail 與 GuardDuty 是 security-cloud-security 課程的核心章節之一。

在真實世界中

CloudTrail 與 GuardDuty 並不是課本上的理論——它在真實的軟體開發中頻繁出現。無論你是正在接案、準備面試,還是想要提升自己的技術深度,理解這個主題都能讓你直接受益。

你將從本章獲得

  • 🎯 完整的知識體系:從核心原理到實作細節,條理分明
  • 💻 可運行的程式碼:每段程式碼都是完整的,可直接執行
  • 🔍 除錯技巧:常見錯誤的分析與解決方案
  • 🚀 下一步指引:學完後該往哪個方向繼續深入

銜接下一章

本章為你建立了 CloudTrail 與 GuardDuty 的完整知識基礎。下一章將在此基礎上,帶你探索更進階的真實世界應用場景——你將學會如何將本章所學應用到更複雜的問題中。

解鎖完整教學內容

本章為付費內容。加入專案即可解鎖超過 5000 字的深度解析,包含 10 個以上神級 Prompt 與真實 Source Code 範例!