ikb42603-cloud-security-essentials

v2026.09.24

AWS cloud security lab exercises covering IAM, VPC, encryption, monitoring, and incident detection for hands-on security learning

GitHub
安装命令
npx skhub add reason-machines/ikb42603-cloud-security-essentials
Markdown
SKILL.md

IKB42603 Cloud Security Essentials Skill

Skill by ara.so — Security Skills collection.

Overview

IKB42603-CLOUD-COMPUTING-SECURITY-ESSENTIALS is an educational repository containing hands-on laboratory exercises for learning AWS cloud security fundamentals. The project covers five core security domains: IAM and account security, secure isolation and multitenancy, encryption and key management, access control and network security, and monitoring/logging/incident detection.

This skill helps developers and students complete practical AWS security implementations using the AWS Console, AWS CLI, and infrastructure-as-code approaches.

Repository Structure

The project is organized into five lab modules:

IKB42603-CLOUD-COMPUTING-SECURITY-ESSENTIALS/
├── README.md
├── Lab0_Environment_Setup.md
├── Lab1_Account_Security_and_IAM.md
├── Lab2_Secure_Isolation_and_Multitenancy.md
├── Lab3_Encryption_and_Key_Management.md
├── Lab4_Access_Control_and_Network_Security.md
└── Lab5_Monitoring_Logging_and_Incident_Detection.md

Installation & Setup

Clone the Repository

git clone https://github.com/<username>/IKB42603-CLOUD-COMPUTING-SECURITY-ESSENTIALS.git
cd IKB42603-CLOUD-COMPUTING-SECURITY-ESSENTIALS

Prerequisites

  • AWS Account (Free Tier eligible)
  • AWS CLI installed and configured
  • Git for version control
  • Text editor (VS Code, Vim, etc.)

Configure AWS CLI

# Configure AWS credentials
aws configure

# Verify configuration
aws sts get-caller-identity

Lab 1: Account Security and IAM

Create IAM Users with Policies

# Create a new IAM user
aws iam create-user --user-name security-admin

# Create a custom policy document
cat > security-admin-policy.json <<EOF
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "iam:*",
        "cloudtrail:*",
        "cloudwatch:*"
      ],
      "Resource": "*"
    }
  ]
}
EOF

# Create and attach the policy
aws iam create-policy \
  --policy-name SecurityAdminPolicy \
  --policy-document file://security-admin-policy.json

aws iam attach-user-policy \
  --user-name security-admin \
  --policy-arn arn:aws:iam::${AWS_ACCOUNT_ID}:policy/SecurityAdminPolicy

Enable MFA for Root Account

# Create virtual MFA device
aws iam create-virtual-mfa-device \
  --virtual-mfa-device-name root-mfa \
  --outfile mfa-qr.png \
  --bootstrap-method QRCodePNG

# Enable MFA (requires MFA codes from authenticator app)
aws iam enable-mfa-device \
  --user-name root \
  --serial-number arn:aws:iam::${AWS_ACCOUNT_ID}:mfa/root-mfa \
  --authentication-code1 <CODE1> \
  --authentication-code2 <CODE2>

Create IAM Groups with Least Privilege

# Create developer group
aws iam create-group --group-name Developers

# Attach managed policies
aws iam attach-group-policy \
  --group-name Developers \
  --policy-arn arn:aws:iam::aws:policy/AmazonEC2ReadOnlyAccess

# Add user to group
aws iam add-user-to-group \
  --user-name security-admin \
  --group-name Developers

Lab 2: Secure Isolation and Multitenancy

Create Isolated VPC

# Create VPC
aws ec2 create-vpc \
  --cidr-block 10.0.0.0/16 \
  --tag-specifications 'ResourceType=vpc,Tags=[{Key=Name,Value=SecureVPC}]'

# Create public subnet
aws ec2 create-subnet \
  --vpc-id <VPC_ID> \
  --cidr-block 10.0.1.0/24 \
  --availability-zone us-east-1a \
  --tag-specifications 'ResourceType=subnet,Tags=[{Key=Name,Value=PublicSubnet}]'

# Create private subnet
aws ec2 create-subnet \
  --vpc-id <VPC_ID> \
  --cidr-block 10.0.2.0/24 \
  --availability-zone us-east-1a \
  --tag-specifications 'ResourceType=subnet,Tags=[{Key=Name,Value=PrivateSubnet}]'

# Create internet gateway
aws ec2 create-internet-gateway \
  --tag-specifications 'ResourceType=internet-gateway,Tags=[{Key=Name,Value=SecureIGW}]'

