Skip to main content

Amazon EC2 Instances Should Not Use Multiple ENIs

Overview

This check verifies that your EC2 instances use only a single Elastic Network Interface (ENI). While AWS allows attaching multiple network interfaces to an instance, doing so creates "dual-homed" configurations that can introduce security risks.

Risk

When an EC2 instance has multiple ENIs attached, it can connect to multiple subnets simultaneously. This creates potential security issues:

  • Network segmentation bypass: An attacker who compromises the instance could pivot between network segments
  • Unintended data paths: Traffic might flow through unexpected routes, bypassing security controls
  • Complexity: Multiple interfaces make it harder to audit and secure network access
  • Data exfiltration: Attackers could use alternate network paths to extract data

Note: Some legitimate use cases require multiple ENIs, such as:

  • Amazon EKS cluster nodes (you can suppress these findings)
  • Network appliances or load balancers
  • Instances requiring separate management and data interfaces

Remediation Steps

Prerequisites

You need permission to view and modify EC2 network interfaces. Specifically, you need ec2:DescribeNetworkInterfaces and ec2:DetachNetworkInterface permissions.

AWS Console Method

  1. Sign in to the AWS Console and go to EC2
  2. In the left menu, click Network Interfaces (under Network & Security)
  3. In the search bar, filter by the Instance ID that failed the check
  4. Review the list of attached ENIs - you should see multiple interfaces
  5. Identify which ENI is the primary (device index 0) - this one cannot be detached
  6. Select a secondary ENI (device index 1 or higher)
  7. Click Actions and choose Detach
  8. In the confirmation dialog, click Detach
  9. Repeat for any other secondary ENIs you want to remove

Important: Before detaching an ENI, verify that the instance does not depend on it for critical connectivity. Some applications specifically require multiple interfaces.

AWS CLI Method

Step 1: List ENIs attached to the instance

aws ec2 describe-network-interfaces \
--region us-east-1 \
--filters "Name=attachment.instance-id,Values=<instance-id>" \
--query 'NetworkInterfaces[*].{ENI:NetworkInterfaceId,DeviceIndex:Attachment.DeviceIndex,AttachmentId:Attachment.AttachmentId,SubnetId:SubnetId}' \
--output table

Replace <instance-id> with your EC2 instance ID (e.g., i-0abc123def456789).

Step 2: Identify secondary ENIs

The primary ENI has DeviceIndex: 0 and cannot be detached. Any ENI with DeviceIndex: 1 or higher is secondary and can be removed.

Step 3: Detach secondary ENIs

aws ec2 detach-network-interface \
--region us-east-1 \
--attachment-id <attachment-id>

Replace <attachment-id> with the attachment ID from Step 1 (e.g., eni-attach-0abc123def456789).

Step 4: (Optional) Delete the detached ENI

If the ENI is no longer needed:

aws ec2 delete-network-interface \
--region us-east-1 \
--network-interface-id <eni-id>

Warning: The --force flag can force detachment from a failed instance, but may cause metadata inconsistencies. Only use it as a last resort.

CloudFormation Template

When defining EC2 instances in CloudFormation, use SubnetId and SecurityGroupIds directly on the instance resource instead of attaching additional network interfaces:

AWSTemplateFormatVersion: '2010-09-09'
Description: EC2 instance with a single network interface (best practice)

Parameters:
InstanceType:
Type: String
Default: t3.micro
Description: EC2 instance type
SubnetId:
Type: AWS::EC2::Subnet::Id
Description: Subnet ID for the instance
SecurityGroupId:
Type: AWS::EC2::SecurityGroup::Id
Description: Security group ID for the instance
AmiId:
Type: AWS::SSM::Parameter::Value<AWS::EC2::Image::Id>
Default: /aws/service/ami-amazon-linux-latest/al2023-ami-kernel-default-x86_64
Description: AMI ID (defaults to latest Amazon Linux 2023)

Resources:
EC2Instance:
Type: AWS::EC2::Instance
Properties:
InstanceType: !Ref InstanceType
ImageId: !Ref AmiId
SubnetId: !Ref SubnetId
SecurityGroupIds:
- !Ref SecurityGroupId
Tags:
- Key: Name
Value: SingleENIInstance

Outputs:
InstanceId:
Description: EC2 Instance ID
Value: !Ref EC2Instance
PrimaryNetworkInterface:
Description: Primary network interface ID
Value: !GetAtt EC2Instance.PrivateIp

Avoid using AWS::EC2::NetworkInterfaceAttachment resources unless you have a documented business requirement for multiple ENIs.

Terraform Configuration

When defining EC2 instances in Terraform, use subnet_id and vpc_security_group_ids directly instead of attaching additional network interfaces:

terraform {
required_version = ">= 1.0"
required_providers {
aws = {
source = "hashicorp/aws"
version = ">= 5.0"
}
}
}

provider "aws" {
region = "us-east-1"
}

variable "subnet_id" {
description = "Subnet ID for the EC2 instance"
type = string
}

variable "security_group_ids" {
description = "List of security group IDs"
type = list(string)
}

variable "instance_type" {
description = "EC2 instance type"
type = string
default = "t3.micro"
}

# Data source to get latest Amazon Linux 2023 AMI
data "aws_ami" "amazon_linux_2023" {
most_recent = true
owners = ["amazon"]

filter {
name = "name"
values = ["al2023-ami-*-x86_64"]
}

filter {
name = "virtualization-type"
values = ["hvm"]
}
}

# EC2 instance with single ENI (best practice)
# Uses subnet_id and vpc_security_group_ids instead of network_interface block
resource "aws_instance" "single_eni" {
ami = data.aws_ami.amazon_linux_2023.id
instance_type = var.instance_type
subnet_id = var.subnet_id
vpc_security_group_ids = var.security_group_ids

tags = {
Name = "SingleENIInstance"
}
}

output "instance_id" {
description = "EC2 Instance ID"
value = aws_instance.single_eni.id
}

output "primary_network_interface_id" {
description = "Primary network interface ID"
value = aws_instance.single_eni.primary_network_interface_id
}

Avoid using aws_network_interface and aws_network_interface_attachment resources unless you have a documented business requirement for multiple ENIs.

Verification

After detaching secondary ENIs, verify the fix:

  1. Go to EC2 > Instances in the AWS Console
  2. Select your instance and click the Networking tab
  3. Under Network interfaces, confirm only one ENI is listed
  4. Re-run the Prowler check to confirm it passes
CLI Verification
# Count ENIs attached to the instance
aws ec2 describe-network-interfaces \
--region us-east-1 \
--filters "Name=attachment.instance-id,Values=<instance-id>" \
--query 'length(NetworkInterfaces)'

The result should be 1 for a compliant instance.

Additional Resources

Notes

  • Primary ENI: Every EC2 instance has a primary ENI (device index 0) that cannot be detached. Only secondary ENIs can be removed.
  • EKS Clusters: Amazon EKS nodes commonly use multiple ENIs for pod networking. If this is expected behavior, suppress the finding for those instances.
  • Stopping may be required: In some cases, you may need to stop the instance before detaching a secondary ENI.
  • Application impact: Before removing an ENI, verify your application does not depend on it for connectivity to specific subnets or services.