Lab 8: Security, Identity & Governance
Is lab mein tum production security ke saare building blocks khud chala ke dekhoge. Tum KMS se data encrypt karoge (envelope encryption tak), permission boundaries aur IAM Access Analyzer use karoge, IAM Identity Center (SSO) se logon ko login karwaoge, Cognito se app ke users banake ek JWT-protected API chalaoge, WAF se attacks block karoge, AWS Config se compliance check aur remediation karoge, GuardDuty se threats pakdoge, aur Security Hub mein account ka security score dekhoge. Aakhir mein ek optional hissa hai jisme tum Control Tower se landing zone banaoge.
- Setup
- KMS: keys, encrypt/decrypt, envelope encryption, SSE-KMS, key policy
- IAM advanced: permission boundaries + Access Analyzer
- IAM Identity Center (SSO) — human access ka sahi tareeka
- Cognito: app users, JWT, protected API
- WAF: SQL/XSS, rate limiting, IP blocking
- AWS Config: compliance rules + remediation
- GuardDuty + Security Hub
- (Optional) Control Tower landing zone
- Break & Fix, Challenge, Explain, Cleanup
0 Setup
Terminal mein region aur account ID set karo, lab ka folder banao, aur ek Python virtual environment banake usme boto3 aur cryptography install karo:
export AWS_DEFAULT_REGION=us-east-1
export ACCOUNT_ID=$(aws sts get-caller-identity --query Account --output text)
mkdir -p ~/deepdive/lab8 && cd ~/deepdive/lab8
python3 -m venv .venv && source .venv/bin/activate && pip install boto3 cryptography
Part C (Identity Center) aur Part H (Control Tower) ke liye AWS Organizations chahiye, isliye yeh dono sirf personal account mein ho sakte hain. Baaki saare parts personal account mein toh chalenge hi; agar Lab 1 ki check script ne sandbox mein ✅ diya ho toh wahan bhi chal sakte hain.
A KMS: keys, encrypt/decrypt, envelope encryption, SSE-KMS, key policy
AWS KMS encryption keys ko hardware security modules (HSMs) mein rakhta hai, aur key kabhi bhi KMS se bahar nahi aati. Tum KMS ko data (zyada se zyada 4 KB) ya data keys bhejte ho aur use encrypt ya decrypt karne ko kehte ho, aur har aisa istemaal CloudTrail mein log hota hai. AWS managed keys (jaise aws/s3 aur aws/ssm) muft hoti hain, lekin unki policy tum control nahi kar sakte. Customer managed key ka lagbhag $1 per month lagta hai (din ke hisaab se), aur isme tum apni key policy, rotation, aur key ko disable ya delete karna khud control karte ho. Kisi key ko use karne ke liye dono permissions chahiye: key policy allow kare, aur agar key policy ne account ko adhikaar de rakha hai, toh IAM policy bhi allow kare.
Neeche ki commands ek nayi key aur uska alias alias/deepdive banati hain, ek chhoti text file ko KMS se encrypt karke secret.bin mein likhti hain, use wapas decrypt karti hain, key ki default policy dikhati hain, aur saalana key rotation chalu karti hain:
KEY_ID=$(aws kms create-key --description "DEEPDIVE lab key" \
--tags TagKey=Project,TagValue=deepdive --query KeyMetadata.KeyId --output text)
aws kms create-alias --alias-name alias/deepdive --target-key-id $KEY_ID
echo "CEO salary: bahut zyada" > plain.txt
aws kms encrypt --key-id alias/deepdive --plaintext fileb://plain.txt \
--query CiphertextBlob --output text | base64 --decode > secret.bin
xxd secret.bin | head -3 # binary ciphertext — ismein key ID bhi embedded hota hai
aws kms decrypt --ciphertext-blob fileb://secret.bin --query Plaintext --output text | base64 --decode
aws kms get-key-policy --key-id $KEY_ID --policy-name default --output text | python3 -m json.tool
aws kms enable-key-rotation --key-id $KEY_ID
aws kms get-key-rotation-status --key-id $KEY_ID
- KMS → Customer managed keys → Create key — type Symmetric, usage Encrypt/decrypt, alias
deepdive, key administrators/usage defaults rehne do, Create karo. - Key kholo, Key rotation tab se automatic rotation ON kar sakte ho. Encrypt/decrypt ke liye console mein direct UI nahi hai (CLI/SDK se hi hota hai) — key sirf yahin banti hai.
Default key policy dhyan se padho. Usme "Principal": {"AWS": "arn:aws:iam::<account>:root"} ko kms:* diya gaya hai, jiska matlab hai ki "is account ki IAM policies tay karengi ki key kaun use kar sakta hai". Tumne dekha hoga ki decrypt karte waqt key ID nahi deni padi; iski wajah yeh hai ki symmetric ciphertext ke andar hi key ka reference hota hai. Rotation chalu hone pe har saal naya key material banta hai, lekin purana ciphertext phir bhi decrypt ho jaata hai, kyunki KMS purana material bhi sambhal ke rakhta hai.
- Decrypt ne original text wapas de diya.
- Tumne key policy ka "Enable IAM User Permissions" statement padha aur samjha.
- Rotation status
truedikha raha hai.
KMS seedha sirf 4 KB tak ka data encrypt karta hai, aur har call network pe jaata hai. Isliye S3, EBS aur RDS jaisi services envelope encryption use karti hain. Isme KMS se ek data key li jaati hai, jo do roop mein aati hai: ek plaintext copy aur ek encrypted copy. Plaintext key se data ko apne computer pe hi encrypt kiya jaata hai, phir plaintext key ko memory se hata diya jaata hai, aur encrypted key ko data ke saath hi store kar diya jaata hai. Decrypt karte waqt KMS se sirf data key decrypt karwayi jaati hai, aur baaki kaam locally hota hai.
Neeche ka Python script (jaise envelope.py naam se save karke chalao) 5 MB random data ko isi tareeke se encrypt karke big.enc mein likhta hai, aur phir use padh ke decrypt karta hai aur check karta hai ki data wahi hai:
import os
import boto3
from cryptography.hazmat.primitives.ciphers.aead import AESGCM
kms = boto3.client("kms", region_name="us-east-1")
# --- encrypt ---
data = os.urandom(5 * 1024 * 1024) # 5 MB "file"
dk = kms.generate_data_key(KeyId="alias/deepdive", KeySpec="AES_256")
nonce = os.urandom(12)
ciphertext = AESGCM(dk["Plaintext"]).encrypt(nonce, data, None)
encrypted_key = dk["CiphertextBlob"]
del dk # plaintext key memory se hatao
with open("big.enc", "wb") as f:
f.write(len(encrypted_key).to_bytes(2, "big") + encrypted_key + nonce + ciphertext)
print("encrypted file:", os.path.getsize("big.enc"), "bytes; KMS calls: 1")
# --- decrypt ---
raw = open("big.enc", "rb").read()
klen = int.from_bytes(raw[:2], "big")
enc_key, nonce, ct = raw[2:2 + klen], raw[2 + klen:14 + klen], raw[14 + klen:]
key = kms.decrypt(CiphertextBlob=enc_key)["Plaintext"]
assert AESGCM(key).decrypt(nonce, ct, None) == data
print("decrypted OK — data matches")
- 5 MB ka encrypt aur decrypt sirf 2 KMS calls mein ho gaya (ek generate ke liye aur ek decrypt ke liye).
- Tum samjha sakte ho ki encrypted data key ko file ke andar hi store karna safe kyun hai (kyunki use kholne ke liye KMS ki permission chahiye).
Real incidents mein sabse zyada uljhan paida karne wala error yeh hota hai: "S3 GetObject allowed hai, phir bhi AccessDenied aa raha hai". Iski wajah aksar yeh hoti hai ki object KMS key se encrypted hai aur request karne wale ke paas kms:Decrypt ki permission nahi hai. Is step mein tum yahi problem jaan-boojh ke paida karoge aur theek karoge.
Neeche ki commands pehle ek bucket banati hain jiska default encryption tumhari KMS key hai, usme file upload karti hain aur check karti hain ki woh KMS se encrypt hui. Phir ek test role deepdive-kms-test banaya jaata hai jise sirf S3 read ki permission hai, aur uske liye ek CLI profile kmstest joda jaata hai. Us profile se file padhne pe KMS wala AccessDenied aata hai. Aakhir mein role ko kms:Decrypt dene ke baad wahi command chal jaati hai:
export KMS_BUCKET=deepdive-kms-$ACCOUNT_ID
aws s3 mb s3://$KMS_BUCKET
KEY_ARN=$(aws kms describe-key --key-id alias/deepdive --query KeyMetadata.Arn --output text)
aws s3api put-bucket-encryption --bucket $KMS_BUCKET --server-side-encryption-configuration \
"{\"Rules\":[{\"ApplyServerSideEncryptionByDefault\":{\"SSEAlgorithm\":\"aws:kms\",\"KMSMasterKeyID\":\"$KEY_ARN\"},\"BucketKeyEnabled\":true}]}"
aws s3 cp plain.txt s3://$KMS_BUCKET/plain.txt
aws s3api head-object --bucket $KMS_BUCKET --key plain.txt --query '[ServerSideEncryption,SSEKMSKeyId,BucketKeyEnabled]'
# Test role: S3 read haan, KMS nahi
cat > kms-test-trust.json <<EOF
{"Version":"2012-10-17","Statement":[{"Effect":"Allow","Principal":{"AWS":"arn:aws:iam::$ACCOUNT_ID:root"},"Action":"sts:AssumeRole"}]}
EOF
cat > kms-test-s3.json <<EOF
{"Version":"2012-10-17","Statement":[{"Effect":"Allow","Action":"s3:GetObject","Resource":"arn:aws:s3:::$KMS_BUCKET/*"}]}
EOF
aws iam create-role --role-name deepdive-kms-test --assume-role-policy-document file://kms-test-trust.json
aws iam put-role-policy --role-name deepdive-kms-test --policy-name s3read --policy-document file://kms-test-s3.json
cat >> ~/.aws/config <<EOF
[profile kmstest]
role_arn = arn:aws:iam::$ACCOUNT_ID:role/deepdive-kms-test
source_profile = default
region = us-east-1
EOF
sleep 10
aws s3 cp s3://$KMS_BUCKET/plain.txt - --profile kmstest
# → AccessDenied ... not authorized to perform: kms:Decrypt (error mein key ARN bhi hoga)
cat > kms-test-decrypt.json <<EOF
{"Version":"2012-10-17","Statement":[{"Effect":"Allow","Action":"kms:Decrypt","Resource":"$KEY_ARN"}]}
EOF
aws iam put-role-policy --role-name deepdive-kms-test --policy-name kmsdecrypt --policy-document file://kms-test-decrypt.json
sleep 10
aws s3 cp s3://$KMS_BUCKET/plain.txt - --profile kmstest # ab chalega
Ab CloudTrail mein Event history kholo, Event source mein kms.amazonaws.com chuno aur Decrypt events dekho; har event batata hai ki kisne, kab aur kaunsi key use ki. Bucket pe Bucket Key chalu hone ki wajah se S3 har object ke liye alag KMS call nahi karta, jisse KMS ka kharcha 99% tak kam ho sakta hai.
- head-object ke output mein
aws:kmsaur tumhari key ka ARN dikha. - Bina kms:Decrypt ke AccessDenied aaya, aur policy jodne ke baad file padh li gayi.
- Tumne CloudTrail mein KMS ka Decrypt event dekha.
B IAM advanced: permission boundaries + Access Analyzer
Company sandboxes aksar yahi tareeka apnaate hain: tumhe roles banane dete hain, lekin sirf ek permission boundary ke saath. Boundary kisi identity ki permissions ki chhat (ceiling) hoti hai. Asli (effective) permission woh hoti hai jo identity policy aur boundary, dono mein allowed ho (aur agar SCP ya session policy hai, toh unme bhi). Isse developers roles bana sakte hain, lekin khud ko admin nahi bana sakte, yaani privilege escalation ruk jaata hai.
Neeche ki commands ek boundary policy banati hain jo sirf S3, CloudWatch aur Logs allow karti hai. Phir deepdive-bounded-admin naam ka role is boundary ke saath banaya jaata hai aur use poora AdministratorAccess diya jaata hai. Uske baad us role ke profile se teen commands chala ke dekho ki kya chalta hai aur kya nahi:
cat > boundary.json <<'EOF'
{"Version":"2012-10-17","Statement":[
{"Effect":"Allow","Action":["s3:*","cloudwatch:*","logs:*"],"Resource":"*"}
]}
EOF
BOUNDARY=$(aws iam create-policy --policy-name DeepdiveDevBoundary --policy-document file://boundary.json \
--query Policy.Arn --output text)
aws iam create-role --role-name deepdive-bounded-admin \
--assume-role-policy-document file://kms-test-trust.json --permissions-boundary $BOUNDARY
aws iam attach-role-policy --role-name deepdive-bounded-admin --policy-arn arn:aws:iam::aws:policy/AdministratorAccess
- IAM → Roles → Create role → Custom trust policy —
kms-test-trust.jsonpaste karo, permissions meinAdministratorAccessattach karo. Naam se pehle Set permissions boundary (Advanced settings ke neeche) kholo, "Use a permissions boundary" chuno aurDeepdiveDevBoundaryselect karo, phir Create role.
cat >> ~/.aws/config <<EOF
[profile bounded]
role_arn = arn:aws:iam::$ACCOUNT_ID:role/deepdive-bounded-admin
source_profile = default
region = us-east-1
EOF
sleep 10
aws s3 ls --profile bounded | head -3 # ✅ boundary mein hai
aws ec2 describe-instances --profile bounded --max-items 1 # ❌ Admin hai phir bhi deny
aws iam list-users --profile bounded # ❌
Error message dhyan se padho; usme likha hoga "no permissions boundary allows the ec2:DescribeInstances action". Ab agar sandbox mein aisa error dikhe, toh tum samajh jaaoge ki tumhari permission boundary tumhe rok rahi hai.
- S3 wali command chal gayi, jabki EC2 aur IAM wali commands "permissions boundary" wale error ke saath deny hui.
Jab account mein hazaaron buckets, keys aur roles hon, toh yeh pata lagana mushkil hota hai ki kaunsa resource account ke bahar (kisi doosre account ya public ke saath) share ho raha hai. Access Analyzer resource policies ka mathematical analysis karke yahi batata hai. External-access analyzer muft hai.
Neeche ki commands ek analyzer banati hain, ek naya bucket banake uski policy mein ek AWS-owned account ko read access deti hain, ek minute ruk ke phir analyzer ki findings dikhati hain:
aws accessanalyzer create-analyzer --analyzer-name deepdive-analyzer --type ACCOUNT
export SHARE_BUCKET=deepdive-share-$ACCOUNT_ID
aws s3 mb s3://$SHARE_BUCKET
# Ek AWS-owned account (us-east-1 Elastic Load Balancing, ALB logs ke liye use hota hai) ko read dete hain
cat > share-policy.json <<EOF
{"Version":"2012-10-17","Statement":[{"Effect":"Allow",
"Principal":{"AWS":"arn:aws:iam::127311923021:root"},
"Action":"s3:GetObject","Resource":"arn:aws:s3:::$SHARE_BUCKET/*"}]}
EOF
aws s3api put-bucket-policy --bucket $SHARE_BUCKET --policy file://share-policy.json
sleep 60
ANALYZER=$(aws accessanalyzer list-analyzers --query "analyzers[?name=='deepdive-analyzer'].arn" --output text)
aws accessanalyzer list-findings --analyzer-arn $ANALYZER \
--query 'findings[].[resourceType,resource,status,principal]' --output json
Finding mein dikhega ki tumhara bucket account 127311923021 ke saath share ho raha hai. Ab aws s3api delete-bucket-policy --bucket $SHARE_BUCKET chala ke bucket policy hata do; kuch minute mein finding ka status RESOLVED ho jaayega.
Access Analyzer ka ek aur feature hai policy validation, jo policy likhte waqt hi galtiyan pakad leta hai. Neeche wali policy mein jaan-boojh ke ek typo aur ek khatarnak permission rakhi gayi hai:
cat > sloppy.json <<'EOF'
{"Version":"2012-10-17","Statement":[
{"Effect":"Allow","Action":["s3:GetObjekt","iam:PassRole"],"Resource":"*"}]}
EOF
aws accessanalyzer validate-policy --policy-type IDENTITY_POLICY --policy-document file://sloppy.json \
--query 'findings[].[findingType,issueCode]' --output table
- Access Analyzer ne external access ki finding di, aur policy hatane pe woh resolved ho gayi.
- validate-policy ne galat spelling wale action ko ERROR ke roop mein, aur
*peiam:PassRoleko SECURITY_WARNING ke roop mein pakda.
C IAM Identity Center (SSO) — human access ka sahi tareeka
Socho 50 engineers hain aur 10 accounts. Kya 500 IAM users aur 500 access keys banaoge? Bilkul nahi. IAM Identity Center mein users aur groups ek hi jagah rehte hain (ya tum company ka Okta, Entra ID ya Google Workspace jod sakte ho). Wahan permission sets (policies ke templates) bante hain, aur assignments kuch is tarah ke hote hain: "group X ko account Y mein permission set Z do". Log ek portal se login karte hain aur har baar unhe temporary credentials milte hain; koi long-term key nahi hoti. Kisi ke naukri chhodne pe sirf ek user disable karna padta hai. Tumhare company sandbox ka login bhi isi tareeke se hota hai.
- Yeh step personal account mein karo, jahan Lab 1 ke G1 mein Organization bana tha. IAM Identity Center kholo, Enable dabao, "Enable with AWS Organizations" chuno aur region us-east-1 rakho.
- Users → Add user mein username
deepdive-devrakho, email daalo (Gmail ka alias bhi chalega), Generate a one-time password chuno, Add dabao aur one-time password (OTP) copy kar lo. - Groups → Create group mein
Developersnaam ka group banao aur usme deepdive-dev ko jodo. - Settings → Authentication → MFA mein "Every time they sign in" chuno; agar yeh pehle se default hai toh waise hi rehne do.
- User aur group ban gaye, aur tumne AWS access portal ka URL (
https://d-xxxx.awsapps.com/start) note kar liya.
- Permission sets → Create mein Predefined chuno,
ViewOnlyAccessselect karo, session duration 1 hour rakho aur Create karo. - AWS accounts mein apna account select karo, Assign users or groups dabao, Groups mein Developers chuno, permission set ViewOnlyAccess chuno aur Submit karo. Parde ke peeche Identity Center tumhare account mein ek
AWSReservedSSO_ViewOnlyAccess_...role bana deta hai, jise tum IAM → Roles mein dekh sakte ho. - Ek private ya incognito window kholo, portal URL pe jao, deepdive-dev aur OTP se login karo, naya password set karo, MFA register karo, phir account aur ViewOnlyAccess chun ke console mein jao.
- Console mein ek S3 bucket banane ki koshish karo; yeh deny ho jaayega. Lekin EC2 ki list tum dekh sakte ho.
CLI se bhi SSO login ho sakta hai. Pehli command ek SSO profile set up karti hai (woh portal URL, region us-east-1, account aur ViewOnlyAccess poochhegi). Baaki commands dikhati hain ki tum kaun ho, read kaam chalta hai, aur bucket banana deny hota hai:
aws configure sso --profile idc-dev # portal URL, region us-east-1, account, ViewOnlyAccess
aws sts get-caller-identity --profile idc-dev # assumed-role/AWSReservedSSO_ViewOnlyAccess_...
aws s3 ls --profile idc-dev
aws s3 mb s3://deepdive-idc-test-$ACCOUNT_ID --profile idc-dev # AccessDenied
- Tumne portal se MFA ke saath login kiya aur ViewOnly console khula.
- CLI ke SSO profile se read commands chali, lekin write deny hua.
- Tumne IAM roles mein
AWSReservedSSO_...role dekha.
D Cognito: app users, JWT, protected API
Identity Center tumhare employees ko AWS accounts ka access dene ke liye hai. Cognito user pools tumhari app ke customers ke sign-up aur sign-in ke liye hain (password, MFA, ya Google aur Apple jaise social login). Login hone pe Cognito JWT tokens deta hai (ID token, access token aur refresh token). API Gateway us JWT ko verify karta hai, aur sahi hone pe hi request ko aage jaane deta hai.
Neeche ki commands ek user pool banati hain jisme email hi username hai, ek app client banati hain jo username-password se login allow karta hai, ek test user asha@example.com banake uska pakka password set karti hain, us user se login karke ID token leti hain, aur aakhir mein token ke beech wale hisse (payload) ko decode karke dikhati hain:
POOL=$(aws cognito-idp create-user-pool --pool-name deepdive-users \
--policies 'PasswordPolicy={MinimumLength=8,RequireUppercase=true,RequireLowercase=true,RequireNumbers=true,RequireSymbols=false}' \
--auto-verified-attributes email --username-attributes email \
--query UserPool.Id --output text); echo $POOL
CLIENT=$(aws cognito-idp create-user-pool-client --user-pool-id $POOL --client-name deepdive-cli \
--explicit-auth-flows ALLOW_USER_PASSWORD_AUTH ALLOW_REFRESH_TOKEN_AUTH --no-generate-secret \
--query UserPoolClient.ClientId --output text); echo $CLIENT
- Cognito → User pools → Create user pool — sign-in option Email, password policy customize karo, MFA optional/off (lab ke liye), naam
deepdive-usersrakho. - Pool ke App integration tab → Create app client — naam
deepdive-cli, "Don't generate a client secret" tick karo, auth flows mein ALLOW_USER_PASSWORD_AUTH aur ALLOW_REFRESH_TOKEN_AUTH tick karo. - Pool ke Users tab → Create user se test user bhi console se ban sakta hai (email verified tick karke, permanent password set karke).
aws cognito-idp admin-create-user --user-pool-id $POOL --username asha@example.com \
--user-attributes Name=email,Value=asha@example.com Name=email_verified,Value=true --message-action SUPPRESS
aws cognito-idp admin-set-user-password --user-pool-id $POOL --username asha@example.com \
--password 'Deepdive2026x' --permanent
TOKEN=$(aws cognito-idp initiate-auth --auth-flow USER_PASSWORD_AUTH --client-id $CLIENT \
--auth-parameters USERNAME=asha@example.com,PASSWORD=Deepdive2026x \
--query AuthenticationResult.IdToken --output text)
# JWT = header.payload.signature — payload decode karo
echo $TOKEN | cut -d. -f2 | python3 -c "import sys,base64,json; s=sys.stdin.read().strip(); s+='='*(-len(s)%4); print(json.dumps(json.loads(base64.urlsafe_b64decode(s)), indent=1))"
Payload mein iss (issuer, yaani user pool ka URL), aud (app client ka ID), email aur exp (expiry, jo 1 ghante baad ki hoti hai) dikhenge. Token ka teesra hissa, yaani signature, Cognito ki private key se banta hai, isliye agar koi payload mein kuch bhi badlega toh signature ki jaanch fail ho jaayegi.
- Tumhe IdToken mila, aur decoded payload mein iss, aud, email aur exp dikhe.
Neeche ki commands pehle ek chhota Lambda deepdive-whoami banati hain jo token ke claims mein se email aur sub wapas bhejta hai (isme Lab 5 wala deepdive-lambda-basic role use hota hai). Phir ek HTTP API banaya jaata hai jo seedha is Lambda se juda hai, aur API Gateway ko Lambda chalane ki permission di jaati hai. Uske baad Cognito wala JWT authorizer banake API ke route pe lagaya jaata hai. Aakhir mein teen curl requests se test hota hai: bina token, sahi token, aur chhede gaye token ke saath:
cat > whoami.py <<'EOF'
import json
def lambda_handler(event, context):
claims = event["requestContext"]["authorizer"]["jwt"]["claims"]
return {"statusCode": 200, "headers": {"Content-Type": "application/json"},
"body": json.dumps({"hello": claims.get("email"), "sub": claims.get("sub")})}
EOF
zip -q whoami.zip whoami.py
LAMBDA_ROLE=$(aws iam get-role --role-name deepdive-lambda-basic --query Role.Arn --output text 2>/dev/null)
# Lab 5 E1 wala role nahi hai? Wahan ke pehle 4 commands chala ke bana lo.
aws lambda create-function --function-name deepdive-whoami --runtime python3.13 \
--handler whoami.lambda_handler --role $LAMBDA_ROLE --zip-file fileb://whoami.zip
aws lambda wait function-active --function-name deepdive-whoami
FN_ARN=$(aws lambda get-function --function-name deepdive-whoami --query Configuration.FunctionArn --output text)
API_ID=$(aws apigatewayv2 create-api --name deepdive-secure-api --protocol-type HTTP \
--target $FN_ARN --query ApiId --output text) # quick create: $default route + stage
aws lambda add-permission --function-name deepdive-whoami --statement-id apigw \
--action lambda:InvokeFunction --principal apigateway.amazonaws.com \
--source-arn "arn:aws:execute-api:us-east-1:$ACCOUNT_ID:$API_ID/*"
AUTH_ID=$(aws apigatewayv2 create-authorizer --api-id $API_ID --name cognito --authorizer-type JWT \
--identity-source '$request.header.Authorization' \
--jwt-configuration Audience=$CLIENT,Issuer=https://cognito-idp.us-east-1.amazonaws.com/$POOL \
--query AuthorizerId --output text)
ROUTE_ID=$(aws apigatewayv2 get-routes --api-id $API_ID --query 'Items[0].RouteId' --output text)
aws apigatewayv2 update-route --api-id $API_ID --route-id $ROUTE_ID \
--authorization-type JWT --authorizer-id $AUTH_ID
URL=https://$API_ID.execute-api.us-east-1.amazonaws.com
sleep 5
curl -s -w " [%{http_code}]\n" $URL/ # 401 Unauthorized
curl -s -w " [%{http_code}]\n" -H "Authorization: $TOKEN" $URL/ # 200 + email
curl -s -w " [%{http_code}]\n" -H "Authorization: ${TOKEN}x" $URL/ # 401 (signature tooti)
Dhyan do ki Lambda ko token khud verify nahi karna pada. API Gateway ne signature, issuer, audience aur expiry check kiye, aur sab sahi hone pe hi Lambda ko claims bheje. Web aur mobile apps ke liye Cognito ka managed login (bana-banaya sign-in page) aur social login bhi yahin se configure kiye jaate hain.
- Bina token ke 401 aaya, sahi token ke saath 200 aaya (email ke saath), aur chhede gaye token pe 401 aaya.
E WAF: SQL/XSS, rate limiting, IP blocking
- API Gateway mein Create API dabao, REST API ke neeche Build chuno, New API chuno, naam
deepdive-restrakho, endpoint type Regional rakho aur Create karo. /hellonaam ka resource banao, usme GET method banao, integration type Mock chuno aur Create karo.- GET method mein Integration response kholo, default response ko Edit karo, Mapping templates mein
application/jsonjodo, body mein{"message": "hello from mock"}likho aur Save karo. - Deploy API dabao, naya stage
prodbanao aur Invoke URL copy kar lo.
Ab URL ko variable mein rakho (xxxx ki jagah apna API ID) aur API ko test karo:
REST=https://xxxx.execute-api.us-east-1.amazonaws.com/prod
curl -s $REST/hello
WAF ko ALB, CloudFront, REST API Gateway, AppSync aur Cognito pe lagaya ja sakta hai, lekin HTTP API pe nahi. Isiliye yahan REST API banaya gaya hai.
- Jawab mein
{"message": "hello from mock"}aaya.
Web ACL ka lagbhag $5 per month, har rule ka $1 per month (ghante ke hisaab se), aur har 10 lakh requests ka $0.60 lagta hai. 2–3 ghante chalane ka kharcha lagbhag $0.05 hoga. Yeh part khatam hote hi ise delete kar dena.
- WAF & Shield mein Web ACLs kholo (naye console mein inhe "protection packs" bhi kaha ja sakta hai) aur Create dabao. Regional resources aur us-east-1 chuno, naam
deepdive-wafrakho, aur Add AWS resources mein API Gateway kadeepdive-rest - prodchuno. - Rules mein Add managed rule groups → AWS managed kholo aur Core rule set, Known bad inputs aur SQL database jodo.
- Add my own rules mein ek Rate-based rule banao jiska naam
deepdive-rateho, limit 10 aur evaluation window 1 minute ho, jo source IP ke hisaab se gine aur action Block ho. - Default action Allow rakho, CloudWatch metrics aur sampled requests chalu rakho, aur Create karo.
Ab ek normal request, ek XSS attack wali request aur ek SQL injection wali request bhejo. Phir ek minute ruk ke 40 requests jaldi-jaldi bhejo aur dekho ki kitne 200 aur kitne 403 aaye:
curl -s -o /dev/null -w "%{http_code} normal\n" "$REST/hello"
curl -s -o /dev/null -w "%{http_code} XSS\n" "$REST/hello?q=%3Cscript%3Ealert(1)%3C%2Fscript%3E"
curl -s -o /dev/null -w "%{http_code} SQLi\n" "$REST/hello?id=1%27%20OR%20%271%27%3D%271"
sleep 60
for i in $(seq 1 40); do curl -s -o /dev/null -w "%{http_code}\n" "$REST/hello"; sleep 0.5; done | sort | uniq -c
Normal request pe 200 aayega, jabki XSS aur SQLi wali requests turant 403 se block hongi. Rate wale loop mein lagbhag 30–60 second baad 403 aane lagenge. Web ACL ke Sampled requests ya Overview mein dekho ki kaunse rule ne kya block kiya.
- XSS aur SQLi wali requests 403 se block hui.
- Rate limit paar hone ke baad 403 aane lage.
- Tumne sampled requests mein match hone wale rule ka naam dekha.
- WAF mein IP sets → Create kholo, naam
deepdive-blocklistrakho, region us-east-1 chuno aur apna IP<TUMHARA_IP>/32ke roop mein daalo. - deepdive-waf ke Rules mein Add my own rules → IP set rule chuno, blocklist select karo, action Block rakho aur is rule ko priority mein sabse upar rakho.
curl $REST/hellochalao; ab 403 aayega. Phir rule hata do aur dobara chalao; ab 200 aayega.
- IP block rule ne tumhe block kiya, aur rule hatane pe tum unblock ho gaye.
F AWS Config: compliance rules + remediation
- AWS Config mein Get started / Set up kholo. Recording strategy mein Specific resource types chuno aur sirf
AWS::EC2::SecurityGroupaurAWS::S3::Bucketjodo; recording frequency Continuous rakho. - Data governance mein naya service-linked role banne do, Delivery mein Create a bucket chuno aur Next dabao.
- Rules mein
restricted-sshaurs3-bucket-versioning-enabledsearch karke jodo aur Confirm karo.
Config ka kharcha har configuration item ka lagbhag $0.003 aur har rule evaluation ka lagbhag $0.001 hota hai, isliye is lab mein sirf kuch cents lagenge.
- Recorder "Recording" status mein hai, dono rules Active hain, aur kuch minute baad compliance ke results aa gaye.
Neeche ki commands default VPC mein deepdive-bad-sg naam ka security group banati hain aur usme poori duniya ke liye SSH (port 22) khol deti hain. 2–5 minute baad aakhri command restricted-ssh rule ke NON_COMPLIANT resources dikhati hai:
VPC_ID=$(aws ec2 describe-vpcs --filters Name=isDefault,Values=true --query 'Vpcs[0].VpcId' --output text)
BAD_SG=$(aws ec2 create-security-group --group-name deepdive-bad-sg --description "open ssh" \
--vpc-id $VPC_ID --query GroupId --output text)
aws ec2 authorize-security-group-ingress --group-id $BAD_SG --protocol tcp --port 22 --cidr 0.0.0.0/0
# 2-5 min:
aws configservice get-compliance-details-by-config-rule --config-rule-name restricted-ssh \
--compliance-types NON_COMPLIANT --query 'EvaluationResults[].EvaluationResultIdentifier.EvaluationResultQualifier.ResourceId'
Ise theek karne (remediation) ke liye AWS ka bana-banaya SSM Automation runbook chalao. Yeh SG se port 22 wala rule hata deta hai. Phir SG ke rules dekho aur rule ka evaluation dobara chalao:
aws ssm start-automation-execution --document-name AWS-DisableIncomingSSHOnPort22 \
--parameters SecurityGroupIds=$BAD_SG
aws ec2 describe-security-groups --group-ids $BAD_SG --query 'SecurityGroups[0].IpPermissions' # []
aws configservice start-config-rules-evaluation --config-rule-names restricted-ssh
Ab Config mein Resources kholo, deepdive-bad-sg chuno aur uski Resource timeline dekho. Usme har configuration change dikhta hai, aur saath mein us change ka CloudTrail event bhi, jisse pata chalta hai ki change kisne kiya. Production mein rule pe automatic remediation lagaya jaata hai (Manage remediation mein yahi runbook aur ek automation role chun ke), taaki agar koi SSH khole, toh woh kuch hi minute mein apne aap band ho jaaye.
- Bad SG NON_COMPLIANT dikha, aur runbook ke baad uske rules khaali ho gaye aur woh COMPLIANT ho gaya.
- Tumne resource timeline mein changes ki history dekhi.
- Tumne note kiya ki versioning wale rule ne kaunse buckets ko NON_COMPLIANT bataya.
G GuardDuty + Security Hub
GuardDuty CloudTrail, VPC Flow Logs aur DNS logs ko machine learning aur threat intelligence ki madad se lagataar analyse karta hai. Woh aisi baatein pakadta hai jaise "tumhara EC2 kisi crypto-mining pool se baat kar raha hai", "root credentials kisi ajeeb IP se use hue", ya "instance ke credentials AWS ke bahar se use ho rahe hain". Iske liye kuch install nahi karna padta, aur pehle 30 din muft trial hota hai.
Neeche ki commands GuardDuty chalu karti hain, kuch sample (nakli) findings banati hain, unki ginti batati hain, aur pehli paanch findings ki severity, type aur title ki table dikhati hain:
DET=$(aws guardduty create-detector --enable --query DetectorId --output text); echo $DET
aws guardduty create-sample-findings --detector-id $DET
- GuardDuty console pehli baar kholne pe seedha Enable GuardDuty button dikhata hai — ek click mein chalu ho jaata hai.
- Settings tab mein Sample findings → Generate sample findings se sample findings bhi console se ban jaati hain.
sleep 30
aws guardduty list-findings --detector-id $DET --query 'length(FindingIds)'
IDS=$(aws guardduty list-findings --detector-id $DET --max-results 5 --query FindingIds --output text)
aws guardduty get-findings --detector-id $DET --finding-ids $IDS \
--query 'Findings[].[Severity,Type,Title]' --output table
Console mein GuardDuty → Findings kholo. Har finding ki severity (Low, Medium, High ya Critical), uske type ka naam (jo ThreatPurpose:ResourceType/ThreatFamily.Variant format mein hota hai), prabhavit resource aur sujhaaya gaya remediation dekho. Jin findings ke aage [SAMPLE] likha hai, woh nakli hain.
Optional real finding: kisi bhi chalte EC2 instance pe Session Manager se dig guarddutyc2activityb.com chalao. Yeh AWS ka documented test domain hai. 15–30 minute mein tumhare instance ID ke saath ek asli Backdoor:EC2/C&CActivity.B!DNS finding aani chahiye.
- Sample findings list hui, aur tumne kam se kam ek High severity finding padhi.
- (Optional) Tumhare instance pe DNS pe aadharit ek asli finding aayi.
Security Hub (console mein iska naam "Security Hub CSPM" bhi dikh sakta hai) best-practice standards, jaise AWS Foundational Security Best Practices aur CIS, ke controls ko lagataar check karta hai. Saath hi woh GuardDuty, Config, Access Analyzer aur Inspector ki findings ko ek jagah le aata hai. Iska bhi 30 din ka muft trial hai. Controls check karne ke liye Config recorder chalu hona chahiye, isiliye Part F pehle karwaya gaya.
Neeche ki pehli command Security Hub ko default standards ke saath chalu karti hai, aur doosri dikhati hai ki kaunse standards chalu hue:
aws securityhub enable-security-hub --enable-default-standards
aws securityhub get-enabled-standards --query 'StandardsSubscriptions[].[StandardsArn,StandardsStatus]' --output table
Controls ko evaluate hone mein kuch ghante lagte hain, isliye yeh hissa kal dekhna. Security Hub ke Summary mein security score (percentage mein) dikhega. Controls mein fail hue controls dikhenge, jaise IAM.6 (root ke liye hardware MFA), S3.x aur EC2.x, aur har control ke saath use theek karne ka link hoga. Findings mein GuardDuty ki findings bhi dikhengi (product = GuardDuty).
- Default standards chalu ho gaye.
- (Agle din) Tumne security score aur top 5 fail hue controls note kiye.
H (Optional) Control Tower landing zone
Control Tower ka setup 30–60 minute leta hai aur isme 2 naye email addresses chahiye (Log Archive aur Audit accounts ke liye). Yeh har governed account aur region mein AWS Config aur CloudTrail ke resources banata hai, aur agar chalta rahe toh har mahine kuch dollars ka kharcha hota hai. Ise band (decommission) kiya ja sakta hai, lekin naye bane accounts ko alag se close karna padta hai, aur close hone ke baad woh 90 din tak suspended rehte hain. Yeh sirf personal account mein karo. Conflict se bachne ke liye Part F ka Config recorder pehle delete kar do (cleanup list mein tareeka diya hai).
- Control Tower mein Set up landing zone kholo. Home region us-east-1 rakho, Region deny ko off rakho, aur governed regions mein sirf us-east-1 chuno.
- OUs mein Foundational OU ka naam
Securityaur Additional OU ka naamSandboxrakho. - Shared accounts (Log Archive aur Audit) ke liye naye email aliases do, jaise
you+ctlog@gmail.comauryou+ctaudit@gmail.com. - CloudTrail mein organization-level trail chalu rakho, aur kharcha bachane ke liye KMS encryption off rakho. Review karke Set up landing zone dabao; isme lagbhag 30–60 minute lagenge.
- Landing zone ka status Available hai, aur Organizations mein Security aur Sandbox OUs aur 2 naye accounts dikh rahe hain.
- Control library mein "Strongly recommended" filter lagao aur koi control chuno, jaise "Disallow public read access to Amazon S3 buckets" (jo detective control hai) ya koi preventive control. Phir Enable on OU dabake use Sandbox OU pe chalu karo.
- Account Factory → Create account mein naam
deepdive-sbxrakho, ek email alias do, OU mein Sandbox chuno aur Create karo; isme lagbhag 20 minute lagte hain. Phir IAM Identity Center se is account mein login karke dekho ki guardrails pehle se lage hue hain. - Dashboard pe noncompliant resources aur har OU pe chalu controls dekho.
Decommission: kaam khatam hone pe Control Tower ki Settings/Landing zone mein Decommission landing zone chuno aur wahan diya gaya process follow karo. Uske baad Organizations mein jaake Log Archive, Audit aur deepdive-sbx accounts ko close karo.
- Sandbox OU pe ek control chalu hai.
- Account Factory se ek naya account ban gaya.
- (Khatam karne pe) Tumne landing zone decommission kiya aur accounts close kiye.
I Break & Fix, Challenge, Explain
aws kms disable-key --key-id $KEY_ID chala ke key ko disable karo, aur phir admin user se bhi aws s3 cp s3://$KMS_BUCKET/plain.txt - chalao. Tumhe KMSInvalidStateException ya AccessDenied milega. Tum admin ho ya nahi, key ke bina encrypted data kisi kaam ka nahi rehta. Isiliye KMS key ko delete karne se pehle 7–30 din ka waiting period hota hai, taaki galti se data hamesha ke liye na kho jaaye. aws kms enable-key --key-id $KEY_ID se key ko wapas chalu kar do.
create-user-pool-client se other-app naam ka ek doosra app client banao, uske ID se login karke token lo, aur woh token D2 wale API ko bhejo. Tumhe 401 milega, kyunki authorizer ka Audience sirf pehle client ka ID accept karta hai. Isse yeh seekh milti hai ki JWT authorizer sirf yeh nahi dekhta ki user kaun hai, balki yeh bhi dekhta hai ki token kis app ke liye bana tha.
Teen kaam bina steps dekhe karo. 1. Ek EventBridge rule banao jo 7 ya usse zyada severity wali GuardDuty findings ko SNS se email pe bheje. Pattern mein "source": ["aws.guardduty"] aur "detail": {"severity": [{"numeric": [">=", 7]}]} use karo, aur sample findings dobara bana ke test karo. 2. Config rule restricted-ssh pe automatic remediation configure karo (iske liye ek automation role banana padega), phir bad SG dobara banao aur dekho ki woh kitne minute mein apne aap band hota hai. 3. Lab 3 ke RDS ka ek snapshot copy banao jo tumhari customer-managed KMS key se encrypted ho (copy-db-snapshot --kms-key-id se).
- KMS mein key policy aur IAM policy ka aapas mein kya rishta hai? Agar "S3 allowed hai phir bhi AccessDenied" aaye, toh tum kya-kya check karoge?
- Envelope encryption kya hai, aur iski zaroorat kyun padti hai?
- Permission boundary, SCP aur identity policy mein kya farak hai, aur effective permission kaise nikalti hai?
- IAM Identity Center, IAM users aur Cognito mein se kaun kiske liye hai?
- JWT ke teen hisse kaunse hain, aur API Gateway ka JWT authorizer kya-kya verify karta hai?
- WAF kahan-kahan lagaya ja sakta hai, aur rate-based rule kaise kaam karta hai?
- Config aur CloudTrail mein kya farak hai? (Config batata hai "kya badla", CloudTrail batata hai "kisne kiya".)
- GuardDuty, Security Hub, Inspector aur Macie ko ek-ek line mein samjhao. (Inspector EC2, ECR aur Lambda mein vulnerabilities scan karta hai, aur Macie S3 mein sensitive data dhoondhta hai.)
- WAF: web ACL se resource ko disassociate karo, phir web ACL aur IP set delete karo. REST API
deepdive-restbhi delete karo. - Cognito/API:
aws apigatewayv2 delete-api --api-id $API_IDchalao, Lambdadeepdive-whoamidelete karo, auraws cognito-idp delete-user-pool --user-pool-id $POOLchalao. - GuardDuty: trial khatam hone se pehle
aws guardduty delete-detector --detector-id $DETchalao, warna charge lagne lagega. - Security Hub:
aws securityhub disable-security-hubchalao. - Config: pehle rules delete karo. Phir kram se
aws configservice stop-configuration-recorder --configuration-recorder-name default,delete-delivery-channel --delivery-channel-name defaultaurdelete-configuration-recorder --configuration-recorder-name defaultchalao (recorder ka naamdescribe-configuration-recordersse confirm kar lena). Uske baad Config ka bucket khaali karke delete karo, aur SGdeepdive-bad-sgbhi delete karo. - KMS:
aws s3 rb s3://$KMS_BUCKET --forcese bucket hatao, phiraws kms schedule-key-deletion --key-id $KEY_ID --pending-window-in-days 7se key ka deletion schedule karo. - IAM: roles
deepdive-kms-testaurdeepdive-bounded-adminse inline aur attached policies hatake unhe delete karo, policyDeepdiveDevBoundarydelete karo, aur~/.aws/configsekmstest,boundedauridc-devprofiles hata do. - Access Analyzer: analyzer ko rakh sakte ho kyunki woh muft hai, lekin bucket
deepdive-share-...delete kar do. - Identity Center: pehle assignment hatao, phir permission set delete karo, aur phir user aur group delete karo. Identity Center ko khud chalu rehne do, kyunki woh muft hai.
- Control Tower: agar tumne Part H kiya tha, toh landing zone decommission karo aur teeno accounts close karo (H2 dekho).