# Attach to VPC
aws ec2 attach-internet-gateway \
  --internet-gateway-id <IGW_ID> \
  --vpc-id <VPC_ID>

Configure Security Groups

# Create web tier security group
aws ec2 create-security-group \
  --group-name web-tier-sg \
  --description "Security group for web tier" \
  --vpc-id <VPC_ID>

# Allow HTTPS from anywhere
aws ec2 authorize-security-group-ingress \
  --group-id <SG_ID> \
  --protocol tcp \
  --port 443 \
  --cidr 0.0.0.0/0

# Create database tier security group
aws ec2 create-security-group \
  --group-name db-tier-sg \
  --description "Security group for database tier" \
  --vpc-id <VPC_ID>

# Allow MySQL only from web tier
aws ec2 authorize-security-group-ingress \
  --group-id <DB_SG_ID> \
  --protocol tcp \
  --port 3306 \
  --source-group <WEB_SG_ID>

Create Network ACLs

# Create network ACL
aws ec2 create-network-acl \
  --vpc-id <VPC_ID> \
  --tag-specifications 'ResourceType=network-acl,Tags=[{Key=Name,Value=PrivateNACL}]'

# Add inbound rule
aws ec2 create-network-acl-entry \
  --network-acl-id <NACL_ID> \
  --ingress \
  --rule-number 100 \
  --protocol tcp \
  --port-range From=443,To=443 \
  --cidr-block 10.0.1.0/24 \
  --rule-action allow

# Add outbound rule
aws ec2 create-network-acl-entry \
  --network-acl-id <NACL_ID> \
  --egress \
  --rule-number 100 \
  --protocol tcp \
  --port-range From=1024,To=65535 \
  --cidr-block 0.0.0.0/0 \
  --rule-action allow

Lab 3: Encryption and Key Management

Create KMS Key

# Create customer managed key
aws kms create-key \
  --description "Data encryption key for Lab 3" \
  --key-usage ENCRYPT_DECRYPT \
  --origin AWS_KMS

# Create alias
aws kms create-alias \
  --alias-name alias/lab3-encryption-key \
  --target-key-id <KEY_ID>

# Set key policy
cat > key-policy.json <<EOF
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "Enable IAM User Permissions",
      "Effect": "Allow",
      "Principal": {
        "AWS": "arn:aws:iam::${AWS_ACCOUNT_ID}:root"
      },
      "Action": "kms:*",
      "Resource": "*"
    },
    {
      "Sid": "Allow use of the key for encryption",
      "Effect": "Allow",
      "Principal": {
        "AWS": "arn:aws:iam::${AWS_ACCOUNT_ID}:user/security-admin"
      },
      "Action": [
        "kms:Encrypt",
        "kms:Decrypt",
        "kms:GenerateDataKey"
      ],
      "Resource": "*"
    }
  ]
}
EOF

aws kms put-key-policy \
  --key-id <KEY_ID> \
  --policy-name default \
  --policy file://key-policy.json

Encrypt S3 Bucket with KMS

# Create S3 bucket
aws s3api create-bucket \
  --bucket secure-data-bucket-${AWS_ACCOUNT_ID} \
  --region us-east-1

# Enable default encryption with KMS
aws s3api put-bucket-encryption \
  --bucket secure-data-bucket-${AWS_ACCOUNT_ID} \
  --server-side-encryption-configuration '{
    "Rules": [{
      "ApplyServerSideEncryptionByDefault": {
        "SSEAlgorithm": "aws:kms",
        "KMSMasterKeyID": "alias/lab3-encryption-key"
      },
      "BucketKeyEnabled": true
    }]
  }'

# Upload encrypted file
aws s3 cp sensitive-data.txt \
  s3://secure-data-bucket-${AWS_ACCOUNT_ID}/ \
  --server-side-encryption aws:kms \
  --ssekms-key-id alias/lab3-encryption-key

Encrypt EBS Volume

# Create encrypted EBS volume
aws ec2 create-volume \
  --availability-zone us-east-1a \
  --size 10 \
  --volume-type gp3 \
  --encrypted \
  --kms-key-id alias/lab3-encryption-key \
  --tag-specifications 'ResourceType=volume,Tags=[{Key=Name,Value=EncryptedVolume}]'

# Attach to EC2 instance
aws ec2 attach-volume \
  --volume-id <VOLUME_ID> \
  --instance-id <INSTANCE_ID> \
  --device /dev/sdf

Encrypt Data at Application Level

