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
- Sign in to the AWS Console and go to EC2
- In the left menu, click Network Interfaces (under Network & Security)
- In the search bar, filter by the Instance ID that failed the check
- Review the list of attached ENIs - you should see multiple interfaces
- Identify which ENI is the primary (device index 0) - this one cannot be detached
- Select a secondary ENI (device index 1 or higher)
- Click Actions and choose Detach
- In the confirmation dialog, click Detach
- 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:
- Go to EC2 > Instances in the AWS Console
- Select your instance and click the Networking tab
- Under Network interfaces, confirm only one ENI is listed
- 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
- AWS Documentation: Elastic Network Interfaces
- AWS Documentation: Detach a Network Interface
- AWS Security Hub: EC2 Controls
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.