Ensure No EC2 Instances Allow Ingress from the Internet to Cassandra Ports
Overview
This check identifies EC2 instances that have Cassandra database ports accessible from the internet through their security group rules. Cassandra uses several TCP ports for different functions:
| Port | Purpose |
|---|---|
| 7000 | Inter-node cluster communication |
| 7001 | TLS inter-node cluster communication |
| 7199 | JMX monitoring |
| 9042 | CQL native transport (client queries) |
| 9160 | Thrift client API (legacy) |
When these ports are open to 0.0.0.0/0 (all IPv4) or ::/0 (all IPv6), anyone on the internet can attempt to connect to your Cassandra database.
Risk
Exposing Cassandra ports to the internet creates serious security risks:
- Data theft: Attackers can query your database and steal sensitive information
- Data manipulation: Unauthorized users can modify or delete your data
- Cluster compromise: JMX port (7199) exposure allows remote management and potential takeover
- Lateral movement: A compromised Cassandra node can be used to attack other systems in your VPC
- Ransomware: Attackers may encrypt your data and demand payment
This is rated as critical severity because databases should never be directly accessible from the internet.
Remediation Steps
Prerequisites
You need:
- Access to the AWS Console with permissions to modify EC2 security groups
- Knowledge of which IP addresses or CIDR ranges legitimately need Cassandra access
Required IAM permissions
To modify security groups, your IAM user or role needs these permissions:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"ec2:DescribeSecurityGroups",
"ec2:DescribeSecurityGroupRules",
"ec2:RevokeSecurityGroupIngress",
"ec2:AuthorizeSecurityGroupIngress"
],
"Resource": "*"
}
]
}
AWS Console Method
- Sign in to the AWS Console and go to EC2
- In the left navigation, click Instances
- Select the flagged EC2 instance
- Click the Security tab at the bottom of the page
- Under Security groups, click on the security group link
- Select the Inbound rules tab
- Click Edit inbound rules
- Find any rules that:
- Have Source set to
0.0.0.0/0or::/0 - Allow ports 7000, 7001, 7199, 9042, or 9160
- Have Source set to
- For each problematic rule, either:
- Delete it by clicking the Delete button on that row
- Restrict it by changing the Source to a specific IP or CIDR (e.g.,
10.0.0.0/8)
- Click Save rules
Important: Before removing rules, confirm that no legitimate users or applications rely on internet access to these ports. Consider using a VPN, AWS PrivateLink, or bastion host for remote access instead.
AWS CLI method
First, identify the security group and problematic rules:
# Find security groups with Cassandra ports open to the internet
aws ec2 describe-security-groups \
--region us-east-1 \
--filters "Name=ip-permission.cidr,Values=0.0.0.0/0" \
--query "SecurityGroups[?IpPermissions[?contains([`7000`,`7001`,`7199`,`9042`,`9160`], to_string(FromPort))]].{GroupId:GroupId,GroupName:GroupName}" \
--output table
Remove the unrestricted rules for each Cassandra port:
# Replace <SECURITY_GROUP_ID> with your actual security group ID
# Remove unrestricted access to port 7000 (inter-node communication)
aws ec2 revoke-security-group-ingress \
--region us-east-1 \
--group-id <SECURITY_GROUP_ID> \
--protocol tcp \
--port 7000 \
--cidr 0.0.0.0/0
# Remove unrestricted access to port 7001 (TLS inter-node)
aws ec2 revoke-security-group-ingress \
--region us-east-1 \
--group-id <SECURITY_GROUP_ID> \
--protocol tcp \
--port 7001 \
--cidr 0.0.0.0/0
# Remove unrestricted access to port 7199 (JMX)
aws ec2 revoke-security-group-ingress \
--region us-east-1 \
--group-id <SECURITY_GROUP_ID> \
--protocol tcp \
--port 7199 \
--cidr 0.0.0.0/0
# Remove unrestricted access to port 9042 (CQL)
aws ec2 revoke-security-group-ingress \
--region us-east-1 \
--group-id <SECURITY_GROUP_ID> \
--protocol tcp \
--port 9042 \
--cidr 0.0.0.0/0
# Remove unrestricted access to port 9160 (Thrift)
aws ec2 revoke-security-group-ingress \
--region us-east-1 \
--group-id <SECURITY_GROUP_ID> \
--protocol tcp \
--port 9160 \
--cidr 0.0.0.0/0
To add restricted access for trusted networks:
# Add access from a trusted CIDR (e.g., your VPC CIDR)
aws ec2 authorize-security-group-ingress \
--region us-east-1 \
--group-id <SECURITY_GROUP_ID> \
--protocol tcp \
--port 9042 \
--cidr 10.0.0.0/8
CloudFormation template
This template creates a security group with Cassandra ports restricted to trusted CIDR blocks:
AWSTemplateFormatVersion: '2010-09-09'
Description: Secure EC2 Security Group - Cassandra ports restricted
Parameters:
VpcId:
Type: AWS::EC2::VPC::Id
Description: VPC where the security group will be created
TrustedCidr:
Type: String
Description: Trusted CIDR block for Cassandra access
Default: 10.0.0.0/8
Resources:
CassandraSecurityGroup:
Type: AWS::EC2::SecurityGroup
Properties:
GroupDescription: Security group for Cassandra with restricted access
VpcId: !Ref VpcId
SecurityGroupIngress:
- IpProtocol: tcp
FromPort: 7000
ToPort: 7000
CidrIp: !Ref TrustedCidr
Description: Cassandra inter-node cluster communication
- IpProtocol: tcp
FromPort: 7001
ToPort: 7001
CidrIp: !Ref TrustedCidr
Description: Cassandra TLS inter-node cluster communication
- IpProtocol: tcp
FromPort: 7199
ToPort: 7199
CidrIp: !Ref TrustedCidr
Description: Cassandra JMX monitoring port
- IpProtocol: tcp
FromPort: 9042
ToPort: 9042
CidrIp: !Ref TrustedCidr
Description: Cassandra CQL native transport port
- IpProtocol: tcp
FromPort: 9160
ToPort: 9160
CidrIp: !Ref TrustedCidr
Description: Cassandra Thrift client API
Tags:
- Key: Name
Value: cassandra-restricted-sg
Outputs:
SecurityGroupId:
Description: ID of the Cassandra security group
Value: !Ref CassandraSecurityGroup
Deploy the template:
aws cloudformation deploy \
--region us-east-1 \
--template-file cassandra-sg.yaml \
--stack-name cassandra-security-group \
--parameter-overrides VpcId=<YOUR_VPC_ID> TrustedCidr=10.0.0.0/8
Terraform configuration
variable "vpc_id" {
description = "VPC ID where the security group will be created"
type = string
}
variable "trusted_cidr_blocks" {
description = "List of trusted CIDR blocks for Cassandra access"
type = list(string)
default = ["10.0.0.0/8"]
}
resource "aws_security_group" "cassandra" {
name = "cassandra-restricted-sg"
description = "Security group for Cassandra with restricted access"
vpc_id = var.vpc_id
# Cassandra inter-node cluster communication
ingress {
from_port = 7000
to_port = 7000
protocol = "tcp"
cidr_blocks = var.trusted_cidr_blocks
description = "Cassandra inter-node cluster communication"
}
# Cassandra TLS inter-node cluster communication
ingress {
from_port = 7001
to_port = 7001
protocol = "tcp"
cidr_blocks = var.trusted_cidr_blocks
description = "Cassandra TLS inter-node cluster communication"
}
# Cassandra JMX monitoring port
ingress {
from_port = 7199
to_port = 7199
protocol = "tcp"
cidr_blocks = var.trusted_cidr_blocks
description = "Cassandra JMX monitoring port"
}
# Cassandra CQL native transport port
ingress {
from_port = 9042
to_port = 9042
protocol = "tcp"
cidr_blocks = var.trusted_cidr_blocks
description = "Cassandra CQL native transport port"
}
# Cassandra Thrift client API
ingress {
from_port = 9160
to_port = 9160
protocol = "tcp"
cidr_blocks = var.trusted_cidr_blocks
description = "Cassandra Thrift client API"
}
egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
description = "Allow all outbound traffic"
}
tags = {
Name = "cassandra-restricted-sg"
}
}
output "security_group_id" {
description = "ID of the Cassandra security group"
value = aws_security_group.cassandra.id
}
Verification
After making changes, verify the fix:
- Go to EC2 > Security Groups in the AWS Console
- Select your security group and check the Inbound rules tab
- Confirm no rules allow
0.0.0.0/0or::/0on ports 7000, 7001, 7199, 9042, or 9160
CLI verification commands
Check that no Cassandra ports are open to the internet:
# This should return empty results if properly remediated
aws ec2 describe-security-groups \
--region us-east-1 \
--group-ids <SECURITY_GROUP_ID> \
--query "SecurityGroups[].IpPermissions[?contains([`7000`,`7001`,`7199`,`9042`,`9160`], to_string(FromPort)) && contains(IpRanges[].CidrIp, '0.0.0.0/0')]" \
--output json
Re-run the Prowler check to confirm remediation:
prowler aws --checks ec2_instance_port_cassandra_exposed_to_internet --region us-east-1
Additional Resources
- AWS Security Groups Documentation
- Apache Cassandra Default Ports
- AWS Well-Architected Framework - Security Pillar
- Prowler Check Documentation
Notes
- Service interruption: Removing security group rules takes effect immediately. Ensure applications and users have alternative access methods before making changes.
- Multiple security groups: An EC2 instance can have multiple security groups attached. Check all of them for exposed Cassandra ports.
- IPv6 considerations: Remember to check for both IPv4 (
0.0.0.0/0) and IPv6 (::/0) unrestricted access. - Network ACLs: Security groups are stateful, but Network ACLs are stateless. Consider adding NACL rules as an additional layer of defense.
- Alternative access methods: For remote Cassandra access, consider using AWS Systems Manager Session Manager, a bastion host, or AWS Client VPN instead of exposing ports to the internet.
Compliance Mapping
This check supports compliance with:
- SOC 2 - CC6.1, CC6.6 (Logical and Physical Access Controls)
- ISO 27001 - A.13.1.1 (Network Controls)
- C5 - OPS-02 (Operational Security)
- KISA-ISMS-P - Network Security
- NIS2 - Article 21 (Cybersecurity Risk Management)