Thursday, 6 March 2025

How will you restrict access of a user who has the private key of an EC2 server?


A compromised EC2 private key is a critical security incident that demands immediate action and long-term safeguards. This guide provides a deep dive into mitigating risks, hardening your environment, and adopting advanced strategies to prevent future breaches. We’ll cover technical steps, real-world examples, and AWS-native tools to secure your infrastructure.

Table of Contents

  1. Immediate Response: Contain the Damage

    • Revoke the Key & Replace the Instance
    • Audit Active Sessions and Keys
  2. Network Layer Restrictions

    • Security Groups: IP Whitelisting & Port Rules
    • NACLs: Subnet-Level Firewalls
    • VPNs, Bastion Hosts, and VPC Peering
  3. IAM & Identity Hardening

    • Enforce MFA for SSH/RDP Access
    • Least Privilege IAM Policies
    • AWS Systems Manager (SSM) Session Manager
  4. SSH/RDP Configuration Hardening

    • Disable Password Logins
    • Restrict Users & Commands
    • SSH Certificates vs. Static Keys
  5. OS-Level Security

    • User Permissions & Sudoers File
    • File Integrity Monitoring (FIM)
  6. Monitoring & Incident Response

    • AWS CloudTrail, GuardDuty, and CloudWatch
    • OS Logs and Fail2ban
  7. Long-Term Strategies

    • Key Rotation & Automation
    • Zero-Trust Architectures
    • Third-Party Tools (HashiCorp Vault, Teleport)
  8. Advanced Scenarios

    • IMDSv2 for SSRF Protection
    • Cross-Account Access Mitigation

1. Immediate Response: Contain the Damage

Step 1: Revoke the Key & Replace the Instance

AWS does not allow key rotation on running instances. Follow these steps:

  1. Stop the Instance:
    aws ec2 stop-instances --instance-id i-0abcdef1234567890
    
  2. Create an AMI for data recovery:
    aws ec2 create-image --instance-id i-0abcdef1234567890 --name "Recovery-AMI"
    
  3. Launch a New Instance with a new key pair.
  4. Attach the Old Volume to recover data:
    aws ec2 attach-volume --volume-id vol-123456 --instance-id i-0newinstance --device /dev/sdf
    

Step 2: Audit Active Sessions and Keys

  1. Check Active SSH Sessions:
    who -u  # Lists logged-in users
    sudo netstat -tnpa | grep 'ESTABLISHED.*ssh'
    
  2. Remove Compromised Keys from ~/.ssh/authorized_keys:
    sudo nano /home/ec2-user/.ssh/authorized_keys  # Delete the leaked public key
    

2. Network Layer Restrictions

Security Groups: Restrict Inbound Traffic

Modify the security group to allow SSH/RDP only from trusted IPs.

Example: Whitelist office IPs and a bastion host:

[
  {
    "FromPort": 22,
    "ToPort": 22,
    "IpProtocol": "tcp",
    "IpRanges": [
      {
        "CidrIp": "203.0.113.10/32",  // Office IP
        "Description": "Corporate Network"
      }
    ],
    "SourceSecurityGroupId": "sg-0abcdef1234567890"  // Bastion host SG
  }
]

NACLs: Subnet-Level Firewalls

Use NACLs to block public SSH access at the subnet level.

Inbound Rules:

Rule # Type Protocol Port Source Allow/Deny
100 SSH TCP 22 203.0.113.10/32 ALLOW
200 SSH TCP 22 0.0.0.0/0 DENY

Outbound Rules:

Rule # Type Protocol Port Destination Allow/Deny
100 All All All 0.0.0.0/0 ALLOW

Bastion Host Architecture

  1. Deploy a bastion host in a public subnet with strict security group rules.
  2. Configure private instances to allow SSH only from the bastion’s security group.
  3. Use SSH agent forwarding or AWS Session Manager for secure access.

3. IAM & Identity Hardening

Enforce MFA for SSH/RDP Access

IAM Policy: Require MFA for EC2 Instance Connect:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "RequireMFAForEC2Connect",
      "Effect": "Deny",
      "Action": [
        "ec2-instance-connect:SendSSHPublicKey",
        "ec2:AssociateIamInstanceProfile"
      ],
      "Resource": "*",
      "Condition": {
        "BoolIfExists": {"aws:MultiFactorAuthPresent": "false"}
      }
    }
  ]
}

Least Privilege IAM Roles

Attach IAM roles with minimal permissions:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "ssm:StartSession",
        "ssm:SendCommand"
      ],
      "Resource": "arn:aws:ec2:us-east-1:123456789012:instance/*"
    }
  ]
}