# Encrypt plaintext using KMS
aws kms encrypt \
  --key-id alias/lab3-encryption-key \
  --plaintext fileb://plaintext.txt \
  --output text \
  --query CiphertextBlob > encrypted.bin

# Decrypt ciphertext
aws kms decrypt \
  --ciphertext-blob fileb://encrypted.bin \
  --output text \
  --query Plaintext | base64 --decode

Lab 4: Access Control and Network Security

Create VPC Endpoints

# Create S3 Gateway Endpoint
aws ec2 create-vpc-endpoint \
  --vpc-id <VPC_ID> \
  --service-name com.amazonaws.us-east-1.s3 \
  --route-table-ids <ROUTE_TABLE_ID>

# Create Interface Endpoint for Secrets Manager
aws ec2 create-vpc-endpoint \
  --vpc-id <VPC_ID> \
  --vpc-endpoint-type Interface \
  --service-name com.amazonaws.us-east-1.secretsmanager \
  --subnet-ids <SUBNET_ID> \
  --security-group-ids <SG_ID>

Configure AWS WAF

# Create IP set
aws wafv2 create-ip-set \
  --name BlockedIPs \
  --scope REGIONAL \
  --ip-address-version IPV4 \
  --addresses 192.0.2.0/24 203.0.113.0/24

# Create web ACL
aws wafv2 create-web-acl \
  --name SecurityLabWAF \
  --scope REGIONAL \
  --default-action Allow={} \
  --rules file://waf-rules.json \
  --visibility-config SampledRequestsEnabled=true,CloudWatchMetricsEnabled=true,MetricName=SecurityLabWAF

Configure AWS Systems Manager Session Manager

# Create IAM role for EC2
cat > ec2-role-trust.json <<EOF
{
  "Version": "2012-10-17",
  "Statement": [{
    "Effect": "Allow",
    "Principal": {"Service": "ec2.amazonaws.com"},
    "Action": "sts:AssumeRole"
  }]
}
EOF

aws iam create-role \
  --role-name SSMRole \
  --assume-role-policy-document file://ec2-role-trust.json

aws iam attach-role-policy \
  --role-name SSMRole \
  --policy-arn arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore

# Start session without SSH
aws ssm start-session --target <INSTANCE_ID>

Lab 5: Monitoring, Logging, and Incident Detection

Enable CloudTrail

# Create S3 bucket for logs
aws s3api create-bucket \
  --bucket cloudtrail-logs-${AWS_ACCOUNT_ID} \
  --region us-east-1

# Apply bucket policy
cat > trail-bucket-policy.json <<EOF
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "AWSCloudTrailAclCheck",
      "Effect": "Allow",
      "Principal": {"Service": "cloudtrail.amazonaws.com"},
      "Action": "s3:GetBucketAcl",
      "Resource": "arn:aws:s3:::cloudtrail-logs-${AWS_ACCOUNT_ID}"
    },
    {
      "Sid": "AWSCloudTrailWrite",
      "Effect": "Allow",
      "Principal": {"Service": "cloudtrail.amazonaws.com"},
      "Action": "s3:PutObject",
      "Resource": "arn:aws:s3:::cloudtrail-logs-${AWS_ACCOUNT_ID}/*",
      "Condition": {
        "StringEquals": {"s3:x-amz-acl": "bucket-owner-full-control"}
      }
    }
  ]
}
EOF

aws s3api put-bucket-policy \
  --bucket cloudtrail-logs-${AWS_ACCOUNT_ID} \
  --policy file://trail-bucket-policy.json

# Create trail
aws cloudtrail create-trail \
  --name security-audit-trail \
  --s3-bucket-name cloudtrail-logs-${AWS_ACCOUNT_ID} \
  --is-multi-region-trail \
  --enable-log-file-validation

aws cloudtrail start-logging --name security-audit-trail

Configure CloudWatch Alarms

# Create SNS topic for alerts
aws sns create-topic --name SecurityAlerts

aws sns subscribe \
  --topic-arn arn:aws:sns:us-east-1:${AWS_ACCOUNT_ID}:SecurityAlerts \
  --protocol email \
  --notification-endpoint ${ALERT_EMAIL}

# Create metric filter for unauthorized API calls
aws logs put-metric-filter \
  --log-group-name CloudTrail/DefaultLogGroup \
  --filter-name UnauthorizedAPICalls \
  --filter-pattern '{ ($.errorCode = "*UnauthorizedOperation") || ($.errorCode = "AccessDenied*") }' \
  --metric-transformations \
    metricName=UnauthorizedAPICalls,metricNamespace=CloudTrailMetrics,metricValue=1

