Detecting EC2 Instances Exposed to Unrestricted SSH Access

4 minute read
Content level: Intermediate
1

Unrestricted SSH access to EC2 instances can create significant security vulnerabilities, exposing your infrastructure to potential attacks. This article provides a method to identify instances at risk by using a Bash script and AWS CLI. By following this guide, you will learn how to detect EC2 instances with open SSH ports and enhance your cloud security.

Introduction

Ensuring secure SSH access to EC2 instances is crucial for maintaining cloud security. This article offers a step-by-step guide to identify instances with security groups that permit inbound SSH access from any IP address. Using a Bash script and AWS CLI, you will discover how to find instances exposed to potential threats, helping you better manage your cloud environment.

Prerequisites

Before you begin, make sure you have the following:

  • IAM Permissions: Ensure you have the necessary permissions to access AWS Config, EC2, and AWS CLI.
  • AWS CLI installed and configured on your machine.
  • Basic knowledge of Bash scripting.

Step 1: Enable the AWS Config Rule

To identify EC2 instances exposed to unrestricted SSH access, first ensure that the AWS Config rule called restricted-ssh is enabled in your AWS account. This rule helps you monitor and identify security groups that allow SSH access from anywhere (TCP port 22 from IP address 0.0.0.0/0) . If the rule is not already active, follow AWS’s documentation to enable it and start receiving compliance evaluations for your security groups.

Step 2: Create the Bash Script

The following Bash script helps identify EC2 instances associated with security groups that permit unrestricted SSH access. It retrieves the relevant security groups and lists the instances linked to them.

#!/bin/bash

# Function to display usage information
usage() {
  echo "Usage: $0 -r <region>"
  exit 1
}

# Parse command-line arguments
while getopts "r:" opt; do
  case $opt in
    r) REGION="$OPTARG" ;;
    *) usage ;;
  esac
done

# Check if region was provided
if [ -z "$REGION" ]; then
  echo "Error: Region is required."
  usage
fi

# Step 1: Get the list of security groups that have an inbound rule allowing SSH from anywhere
SG_IDS=$(aws configservice get-compliance-details-by-config-rule \
  --region $REGION \
  --config-rule-name restricted-ssh \
  --compliance-types NON_COMPLIANT \
  --query 'EvaluationResults[].EvaluationResultIdentifier.EvaluationResultQualifier.ResourceId' \
  --output text)

# Step 2: Loop through each security group and find the instances associated with it
for SG_ID in $SG_IDS; do
  # Get the security group name
  SG_NAME=$(aws ec2 describe-security-groups \
    --region $REGION \
    --group-ids $SG_ID \
    --query 'SecurityGroups[0].GroupName' \
    --output text)

  INSTANCE_IDS=$(aws ec2 describe-instances \
    --region $REGION \
    --filters Name=instance.group-id,Values=$SG_ID \
    --query 'Reservations[*].Instances[*].[InstanceId, Tags[?Key==`Name`].Value | [0]]' \
    --output text)

  # Check if any instances were found with the security group
  if [ -n "$INSTANCE_IDS" ]; then
    while read -r INSTANCE_ID INSTANCE_NAME; do
      if [ -z "$INSTANCE_NAME" ]; then
        INSTANCE_NAME="No_Name"
      fi
      echo "Security Group: $SG_ID ($SG_NAME) => Instance: $INSTANCE_ID ($INSTANCE_NAME)"
    done <<< "$INSTANCE_IDS"
  else
    echo "Security Group: $SG_ID ($SG_NAME) => No instances found"
  fi
done

Step 3: Running the Script

To run the script, save it as find_ssh_instances.sh and execute it with the required region flag:

bash find_ssh_instances.sh -r <your-region>

Replace <your-region> with the AWS region you're working in (e.g., us-east-1).

Example Output

When you run the script, it will output a list of security group to instance mappings:

Security Group: sg-00949c20db67e88a4 (my-sg-name) => Instance: i-07608871ec814f6a8 (my-instance-name)
Security Group: sg-0d08633048febd06d (another-sg-name) => Instance: i-0123456789abcdef0 (another-instance-name)
Security Group: sg-0abc1234abcd5678 (unused-sg-name) => No instances found

Conclusion

By using this script, you can easily detect EC2 instances at risk due to unrestricted SSH access. Regularly running this script can help maintain a secure environment and comply with best practices.