Amazon SAA-C03: 安全性、IAM、KMS 與治理 — 學習指南
屬於 AWS SAA-C03 — 完整學習指南. 使用經過驗證的解答練習: Amazon 考試中心, 或參加限時模擬考試: ExamRoll.io.
身分識別基礎:使用者、根使用者、群組與角色
身分與存取管理 (Identity and Access Management) 是每個工作負載都會經過的控制平面,其指導原則是最低權限:只授予必要的權限,且僅在必要的時間內授予,並且偏好使用產生短期憑證的身分,而非持有靜態秘密的身分。
根使用者擁有整個帳戶,持有無限制的權限,且不能被 IAM 政策或 SCPs 所限制。這使其成為環境中最敏感的單一憑證,應被視為緊急破窗 (break-glass) 程序。在一個新帳戶中:為根使用者啟用硬體或虛擬 MFA 裝置、設定一個長而獨特的密碼、移除任何歷史的根存取金鑰,並註冊備用的帳務/營運/安全聯絡人,以便在需要時進行復原。在初始設定——建立一個 IAM 管理員身分、設定帳務、以及設定帳戶別名——之後,除了 AWS 明確要求使用它的少數特定任務(如關閉帳戶、變更帳戶名稱、還原被刪除的 IAM 權限、啟用 MFA Delete,以及少數 S3/CloudFront 的根使用者簽署操作)外,不應再使用根使用者。使用根使用者進行日常工作是錯誤的,因為它無法被政策限制範圍、當共用時在 CloudTrail 中難以追溯歸屬,且一次洩露就會授予不可撤銷的控制權。
人員的日常存取是透過由最低權限政策限定範圍的 IAM 身分來進行。將受管政策附加到群組,而非個別使用者:一個附加了 AdministratorAccess 的 Administrators 群組,並將具名使用者放入其中,這樣可以產生單一的變更點,並避免將相同政策複製貼上到每個使用者的反模式。使用明確的 ARN 來限定資源範圍,而不是 *。
角色則完全用於不同的目的。它們由主體(principal)——服務、EC2 執行個體、Lambda 函式、聯合身分使用者、跨帳戶呼叫者——所承擔,並產生會自動輪換的臨時 STS 憑證。因為這些憑證不會在 Git commit 中洩露,且在幾分鐘到幾小時內就會過期,而不是持續有效直到手動輪換,所以角色是任何非人類實體的預設身分。
每個角色的兩種政策:權限與信任
每個角色都由兩個獨立的文件所管理,忘記其中任何一個都是典型的失敗模式。
權限政策(身分型)宣告該角色在被承擔後可以做什麼。信任政策(資源型,附加於角色本身)宣告誰可以承擔它。將 AmazonS3ReadOnlyAccess 附加到一個角色上,如果沒有任何主體被允許對其呼叫 sts:AssumeRole,那也毫無作用;反之,一個寬鬆的信任政策若沒有權限政策,會產生一個可以被承擔但做不了任何有用事情的角色。
一個 Lambda 執行角色展示了服務主體(service-principal)的模式——呼叫者是服務本身,而不是帳戶擁有者:
AssumeRolePolicyDocument: # trust policy
Version: "2012-10-17"
Statement:
- Effect: Allow
Principal: { Service: lambda.amazonaws.com }
Action: sts:AssumeRole
Policies: # permissions
- PolicyName: ReadOrders
PolicyDocument:
Statement:
- Effect: Allow
Action: dynamodb:GetItem
Resource: arn:aws:dynamodb:*:*:table/Orders
工作負載身分:Instance Profiles、Task Roles、IRSA、Roles Anywhere
每個存在於範本、環境變數或筆記型電腦中的憑證都是未來的安全漏洞。典型的 AWS 模式是透過角色來交付短期、自動輪換的憑證,以取代靜態的存取金鑰。
對於 EC2,交付機制是 instance profile——一個將 IAM 角色綁定到執行個體的輕量級容器,以便 Instance Metadata Service (IMDSv2) 可以向 SDK 提供臨時憑證。預設的憑證提供者鏈(credential provider chain)無需設定即可找到它們,所以 boto3.client('s3') 就能直接運作,而應用程式碼永遠不會接觸到憑證。應強制執行 IMDSv2 (HttpTokens: required) 以防止基於 SSRF 的憑證竊取。憑證大約每六小時輪換一次,而撤銷只需簡單地編輯角色即可。
AppRole:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Statement:
- Effect: Allow
Principal: { Service: ec2.amazonaws.com }
Action: sts:AssumeRole
Policies:
- PolicyName: S3DocAccess
PolicyDocument:
Statement:
- Effect: Allow
Action: [s3:GetObject, s3:PutObject]
Resource: arn:aws:s3:::docs-bucket/*
AppInstanceProfile:
Type: AWS::IAM::InstanceProfile
Properties:
Roles: [!Ref AppRole]
對於 ECS,對應的是 task role;對於 Lambda,是 execution role;對於 EKS pods,則是 IRSA (IAM Roles for Service Accounts) 或 EKS Pod Identity。在每種情況下,都是由 AWS 本身根據角色來仲介憑證,工作負載永遠不會接觸到長期有效的秘密。
將存取金鑰寫死在 AMI、使用者資料(user-data)腳本或 .env 檔案中是錯誤的,原因有三:金鑰永遠不會自動輪換、它們無法像來源 VPC 端點那樣被限定於會話上下文(session context),以及如果執行個體被入侵或 AMI 被無意中分享,憑證將會永久洩露。
對於在 AWS 之外的工作負載——例如地端伺服器、其他雲端、CI 執行器——若需要臨時的 AWS 憑證而又不想嵌入金鑰,IAM Roles Anywhere 使用來自私有 CA(AWS Private CA 或您自己的 CA)的 X.509 憑證作為信任錨點。工作負載出示其客戶端憑證,即可接收短期的 STS 憑證:
aws_signing_helper credential-process \
--certificate /etc/pki/client.pem \
--private-key /etc/pki/client.key \
--trust-anchor-arn arn:aws:rolesanywhere:...:trust-anchor/... \
--profile-arn arn:aws:rolesanywhere:...:profile/... \
--role-arn arn:aws:iam::111122223333:role/OnPremWorkload
這解決了與 instance roles 和 Secrets Manager 在 AWS 內部所解決的相同的反模式。
規模化的人員存取:Identity Center、SAML、Directory Service
在任何規模下,為每個帳戶配置 IAM 使用者都是難以管理的。AWS IAM Identity Center(AWS SSO 的後繼者)是建議用於員工存取的前門:一個可聯合到 Organization 中每個帳戶的單一目錄,並透過 permission sets(權限集)——對應到 IdP 群組的 IAM 角色範本——發放基於角色的臨時會話。使用者在 Identity Center 入口網站驗證一次後,即可承擔權限集進入任何已分配的帳戶。
Identity Center 透過 SAML 2.0 和 SCIM 與外部 IdP(Okta、Entra ID/Azure AD、Google Workspace、ADFS)整合,以實現自動化的員工加入/異動/離職流程,並透過 AWS Directory Service AD Connector(一個代理)或 AWS Managed Microsoft AD(一個在 AWS 中的完整複本)與地端的 Active Directory 整合。對於需要從未經驗證或第三方驗證的使用者呼叫 AWS 的行動或網頁應用程式,Amazon Cognito 會將外部身分交換為臨時的 STS 憑證,同樣避免了嵌入長期有效的金鑰。
跨帳戶存取
跨帳戶存取是透過角色 (role) 來實現,而非共享使用者,且雙方都必須同意。目標帳戶 (B) 建立一個角色,其信任政策 (trust policy) 中指名帳戶 A (或其中的特定主體),而帳戶 A 中的呼叫者也必須擁有針對該角色 ARN 的 sts:AssumeRole 權限。單方面的設定是不夠的。這樣做會產生有時效性的短期憑證,並在兩個帳戶的 CloudTrail 中留下清晰的稽核軌跡。
當第三方 (例如 SaaS 供應商) 是擔任角色的主體時,請加上 ExternalId 條件來解決混淆代理人問題 (confused deputy problem),並考慮要求 MFA:
{
"Effect": "Allow",
"Principal": { "AWS": "arn:aws:iam::222222222222:root" },
"Action": "sts:AssumeRole",
"Condition": {
"StringEquals": { "sts:ExternalId": "a1b2c3-unique-token" },
"Bool": { "aws:MultiFactorAuthPresent": "true" }
}
}
對於服務對服務 (service-to-service) 的跨帳戶調用,則由資源政策 (resource policy) 來處理。要讓帳戶 A 中的 SNS 主題調用帳戶 B 中的 Lambda:
aws lambda add-permission \
--function-name ProcessNotification \
--statement-id AllowSNSInvoke \
--action lambda:InvokeFunction \
--principal sns.amazonaws.com \
--source-arn arn:aws:sns:us-east-1:111111111111:my-topic
--principal sns.amazonaws.com 是服務主體 (service principal) (由 SNS 服務本身調用 Lambda),而 --source-arn 則將信任範圍限定在特定的主題,以防止混淆代理人問題。
對於跨 AWS Organizations 的 S3 共享,天真的作法——在儲存桶政策 (bucket policy) 中列出每個帳戶的 ARN——不僅無法擴展,而且每當新增帳戶時就會出問題。正確的模式是使用 aws:PrincipalOrgID:
{
"Effect": "Allow",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::reports-bucket/*",
"Condition": {
"StringEquals": { "aws:PrincipalOrgID": "o-abcd1234ef" }
}
}
該組織中任何帳戶的任何主體都會被允許;其他任何人則會被拒絕。請注意,如果 Principal: "*" 沒有加上條件,儲存桶就會變成公開的——正是這個條件鍵 (condition key) 限制了範圍。身分端的設定仍然重要:成員帳戶中的使用者也需要透過他們自己的 IAM 政策授予 s3:GetObject 權限 (除非他們是帳戶根使用者),因為跨帳戶存取需要雙方都允許該呼叫。
特別針對 S3,自 2023 年起,預設的物件擁有權 (Object Ownership) 設定 Bucket owner enforced (強制儲存桶擁有者) 會完全停用 ACL,使得儲存桶政策成為該儲存桶唯一的授權機制。當物件先前是由其他帳戶上傳時,歷史的物件 ACL 或 bucket-owner-full-control 這類預設 ACL (canned ACL) 可能仍然有效。
Organizations 與服務控制政策
AWS Organizations 將多個帳戶彙整成一個由 OU (組織單位) 組成的樹狀結構,並以一個管理帳戶 (management account) 作為根節點。服務控制政策 (Service Control Policies, SCPs) 是附加在根、OU 或個別帳戶上的護欄 (guardrails)。它們適用於帳戶中的每個 IAM 使用者和角色——包含帳戶根使用者——但不適用於管理帳戶本身,這就是為什麼工作負載絕不應該在管理帳戶中執行的原因。
關鍵的心智模型是:SCPs 絕不會授予權限。它們定義的是一個帳戶中允許執行的最大權限集合。一個動作只有在被身分或資源政策授予,且未被該帳戶路徑上任何 SCP 阻擋的情況下,才會被允許。如果一位開發者擁有 AdministratorAccess 權限,但 SCP 拒絕了在 ap-southeast-2 區域之外的 ec2:RunInstances 動作,那麼在 us-east-1 啟動執行個體就會失敗。反過來說,一個允許 s3:* 的 SCP 本身並無作用——使用者仍然需要一個授予 s3:* 的 IAM 政策。SCPs 過濾的是 IAM 已經允許的權限;它們是權限的天花板,而不是地板。
SCPs 的典型用途包括區域鎖定、禁止停用 CloudTrail 或 GuardDuty、禁止在緊急應變角色 (break-glass role) 之外刪除 KMS 金鑰,以及強制加密。要強制在啟動時加密 EBS,可以結合兩種機制:在該區域啟用預設 EBS 加密 (這是一個每個區域、每個帳戶的設定,這樣使用者就不需更改腳本),再加上一個 SCP 作為可稽核的護欄:
{
"Effect": "Deny",
"Action": "ec2:RunInstances",
"Resource": "arn:aws:ec2:*:*:volume/*",
"Condition": { "Bool": { "ec2:Encrypted": "false" } }
}
因為 SCPs 適用於整個帳戶,所以它們無法被成員帳戶中一個被入侵的管理者繞過。標籤政策 (Tag policies) 強制標準化的標籤鍵 (key) 和大小寫 (例如 CostCenter 而非 costcenter),以確保成本分攤和 ABAC (屬性型存取控制) 能可靠運作。Organizations 也支援委派管理 (delegated administration):與其從管理帳戶執行安全服務,不如委派一個成員帳戶 (例如「安全」或「稽核」帳戶) 作為 GuardDuty、Security Hub、IAM Access Analyzer 或 Config 的管理者——藉此維持職責分離 (separation of duties)。
KMS:金鑰、金鑰政策與擁有權模型
KMS 根據擁有權和控制權來區分金鑰材料:
| 模型 | 金鑰材料 | 輪換 | 可稽核 | 使用案例 |
|---|---|---|---|---|
| SSE-S3 / AWS 擁有 | AWS,隱藏 | 自動,不透明 | 不可見 | 簡單的「靜態加密」 |
AWS 管理的 CMK (aws/service) | AWS | 每年自動 | 是 | 預設,無需控制 |
| 客戶管理的 CMK | AWS KMS,您擁有政策 | 選用性每年輪換 (需啟用),可設定 90–2560 天 | 是 | 您需要停用、稽核、限定範圍或共享時 |
| 匯入的金鑰材料 | 您產生,匯入至 KMS | 手動重新匯入;永不自動 | 是 | 法規強制要求自行產生金鑰 |
| 外部金鑰存放區 (XKS) | 您透過 XKS proxy 控制的本地 HSM | 您在外部控制 | 是 | 資料主權;金鑰永不離開您的場域 |
| SSE-C | 客戶依請求提供 | 手動 | 有限 | 客戶堅持持有金鑰材料 |
CMK 由金鑰政策 (key policy) 所控管——這是一種附加在金鑰上的資源型政策。與幾乎所有其他 AWS 資源不同,單獨的 IAM 政策無法授予對 KMS 金鑰的存取權,除非金鑰政策首先將權限委派給 IAM:
{
"Sid": "EnableIAMPolicies",
"Effect": "Allow",
"Principal": { "AWS": "arn:aws:iam::111122223333:root" },
"Action": "kms:*",
"Resource": "*"
}
若無此陳述,任何 IAM 政策都無法讓該金鑰變得可用。金鑰政策與呼叫者的 IAM 政策兩者都必須允許該操作——這是最常見的單一加密錯誤。在 IAM 政策中授予 kms:Decrypt 是必要但非充分條件;如果金鑰政策未委派給 IAM 或未指名 principal,即使是管理員,解密也會因 AccessDenied 而失敗。
對於代表您使用 KMS 的服務 (EBS、S3、RDS、Lambda),呼叫的角色通常需要 kms:GenerateDataKey、kms:Decrypt,且經常需要 kms:CreateGrant。對於使用 CMK 加密 EBS 磁碟區的 EKS 受管節點群組,Auto Scaling 的服務連結角色 (service-linked role) 必須出現在金鑰政策中並具備 kms:CreateGrant 權限,否則執行個體的啟動將會無聲地失敗。
客戶管理的 CMK 輪換需要明確啟用——許多從業人員錯誤地假設所有 KMS 金鑰都會自動輪換:
aws kms enable-key-rotation --key-id alias/my-cmk
aws kms get-key-rotation-status --key-id alias/my-cmk
輪換會保留相同的金鑰 ID 和別名;底層的金鑰材料會變更,但過去的密文仍然可以解密,因為 KMS 會保留舊材料以解密現有密文,而新的寫入操作則使用新的材料。匯入的材料永不自動輪換。KMS 強制執行 7-30 天的待刪除等待期;將此與一個 EventBridge 規則配對,該規則匹配 CloudTrail 中的 ScheduleKeyDeletion 或 DisableKey 事件,並將目標設為一個 SNS 主題,以實現無伺服器、免輪詢的警示模式:
{
"source": ["aws.kms"],
"detail-type": ["AWS API Call via CloudTrail"],
"detail": { "eventName": ["ScheduleKeyDeletion", "DisableKey"] }
}
當法規要求金鑰材料必須實際存放在客戶控制的 HSM 中時,外部金鑰存放區 (External Key Stores) 擴展了此模型。KMS 會將加密操作轉發到與本地 HSM 通訊的 XKS proxy;如果 HSM 離線,解密將會失敗——可用性變成了客戶的責任。
多區域金鑰 (Multi-Region Keys, MRKs) 在不同區域間共享相同的金鑰 ID 和材料,因此在 us-east-1 產生的密文可以直接在 eu-west-1 解密。這對於 DynamoDB Global Tables、使用 SSE-KMS 的 S3 跨區域複寫,以及災難復原 (DR) 情境中備援區域必須讀取加密備份的場景,是正確的模式。標準的單一區域金鑰在複寫時則需要先解密再重新加密。
跨帳戶加密資源共享
加密的 AMI 和 EBS 快照共享是最常見的跨帳戶失敗模式之一,因為它需要四個協調的動作:(1) 使用客戶管理的 CMK——AWS 管理的金鑰無法共享;(2) 在金鑰政策中將目標帳戶新增為 principal,並授予 kms:Decrypt、kms:DescribeKey、kms:CreateGrant 和 kms:ReEncrypt* 權限;(3) 修改 AMI 或快照的啟動/共享權限以包含該帳戶;以及 (4) 確保目標帳戶中的 IAM principal 也擁有這些 KMS 動作的權限。如果您跳過步驟 2,共享操作表面上會成功,但接收方帳戶將無法解密。假設僅共享 AMI 就足夠了,這是一個典型的陷阱。
S3 伺服器端加密模式
| 模式 | 金鑰擁有者 | 輪換 | CloudTrail 稽核 | 成本 |
|---|---|---|---|---|
| SSE-S3 (AES-256) | AWS 管理,隱藏 | 自動,不透明 | 不可見 | 無金鑰成本 |
使用 aws/s3 的 SSE-KMS | AWS | 每年自動 | 是 | 無金鑰成本,但需支付 API 費用 |
| 使用客戶 CMK 的 SSE-KMS | 客戶 | 選用,需啟用 | 是 | 每把金鑰每月 1 美元 + API 費用 |
| DSSE-KMS | 客戶 | 與 CMK 相同 | 是 | 更高;適用於受監管工作負載的雙層加密 |
| SSE-C | 客戶依請求提供 | 手動 | 有限 | 無金鑰成本 |
| CSE-KMS / CSE-C | 客戶,上傳前加密 | 手動 | 僅 KMS 呼叫 | 不定 |
當需求指定自動年度輪換、CloudTrail 可稽核性,且要最小化金鑰成本時,答案是使用 AWS 管理的 aws/s3 金鑰的 SSE-KMS——它每年免費輪換,且每一次 GenerateDataKey/Decrypt 呼叫都會被記錄。SSE-S3 比較便宜,但不會留下金鑰使用軌跡。客戶管理的 CMK 每月會增加 1 美元的費用,且只有在您啟用輪換時才會輪換。
混淆 SSE-S3 和 SSE-KMS 是典型的 PHI (受保護健康資訊) 陷阱。SSE-S3 會加密資料,但不提供金鑰政策、沒有 CloudTrail 可見性,也無法讓合規團隊管理金鑰——因此它無法滿足任何提及「管理」、「控制」、「稽核」或「撤銷存取權」等要求的場景。反過來說,當需求僅是「以最少管理來達成靜態加密」時,選擇 SSE-KMS 則是過度設計 (over-engineering)。
啟用 SSE-KMS 本身並不能防止未經授權的讀取。如果儲存貯體政策允許 s3:GetObject,且金鑰政策也對同一個 principal 授予 kms:Decrypt,那麼物件就是可讀取的。靜態加密是為了防禦實體媒體外洩,並透過金鑰政策增加第二層授權檢查——它不能取代範圍設定正確的儲存貯體政策、IAM 政策、VPC 端點政策和 aws:PrincipalOrgID 條件。
在 S3 上強制執行加密與 TLS
僅將儲存貯體設為「預設加密」是不夠的——用戶端可以省略或覆寫加密標頭。必須疊加兩種防護機制:預設儲存貯體加密(若用戶端省略標頭則自動填入)以及基於 deny 的儲存貯體政策,用以拒絕沒有必要標頭的 PutObject 請求,再加上一條拒絕非 TLS 存取的陳述式:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "DenyUnEncryptedObjectUploads",
"Effect": "Deny",
"Principal": "*",
"Action": "s3:PutObject",
"Resource": "arn:aws:s3:::phi-bucket/*",
"Condition": {
"StringNotEquals": { "s3:x-amz-server-side-encryption": "aws:kms" }
}
},
{
"Sid": "DenyInsecureTransport",
"Effect": "Deny",
"Principal": "*",
"Action": "s3:*",
"Resource": ["arn:aws:s3:::phi-bucket", "arn:aws:s3:::phi-bucket/*"],
"Condition": { "Bool": { "aws:SecureTransport": "false" } }
}
]
}
aws:SecureTransport 條件強制使用 HTTPS,滿足了「傳輸中加密」的要求。結合使用由合規團隊擁有的 CMK 進行 SSE-KMS 加密,這是儲存 PHI 的典型模式。
傳輸中加密 vs. 靜態加密
靜態加密(KMS 加密的 EBS、RDS 儲存、S3 物件)和傳輸中加密(線路上的 TLS)是獨立的控制措施,用以應對不同的威脅——前者針對磁碟竊取,後者針對網路攔截。在 RDS 執行個體上啟用 KMS 可以保護其底層儲存;但對於用戶端到資料庫的連線階段則毫無作用,該連線預設可能未經加密。對於 RDS MySQL,傳輸中加密的保護需要下載 RDS CA 憑證包,在參數群組中設定 require_secure_transport=ON,並讓用戶端使用 --ssl-ca=rds-combined-ca-bundle.pem 進行連線。將「靜態加密已開啟」視為足夠,是稽核中常見的失敗點。
Secrets Manager 與 Parameter Store
將靜態資料庫密碼存放在設定檔、環境變數或 CloudFormation 參數中,是主要的憑證洩漏途徑。AWS Secrets Manager 使用 KMS 將機密加密儲存,透過受 IAM 控制的 GetSecretValue 來存取,並且——至關重要的是——透過 Lambda 輪換函式自動輪換這些機密。對於 RDS、Aurora、Redshift 和 DocumentDB,AWS 提供了託管的輪換 Lambda,它會連線到資料庫,產生新密碼,以原子方式更新機密和資料庫使用者,並支援單一使用者或多使用者策略。對於其他系統,您需要自行編寫一個 Lambda 來實作四個步驟的生命週期:createSecret、setSecret、testSecret、finishSecret。
import boto3, json
secret = json.loads(
boto3.client('secretsmanager')
.get_secret_value(SecretId='prod/aurora/app')['SecretString'])
conn = pymysql.connect(host=secret['host'],
user=secret['username'],
password=secret['password'])
應用程式會短暫快取該值(使用 AWS SDK 快取程式庫),並在驗證失敗時重新連線。輪換是無感的,且變更密碼無需部署。
當不需要輪換且成本是主要考量時,SSM Parameter Store SecureString 是另一個選擇:
| 功能 | Secrets Manager | SSM Parameter Store |
|---|---|---|
| 自動輪換 | 是;對 RDS/Aurora/Redshift/DocumentDB 提供原生支援 | 無原生輪換功能 (Advanced tier 可觸發 EventBridge) |
| 成本 | 每個機密每月 $0.40 + API 費用 | Standard tier 免費;Advanced tier 付費 |
| 大小限制 | 64 KB | Standard 4 KB, Advanced 8 KB |
| 跨帳戶共用 | 資源型政策 | 無法原生共用 |
| 跨區域複寫 | 是 | 否 |
| 加密 | 必須使用 KMS | 僅 SecureString 使用 KMS |
SecureString 參數的擷取者需要同時擁有對金鑰的 ssm:GetParameter 和 kms:Decrypt 權限。忘記 KMS 權限是最常見的錯誤配置之一——IAM 政策看起來正確,但 API 呼叫在解密時失敗。
在 EC2、ECS、EKS 和 Lambda 上,程式碼應擔任一個 IAM 角色並呼叫 GetSecretValue 或 GetParameter;磁碟上不應存放長期有效的憑證。直接在應用程式碼中嵌入 IAM 使用者存取金鑰——即使是加密的——也違反了最低權限原則並使輪換變得複雜。
稽核與鑑識工具
CloudTrail 記錄每一次 AWS API 呼叫:誰、做了什麼、何時、從何處。從管理帳戶啟用的組織追蹤 (organization trail) 會將所有帳戶的事件捕獲到單一的 S3 儲存貯體中,理想情況下,該儲存貯體應位於一個鎖定的安全帳戶內,並啟用 S3 Object Lock 和 MFA Delete。這提供了一個不可變的鑑識時間軸——哪個主體刪除了磁碟區,哪個角色修改了安全群組,哪個存取金鑰在 UTC 03:17 呼叫了 ec2:RunInstances。可搭配 CloudWatch Logs 和警報(root 登入、IAM 政策變更),以及用於檢視特定時間點資源狀態和合規包的 AWS Config。使用 SCP 拒絕 cloudtrail:StopLogging 和 cloudtrail:DeleteTrail 來防止篡改。
S3 儲存貯體上的 MFA Delete 強制 root 使用者必須出示 MFA 權杖才能永久刪除物件版本或停用版本控制。它只能由 root 使用者透過 CLI 啟用,並針對勒索軟體和內部人員刪除提供強大的保護。
Amazon Macie 使用託管的機器學習技術來探索 S3 中的 PII、PHI、憑證和財務資料,並產生按嚴重性排序的調查發現。它是一個探索工具,而非加密工具。
威脅偵測:GuardDuty、Security Hub、Detective
Amazon GuardDuty 持續分析 VPC Flow Logs、DNS logs、以及 CloudTrail 管理和資料事件,並為 EKS 稽核日誌、S3 資料事件、EBS 惡意軟體掃描、Lambda 網路活動和 RDS 登入事件 提供專門的保護計畫。GuardDuty RDS Protection 能揭露針對 Aurora 和 RDS 的異常或暴力破解驗證嘗試——這種行為是安全群組無法捕捉到的,因為在 L4 層級連線是合法的。調查發現會流入 EventBridge、Security Hub 和 Detective 的儀表板。
安全群組僅在 L3–L4 層級運作。一個允許 443 埠對 0.0.0.0/0 開放的安全群組,在轉發 SQL injection 酬載時,正是在做它份內的工作——而這正是 WAF 存在的目的。深度防禦意味著安全群組加上 WAF、Shield 和 GuardDuty,每一層都涵蓋了其他層無法看到的範圍。
DDoS:Shield Standard 與 Advanced
AWS Shield Standard 是自動且免費的,保護每個帳戶免於常見的 L3/L4 攻擊(如 SYN floods、reflection)。它在背景默默運行,沒有可視性、無法自訂緩解措施,也沒有人為介入的途徑。
AWS Shield Advanced(每個組織每月 3,000 美元,外加資料傳輸費用)在情境中提到主動參與 (proactive engagement)、專屬應對 (dedicated response)、針對 DDoS 誘發擴展的成本保護 (cost protection),或近乎即時的攻擊可視性時,就是必要的。它涵蓋 CloudFront、Global Accelerator、ALB、CLB、Route 53 和 Elastic IPs,並提供對 Shield Response Team (SRT) 的 24/7 存取權限——透過 IAM 角色預先授權——在攻擊發生時代表您撰寫 WAF 規則。當一個位於 ALB 和 Route 53 後方的設計需要受管的偵測以及人為應對時,單靠 Shield Standard 是不夠的;這是一個常見的陷阱。Advanced 也提供因應攻擊而觸發擴展的成本保護。當題目提到「最少實作精力」(LEAST implementation effort) 且架構中已包含 Global Accelerator 或 ALB 時,答案通常是啟用 Shield Advanced 並附加 AWS 管理的 WAF 規則群組,而不是建立自訂的 Lambda@Edge 或遷移 CDN。
應用層保護:AWS WAF
AWS WAF 可附加到 CloudFront、Application Load Balancers、API Gateway、AppSync、App Runner 和 Cognito 使用者集區。它不能直接保護 Network Load Balancers(需將 CloudFront 放在其前方)。它會檢查 L7 流量並應用規則來防禦 SQL injection、XSS、大小限制、地理封鎖、IP 信譽和速率限制。AWS Managed Rules 提供了精選的規則群組,例如 AWSManagedRulesCommonRuleSet 和 AWSManagedRulesSQLiRuleSet,無需自行撰寫 regex。
基於速率的規則 (Rate-based rules) 是防禦 HTTP floods 和 credential stuffing 的主要手段——它們會計算每個來源 IP(或每個轉發的標頭)在五分鐘內的請求數量,並自動封鎖違規者:
Rules:
- Name: RateLimitPerIP
Priority: 1
Statement:
RateBasedStatement:
Limit: 2000 # per 5-min window per IP
AggregateKeyType: IP
Action: { Block: {} }
VisibilityConfig:
CloudWatchMetricsEnabled: true
MetricName: RateLimitPerIP
SampledRequestsEnabled: true
WAF 不是 DDoS 服務——那是 Shield 的職責。WAF 補充了資源政策(如 S3 儲存貯體政策拒絕非 TLS 連線、VPC 端點政策限制可存取的儲存貯體)和網路控制(安全群組、NACLs)——任何單一層級的錯誤配置都不能導致資料外洩。
網路隔離:Security Groups、NACLs、Network Firewall
在 VPC 內部,防禦是分層的:
- 安全群組 (Security groups) 是 stateful (有狀態的),應用於 ENI,只允許 (allow-only),並同時評估所有規則。回傳流量會自動被允許,因此無需明確開放 ephemeral ports (臨時埠)。
- 網路 ACLs (Network ACLs) 是 stateless (無狀態的),應用於子網路,支援 allow 和 deny,並按數字順序評估。因為它們是無狀態的,如果您允許 inbound 443,您也必須允許 outbound ephemeral 1024–65535 以便回應。忘記這一點會以難以察覺的方式丟棄所有回覆。安全群組沒有這個問題。
- AWS Network Firewall 提供深度封包檢測 (deep packet inspection)、與 Suricata 相容的 IPS 規則,以及基於網域的出口過濾,位於子網路和 IGWs/TGWs 之間進行集中式檢測。
假設單靠安全群組就足夠,是忽略了子網路層級的威脅和爆炸半徑控制;假設單靠 NACLs 就足夠,是忽略了它們的無狀態性和粗糙性。
陷阱目錄
忘記信任政策 (Trust policy)。 角色的權限政策授予能力;只有信任政策授予被擔任 (assumability) 的權力。兩者都必須開放,跨帳戶或服務對服務的存取才能運作——無論身分政策多麼寬鬆,呼叫者都會在 sts:AssumeRole 上收到 AccessDenied。
IAM 政策與金鑰政策不匹配。 IAM 中的 kms:Decrypt 是必要的但非充分條件。金鑰政策必須指名 principal,或透過 Principal: {"AWS": "arn:aws:iam::ACCOUNT:root"} 委派給 IAM。當只分享了 AMI 卻未更新金鑰政策時,加密的 AMI/快照分享會失敗。
將 SCPs 視為授予權限。 SCPs 只設上限,從不授予權限。一個 Allow s3:* 的 SCP 若沒有匹配的身分政策,則毫無作用。反之,一個寬鬆的身分政策會受到該帳戶路徑上任何 SCP Deny 的限制。
假設 KMS 會自動輪換。 客戶管理的 CMK 在啟用前不會輪換;匯入的金鑰材料永遠不會自動輪換。
為受合規控管的資料選擇 SSE-S3。 SSE-S3 沒有金鑰政策、沒有 CloudTrail 可視性,也沒有撤銷路徑——它無法滿足任何提到要「管理」、「控制」、「稽核」或「撤銷」金鑰的需求。
將靜態加密視為足夠。 靜態加密和傳輸中加密是獨立的。使用 KMS 的 RDS 仍然需要設定 require_secure_transport=ON 和客戶端 CA 驗證。
儲存貯體政策逐一指名帳戶。 這種做法無法擴展,且在組織變動時會出錯。應使用 aws:PrincipalOrgID。
在任何地方硬編碼存取金鑰。 在 user data、.env 檔案、CloudFormation 參數、Git 中——永遠是錯的。應使用 instance profiles、task roles、execution roles、IRSA/Pod Identity 或 Roles Anywhere。
使用根使用者進行日常工作或附加政策。 根使用者不受 IAM 或 SCPs 的限制;為根使用者附加政策是沒有意義的。任何這樣做的答案從根本上就是錯的。
使用 IAM 使用者進行跨帳戶存取。 IAM 使用者不能被跨帳戶擔任;應在目標帳戶中建立一個角色,並讓來源帳戶的 principal 來擔任它。
將 NLB 放在 WAF 後方。 WAF 不能附加到 NLB。如果需要 L7 過濾,請在 NLB 前方加上 CloudFront。
NACL 缺少 ephemeral outbound 規則。 無狀態的 NACL 需要明確的回傳路徑規則。缺少 outbound 1024–65535 規則會默默地中斷所有 inbound 443 的回應。
使用 Shield Standard 應對需要管理的場景。 Standard 是被動的,無法存取 SRT;只有 Advanced 才能滿足「主動管理參與」或「成本保護」的需求。
← 應用程式整合、訊息傳遞與串流 · 所有領域 · 管理、維運、可觀測性與成本 →
練習這些題目 → · 在 ExamRoll.io 上限時練習 →
Pass the whole exam — not just this question
You found this answer. Get every verified question and explanation in one place, and save hours of prep. Free to start.
通過考試 →