# Create alarm
aws cloudwatch put-metric-alarm \
  --alarm-name UnauthorizedAPICallsAlarm \
  --alarm-description "Triggers when unauthorized API calls are detected" \
  --metric-name UnauthorizedAPICalls \
  --namespace CloudTrailMetrics \
  --statistic Sum \
  --period 300 \
  --threshold 1 \
  --comparison-operator GreaterThanOrEqualToThreshold \
  --evaluation-periods 1 \
  --alarm-actions arn:aws:sns:us-east-1:${AWS_ACCOUNT_ID}:SecurityAlerts

Query CloudTrail Logs with Athena

-- Create Athena table for CloudTrail logs
CREATE EXTERNAL TABLE cloudtrail_logs (
  eventversion STRING,
  useridentity STRUCT<
    type:STRING,
    principalid:STRING,
    arn:STRING,
    accountid:STRING,
    username:STRING>,
  eventtime STRING,
  eventsource STRING,
  eventname STRING,
  awsregion STRING,
  sourceipaddress STRING,
  useragent STRING,
  errorcode STRING,
  errormessage STRING,
  requestparameters STRING,
  responseelements STRING
)
ROW FORMAT SERDE 'com.amazon.emr.hive.serde.CloudTrailSerde'
STORED AS INPUTFORMAT 'com.amazon.emr.cloudtrail.CloudTrailInputFormat'
OUTPUTFORMAT 'org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat'
LOCATION 's3://cloudtrail-logs-${AWS_ACCOUNT_ID}/AWSLogs/${AWS_ACCOUNT_ID}/CloudTrail/';

-- Query failed login attempts
SELECT 
  eventtime,
  useridentity.username,
  sourceipaddress,
  errorcode,
  errormessage
FROM cloudtrail_logs
WHERE eventname = 'ConsoleLogin'
  AND errorcode IS NOT NULL
ORDER BY eventtime DESC
LIMIT 50;

Configure AWS GuardDuty

# Enable GuardDuty
aws guardduty create-detector --enable

# Get detector ID
DETECTOR_ID=$(aws guardduty list-detectors --query 'DetectorIds[0]' --output text)

# Create threat intelligence set
aws guardduty create-threat-intel-set \
  --detector-id ${DETECTOR_ID} \
  --name CustomThreatList \
  --format TXT \
  --location s3://threat-intel-bucket/threats.txt \
  --activate

# List findings
aws guardduty list-findings \
  --detector-id ${DETECTOR_ID} \
  --finding-criteria '{"Criterion":{"severity":{"Gte":7}}}'

Common Patterns

Secure EC2 Instance Launch

# Launch EC2 with security best practices
aws ec2 run-instances \
  --image-id ami-0c55b159cbfafe1f0 \
  --instance-type t3.micro \
  --subnet-id <PRIVATE_SUBNET_ID> \
  --security-group-ids <RESTRICTED_SG_ID> \
  --iam-instance-profile Name=SSMRole \
  --metadata-options HttpTokens=required,HttpPutResponseHopLimit=1 \
  --block-device-mappings '[
    {
      "DeviceName": "/dev/xvda",
      "Ebs": {
        "VolumeSize": 20,
        "VolumeType": "gp3",
        "Encrypted": true,
        "KmsKeyId": "alias/lab3-encryption-key",
        "DeleteOnTermination": true
      }
    }
  ]' \
  --tag-specifications 'ResourceType=instance,Tags=[{Key=Name,Value=SecureInstance}]'

Rotate IAM Access Keys

#!/bin/bash
# Rotate access keys for a user

USER_NAME="security-admin"

# Create new access key
NEW_KEY=$(aws iam create-access-key --user-name ${USER_NAME} --output json)
NEW_ACCESS_KEY=$(echo ${NEW_KEY} | jq -r '.AccessKey.AccessKeyId')
NEW_SECRET_KEY=$(echo ${NEW_KEY} | jq -r '.AccessKey.SecretAccessKey')

echo "New Access Key: ${NEW_ACCESS_KEY}"
echo "New Secret Key: ${NEW_SECRET_KEY}"

# Update AWS credentials file
aws configure set aws_access_key_id ${NEW_ACCESS_KEY} --profile ${USER_NAME}
aws configure set aws_secret_access_key ${NEW_SECRET_KEY} --profile ${USER_NAME}

# List old access keys
OLD_KEYS=$(aws iam list-access-keys --user-name ${USER_NAME} --query 'AccessKeyMetadata[?AccessKeyId!=`'${NEW_ACCESS_KEY}'`].AccessKeyId' --output text)