AWS Systems Manager (SSM) Session Manager

Eliminate SSH keys entirely using SSM:

  1. Attach the AmazonSSMManagedInstanceCore policy to the instance role.
  2. Start a secure session:
    aws ssm start-session --target i-0abcdef1234567890
    

4. SSH/RDP Configuration Hardening

Disable Password Authentication

Edit /etc/ssh/sshd_config:

PasswordAuthentication no
PermitRootLogin no
AllowUsers ec2-user admin  # Restrict valid users

Reload SSH:

sudo systemctl reload sshd

Restrict Commands via authorized_keys

Prepend forced commands in ~/.ssh/authorized_keys:

command="echo 'Command not allowed'" ssh-rsa AAAAB3Nz... user@host

SSH Certificates (Advanced)

Replace static keys with short-lived certificates using OpenSSH:

  1. Generate a CA Key:
    ssh-keygen -t ed25519 -f ca_key
    
  2. Sign User Keys:
    ssh-keygen -s ca_key -I "user@example.com" -n ec2-user -V +1h user_key.pub
    
  3. Configure sshd_config:
    TrustedUserCAKeys /etc/ssh/ca_key.pub
    

5. OS-Level Security

Restrict Sudo Access

Edit /etc/sudoers to limit privileges:

# Allow 'admin' to run only specific commands
admin ALL=(ALL) /usr/bin/apt, /usr/bin/systemctl

File Integrity Monitoring (FIM)

Use tools like Tripwire or AWS CloudTrail Logs to detect unauthorized changes:

# Monitor /etc/ssh/sshd_config
sudo tripwire --check

6. Monitoring & Incident Response

AWS GuardDuty

Enable GuardDuty to detect:

  • Unusual API activity (e.g., StopLogging).
  • Geographic anomalies in SSH logins.

CloudWatch Alarms

Trigger alerts for failed SSH attempts:

aws cloudwatch put-metric-alarm \
  --alarm-name "SSH-Brute-Force" \
  --metric-name "SSHAttempts" \
  --namespace "AWS/EC2" \
  --statistic "Sum" \
  --period 300 \
  --threshold 5 \
  --comparison-operator "GreaterThanThreshold" \
  --evaluation-periods 1

Fail2ban for Brute-Force Protection

Install and configure Fail2ban:

sudo apt install fail2ban
sudo nano /etc/fail2ban/jail.local  # Set bantime = 3600, maxretry = 3
sudo systemctl restart fail2ban

7. Long-Term Strategies

Key Rotation Automation

Use AWS Lambda to enforce key rotation every 90 days:

import boto3
def rotate_keys(event, context):
    ec2 = boto3.client('ec2')
    old_keys = ec2.describe_key_pairs()['KeyPairs']
    # Logic to create new keys and replace old ones

Zero-Trust Architecture

  • Microsegmentation: Isolate instances using private subnets and VPC peering.
  • Teleport: Implement SSH certificate-based access with audit logs.

Third-Party Tools

  • HashiCorp Vault: Manage dynamic SSH keys and secrets.
  • AWS Certificate Manager (ACM): Issue TLS certificates for encrypted traffic.

8. Advanced Scenarios

IMDSv2 for SSRF Protection

Upgrade to IMDSv2 to block server-side request forgery:

aws ec2 modify-instance-metadata-options \
  --instance-id i-0abcdef1234567890 \
  --http-tokens required \
  --http-endpoint enabled

Cross-Account Access Mitigation

Use IAM roles and resource policies to restrict cross-account actions:

{
  "Effect": "Deny",
  "Principal": {"AWS": "arn:aws:iam::123456789012:root"},
  "Action": "ec2:*",
  "Condition": {"StringNotEquals": {"aws:PrincipalAccount": "987654321098"}}
}

Final Checklist & Best Practices

  1. Immediate: Replace keys, restrict IPs, audit logs.
  2. Network: Use bastion hosts, NACLs, and VPNs.
  3. IAM: Enforce MFA and least privilege.
  4. SSH: Disable passwords, use certificates.
  5. Monitoring: Enable GuardDuty, CloudTrail, and Fail2ban.
  6. Automation: Rotate keys, patch instances, and use SSM.

By adopting these strategies, you transform a potential breach into an opportunity to fortify your AWS environment. Stay proactive, automate security, and embrace zero-trust principles to stay ahead of threats.

Labels:

0 Comments:

Post a Comment

Note: only a member of this blog may post a comment.

<< Home