# Deactivate old keys (after testing new key)
for KEY in ${OLD_KEYS}; do
  aws iam update-access-key --user-name ${USER_NAME} --access-key-id ${KEY} --status Inactive
  echo "Deactivated old key: ${KEY}"
done

Automated Security Group Auditing

#!/bin/bash
# Audit security groups for overly permissive rules

echo "Auditing Security Groups for 0.0.0.0/0 access..."

aws ec2 describe-security-groups --query 'SecurityGroups[*].[GroupId,GroupName,IpPermissions]' --output json | \
jq -r '.[] | select(.[2][]?.IpRanges[]?.CidrIp == "0.0.0.0/0") | "Security Group: \(.[1]) (\(.[0])) has unrestricted access"'

Troubleshooting

IAM Permission Errors

# Decode authorization failure message
aws sts decode-authorization-message \
  --encoded-message <ENCODED_MESSAGE> \
  --query DecodedMessage \
  --output text | jq '.'

VPC Connectivity Issues

# Check route tables
aws ec2 describe-route-tables --filters "Name=vpc-id,Values=<VPC_ID>"

# Check NACLs
aws ec2 describe-network-acls --filters "Name=vpc-id,Values=<VPC_ID>"

# Check security group rules
aws ec2 describe-security-groups --group-ids <SG_ID>

# Test connectivity with VPC Reachability Analyzer
aws ec2 create-network-insights-path \
  --source <SOURCE_ENI_ID> \
  --destination <DEST_ENI_ID> \
  --protocol tcp \
  --destination-port 443

aws ec2 start-network-insights-analysis \
  --network-insights-path-id <PATH_ID>

KMS Key Access Issues

# List key grants
aws kms list-grants --key-id alias/lab3-encryption-key

# Get key policy
aws kms get-key-policy \
  --key-id alias/lab3-encryption-key \
  --policy-name default \
  --output text | jq '.'

# Check key state
aws kms describe-key --key-id alias/lab3-encryption-key

CloudTrail Logging Not Working

# Get trail status
aws cloudtrail get-trail-status --name security-audit-trail

# Validate S3 bucket policy
aws s3api get-bucket-policy \
  --bucket cloudtrail-logs-${AWS_ACCOUNT_ID} \
  --output text | jq '.'

# Check CloudTrail event selectors
aws cloudtrail get-event-selectors --trail-name security-audit-trail

Environment Variables

# Set AWS credentials
export AWS_ACCESS_KEY_ID=your_access_key
export AWS_SECRET_ACCESS_KEY=your_secret_key
export AWS_DEFAULT_REGION=us-east-1
export AWS_ACCOUNT_ID=$(aws sts get-caller-identity --query Account --output text)

# Lab-specific variables
export VPC_ID=vpc-xxxxx
export SUBNET_ID=subnet-xxxxx
export KMS_KEY_ALIAS=alias/lab3-encryption-key
export ALERT_EMAIL=security@example.com

Documentation Best Practices

Each lab should include:

# Lab X: [Title]

## Objective
Brief description of what you'll learn

## Prerequisites
- AWS account configured
- IAM permissions required
- Any other dependencies

## Implementation Steps

### Step 1: [Task Name]
\`\`\`bash
# Commands with explanations
\`\`\`

### Step 2: [Task Name]
Screenshots and evidence

## Verification
How to verify the implementation works

## Cleanup
Commands to remove resources and avoid charges

## Lessons Learned
Key takeaways and security insights

## References
- AWS documentation links
- Security best practices

Best Practices

  1. Always use least privilege: Grant minimum permissions required
  2. Enable MFA: For all human users, especially privileged accounts
  3. Encrypt data: At rest and in transit using KMS
  4. Use private subnets: For resources that don't need internet access
  5. Enable logging: CloudTrail, VPC Flow Logs, and application logs
  6. Automate security: Use AWS Config rules and Security Hub
  7. Regular audits: Review IAM policies, security groups, and access logs
  8. Tag resources: For cost allocation and security tracking
  9. Use Systems Manager: Instead of SSH for instance access
  10. Clean up resources: Delete unused resources to avoid costs

Additional Resources

发现
标签

此技能尚未发布标签。

版本
最新版本元数据

版本

v2026.09.24

发布时间

Sep 24, 2026

分类

未分类

许可证

NOASSERTION

源路径

skills/ikb42603-cloud-security-essentials

默认分支

main

最新提交

304c245

Tree SHA

010f47d