SEC05-BP01 - Create network layers
One-Click Remediation
Deploy CloudFormation stacks to implement this best practice with a single click.
Stacks deploy to your AWS account. Review parameters before creating. Standard AWS charges apply.
Implementation guidance
Network layering is a fundamental security principle that involves organizing your network infrastructure into distinct segments or layers, each with specific security controls and access requirements. By implementing proper network layers, you can significantly reduce the attack surface and limit the potential impact of security incidents.
Key steps for implementing this best practice:
-
Design multi-tier network architecture:
- Create separate layers for different application tiers (web, application, database)
- Implement network segmentation based on security requirements
- Design layers with appropriate isolation and access controls
- Plan for scalability and future growth requirements
- Document network architecture and layer purposes
-
Implement subnet-based segmentation:
- Create public subnets for internet-facing resources
- Design private subnets for internal application components
- Establish isolated subnets for sensitive data and databases
- Use dedicated subnets for management and administrative access
- Implement subnet-level access controls and routing
-
Configure routing and connectivity:
- Design routing tables for each network layer
- Implement controlled connectivity between layers
- Use NAT gateways for outbound internet access from private subnets
- Configure VPC endpoints for secure AWS service access
- Establish secure connectivity for hybrid environments
-
Apply security controls at each layer:
- Implement Network ACLs for subnet-level filtering
- Configure Security Groups for instance-level protection
- Deploy network firewalls for advanced threat protection
- Use load balancers for traffic distribution and security
- Implement intrusion detection and prevention systems
-
Monitor and maintain network layers:
- Enable VPC Flow Logs for network traffic analysis
- Implement network monitoring and alerting
- Regularly review and update network configurations
- Conduct network security assessments
- Maintain network documentation and diagrams
-
Implement defense in depth:
- Layer multiple security controls for comprehensive protection
- Use different security mechanisms at each network layer
- Implement redundant security measures for critical paths
- Design fail-safe mechanisms for security control failures
- Regularly test and validate layered security effectiveness
Implementation examples
Example 1: Three-tier network architecture
View code
# CloudFormation template for three-tier network architecture
AWSTemplateFormatVersion: '2010-09-09'
Description: 'Three-tier network architecture with proper layering'
Parameters:
VpcCidr:
Type: String
Default: '10.0.0.0/16'
Description: CIDR block for the VPC
Resources:
# VPC
MainVPC:
Type: AWS::EC2::VPC
Properties:
CidrBlock: !Ref VpcCidr
EnableDnsHostnames: true
EnableDnsSupport: true
Tags:
- Key: Name
Value: MainVPC
- Key: Environment
Value: Production
# Internet Gateway
InternetGateway:
Type: AWS::EC2::InternetGateway
Properties:
Tags:
- Key: Name
Value: MainVPC-IGW
AttachGateway:
Type: AWS::EC2::VPCGatewayAttachment
Properties:
VpcId: !Ref MainVPC
InternetGatewayId: !Ref InternetGateway
# Public Subnets (Web Tier)
PublicSubnet1:
Type: AWS::EC2::Subnet
Properties:
VpcId: !Ref MainVPC
CidrBlock: '10.0.1.0/24'
AvailabilityZone: !Select [0, !GetAZs '']
MapPublicIpOnLaunch: true
Tags:
- Key: Name
Value: Public-Subnet-1
- Key: Tier
Value: Web
PublicSubnet2:
Type: AWS::EC2::Subnet
Properties:
VpcId: !Ref MainVPC
CidrBlock: '10.0.2.0/24'
AvailabilityZone: !Select [1, !GetAZs '']
MapPublicIpOnLaunch: true
Tags:
- Key: Name
Value: Public-Subnet-2
- Key: Tier
Value: Web
# Private Subnets (Application Tier)
PrivateSubnet1:
Type: AWS::EC2::Subnet
Properties:
VpcId: !Ref MainVPC
CidrBlock: '10.0.11.0/24'
AvailabilityZone: !Select [0, !GetAZs '']
Tags:
- Key: Name
Value: Private-Subnet-1
- Key: Tier
Value: Application
PrivateSubnet2:
Type: AWS::EC2::Subnet
Properties:
VpcId: !Ref MainVPC
CidrBlock: '10.0.12.0/24'
AvailabilityZone: !Select [1, !GetAZs '']
Tags:
- Key: Name
Value: Private-Subnet-2
- Key: Tier
Value: Application
# Database Subnets (Data Tier)
DatabaseSubnet1:
Type: AWS::EC2::Subnet
Properties:
VpcId: !Ref MainVPC
CidrBlock: '10.0.21.0/24'
AvailabilityZone: !Select [0, !GetAZs '']
Tags:
- Key: Name
Value: Database-Subnet-1
- Key: Tier
Value: Database
DatabaseSubnet2:
Type: AWS::EC2::Subnet
Properties:
VpcId: !Ref MainVPC
CidrBlock: '10.0.22.0/24'
AvailabilityZone: !Select [1, !GetAZs '']
Tags:
- Key: Name
Value: Database-Subnet-2
- Key: Tier
Value: Database
# NAT Gateways for private subnet internet access
NATGateway1EIP:
Type: AWS::EC2::EIP
DependsOn: AttachGateway
Properties:
Domain: vpc
NATGateway2EIP:
Type: AWS::EC2::EIP
DependsOn: AttachGateway
Properties:
Domain: vpc
NATGateway1:
Type: AWS::EC2::NatGateway
Properties:
AllocationId: !GetAtt NATGateway1EIP.AllocationId
SubnetId: !Ref PublicSubnet1
NATGateway2:
Type: AWS::EC2::NatGateway
Properties:
AllocationId: !GetAtt NATGateway2EIP.AllocationId
SubnetId: !Ref PublicSubnet2
# Route Tables
PublicRouteTable:
Type: AWS::EC2::RouteTable
Properties:
VpcId: !Ref MainVPC
Tags:
- Key: Name
Value: Public-Route-Table
DefaultPublicRoute:
Type: AWS::EC2::Route
DependsOn: AttachGateway
Properties:
RouteTableId: !Ref PublicRouteTable
DestinationCidrBlock: '0.0.0.0/0'
GatewayId: !Ref InternetGateway
PublicSubnet1RouteTableAssociation:
Type: AWS::EC2::SubnetRouteTableAssociation
Properties:
RouteTableId: !Ref PublicRouteTable
SubnetId: !Ref PublicSubnet1
PublicSubnet2RouteTableAssociation:
Type: AWS::EC2::SubnetRouteTableAssociation
Properties:
RouteTableId: !Ref PublicRouteTable
SubnetId: !Ref PublicSubnet2
PrivateRouteTable1:
Type: AWS::EC2::RouteTable
Properties:
VpcId: !Ref MainVPC
Tags:
- Key: Name
Value: Private-Route-Table-1
DefaultPrivateRoute1:
Type: AWS::EC2::Route
Properties:
RouteTableId: !Ref PrivateRouteTable1
DestinationCidrBlock: '0.0.0.0/0'
NatGatewayId: !Ref NATGateway1
PrivateSubnet1RouteTableAssociation:
Type: AWS::EC2::SubnetRouteTableAssociation
Properties:
RouteTableId: !Ref PrivateRouteTable1
SubnetId: !Ref PrivateSubnet1
PrivateRouteTable2:
Type: AWS::EC2::RouteTable
Properties:
VpcId: !Ref MainVPC
Tags:
- Key: Name
Value: Private-Route-Table-2
DefaultPrivateRoute2:
Type: AWS::EC2::Route
Properties:
RouteTableId: !Ref PrivateRouteTable2
DestinationCidrBlock: '0.0.0.0/0'
NatGatewayId: !Ref NATGateway2
PrivateSubnet2RouteTableAssociation:
Type: AWS::EC2::SubnetRouteTableAssociation
Properties:
RouteTableId: !Ref PrivateRouteTable2
SubnetId: !Ref PrivateSubnet2
DatabaseRouteTable:
Type: AWS::EC2::RouteTable
Properties:
VpcId: !Ref MainVPC
Tags:
- Key: Name
Value: Database-Route-Table
DatabaseSubnet1RouteTableAssociation:
Type: AWS::EC2::SubnetRouteTableAssociation
Properties:
RouteTableId: !Ref DatabaseRouteTable
SubnetId: !Ref DatabaseSubnet1
DatabaseSubnet2RouteTableAssociation:
Type: AWS::EC2::SubnetRouteTableAssociation
Properties:
RouteTableId: !Ref DatabaseRouteTable
SubnetId: !Ref DatabaseSubnet2
Outputs:
VPCId:
Description: VPC ID
Value: !Ref MainVPC
Export:
Name: !Sub '${AWS::StackName}-VPC-ID'
PublicSubnets:
Description: Public subnet IDs
Value: !Join [',', [!Ref PublicSubnet1, !Ref PublicSubnet2]]
Export:
Name: !Sub '${AWS::StackName}-Public-Subnets'
PrivateSubnets:
Description: Private subnet IDs
Value: !Join [',', [!Ref PrivateSubnet1, !Ref PrivateSubnet2]]
Export:
Name: !Sub '${AWS::StackName}-Private-Subnets'
DatabaseSubnets:
Description: Database subnet IDs
Value: !Join [',', [!Ref DatabaseSubnet1, !Ref DatabaseSubnet2]]
Export:
Name: !Sub '${AWS::StackName}-Database-Subnets'Example 2: Network ACLs for layer-specific access control
View code
# Create Network ACLs for different tiers
aws ec2 create-network-acl \
--vpc-id vpc-12345678 \
--tag-specifications 'ResourceType=network-acl,Tags=[{Key=Name,Value=Web-Tier-NACL},{Key=Tier,Value=Web}]'
aws ec2 create-network-acl \
--vpc-id vpc-12345678 \
--tag-specifications 'ResourceType=network-acl,Tags=[{Key=Name,Value=App-Tier-NACL},{Key=Tier,Value=Application}]'
aws ec2 create-network-acl \
--vpc-id vpc-12345678 \
--tag-specifications 'ResourceType=network-acl,Tags=[{Key=Name,Value=DB-Tier-NACL},{Key=Tier,Value=Database}]'
# Configure Web Tier NACL (allow HTTP/HTTPS inbound, ephemeral ports outbound)
aws ec2 create-network-acl-entry \
--network-acl-id acl-web123456 \
--rule-number 100 \
--protocol tcp \
--rule-action allow \
--port-range From=80,To=80 \
--cidr-block 0.0.0.0/0
aws ec2 create-network-acl-entry \
--network-acl-id acl-web123456 \
--rule-number 110 \
--protocol tcp \
--rule-action allow \
--port-range From=443,To=443 \
--cidr-block 0.0.0.0/0
aws ec2 create-network-acl-entry \
--network-acl-id acl-web123456 \
--rule-number 100 \
--protocol tcp \
--rule-action allow \
--port-range From=1024,To=65535 \
--cidr-block 0.0.0.0/0 \
--egress
# Configure Application Tier NACL (allow from web tier only)
aws ec2 create-network-acl-entry \
--network-acl-id acl-app123456 \
--rule-number 100 \
--protocol tcp \
--rule-action allow \
--port-range From=8080,To=8080 \
--cidr-block 10.0.1.0/24
aws ec2 create-network-acl-entry \
--network-acl-id acl-app123456 \
--rule-number 110 \
--protocol tcp \
--rule-action allow \
--port-range From=8080,To=8080 \
--cidr-block 10.0.2.0/24
# Configure Database Tier NACL (allow from application tier only)
aws ec2 create-network-acl-entry \
--network-acl-id acl-db123456 \
--rule-number 100 \
--protocol tcp \
--rule-action allow \
--port-range From=3306,To=3306 \
--cidr-block 10.0.11.0/24
aws ec2 create-network-acl-entry \
--network-acl-id acl-db123456 \
--rule-number 110 \
--protocol tcp \
--rule-action allow \
--port-range From=3306,To=3306 \
--cidr-block 10.0.12.0/24Example 3: Security Groups for layered protection
View code
{
"WebTierSecurityGroup": {
"Type": "AWS::EC2::SecurityGroup",
"Properties": {
"GroupDescription": "Security group for web tier instances",
"VpcId": {"Ref": "MainVPC"},
"SecurityGroupIngress": [
{
"IpProtocol": "tcp",
"FromPort": 80,
"ToPort": 80,
"CidrIp": "0.0.0.0/0",
"Description": "Allow HTTP from internet"
},
{
"IpProtocol": "tcp",
"FromPort": 443,
"ToPort": 443,
"CidrIp": "0.0.0.0/0",
"Description": "Allow HTTPS from internet"
}
],
"SecurityGroupEgress": [
{
"IpProtocol": "tcp",
"FromPort": 8080,
"ToPort": 8080,
"DestinationSecurityGroupId": {"Ref": "AppTierSecurityGroup"},
"Description": "Allow outbound to application tier"
}
],
"Tags": [
{"Key": "Name", "Value": "Web-Tier-SG"},
{"Key": "Tier", "Value": "Web"}
]
}
},
"AppTierSecurityGroup": {
"Type": "AWS::EC2::SecurityGroup",
"Properties": {
"GroupDescription": "Security group for application tier instances",
"VpcId": {"Ref": "MainVPC"},
"SecurityGroupIngress": [
{
"IpProtocol": "tcp",
"FromPort": 8080,
"ToPort": 8080,
"SourceSecurityGroupId": {"Ref": "WebTierSecurityGroup"},
"Description": "Allow inbound from web tier"
}
],
"SecurityGroupEgress": [
{
"IpProtocol": "tcp",
"FromPort": 3306,
"ToPort": 3306,
"DestinationSecurityGroupId": {"Ref": "DatabaseTierSecurityGroup"},
"Description": "Allow outbound to database tier"
}
],
"Tags": [
{"Key": "Name", "Value": "App-Tier-SG"},
{"Key": "Tier", "Value": "Application"}
]
}
},
"DatabaseTierSecurityGroup": {
"Type": "AWS::EC2::SecurityGroup",
"Properties": {
"GroupDescription": "Security group for database tier instances",
"VpcId": {"Ref": "MainVPC"},
"SecurityGroupIngress": [
{
"IpProtocol": "tcp",
"FromPort": 3306,
"ToPort": 3306,
"SourceSecurityGroupId": {"Ref": "AppTierSecurityGroup"},
"Description": "Allow inbound from application tier"
}
],
"Tags": [
{"Key": "Name", "Value": "Database-Tier-SG"},
{"Key": "Tier", "Value": "Database"}
]
}
}
}Example 4: VPC Flow Logs for network monitoring
View code
import boto3
import json
from datetime import datetime
def setup_vpc_flow_logs():
"""Configure VPC Flow Logs for network layer monitoring"""
ec2 = boto3.client('ec2')
logs = boto3.client('logs')
# Create CloudWatch Log Group for VPC Flow Logs
log_group_name = '/aws/vpc/flowlogs'
try:
logs.create_log_group(
logGroupName=log_group_name,
retentionInDays=90
)
print(f"Created log group: {log_group_name}")
except logs.exceptions.ResourceAlreadyExistsException:
print(f"Log group already exists: {log_group_name}")
# Create IAM role for VPC Flow Logs
iam = boto3.client('iam')
trust_policy = {
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "vpc-flow-logs.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}
flow_logs_policy = {
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"logs:CreateLogGroup",
"logs:CreateLogStream",
"logs:PutLogEvents",
"logs:DescribeLogGroups",
"logs:DescribeLogStreams"
],
"Resource": "*"
}
]
}
try:
# Create IAM role
role_response = iam.create_role(
RoleName='VPCFlowLogsRole',
AssumeRolePolicyDocument=json.dumps(trust_policy),
Description='Role for VPC Flow Logs to write to CloudWatch'
)
# Attach policy to role
iam.put_role_policy(
RoleName='VPCFlowLogsRole',
PolicyName='VPCFlowLogsPolicy',
PolicyDocument=json.dumps(flow_logs_policy)
)
role_arn = role_response['Role']['Arn']
print(f"Created IAM role: {role_arn}")
except iam.exceptions.EntityAlreadyExistsException:
# Get existing role ARN
role_response = iam.get_role(RoleName='VPCFlowLogsRole')
role_arn = role_response['Role']['Arn']
print(f"Using existing IAM role: {role_arn}")
# Enable VPC Flow Logs for different network layers
vpc_id = 'vpc-12345678' # Replace with your VPC ID
# Custom log format to capture layer-specific information
log_format = '${srcaddr} ${dstaddr} ${srcport} ${dstport} ${protocol} ${packets} ${bytes} ${windowstart} ${windowend} ${action} ${flowlogstatus} ${subnet-id} ${instance-id}'
try:
response = ec2.create_flow_logs(
ResourceType='VPC',
ResourceIds=[vpc_id],
TrafficType='ALL',
LogDestinationType='cloud-watch-logs',
LogGroupName=log_group_name,
DeliverLogsPermissionArn=role_arn,
LogFormat=log_format,
TagSpecifications=[
{
'ResourceType': 'vpc-flow-log',
'Tags': [
{
'Key': 'Name',
'Value': 'VPC-Flow-Logs'
},
{
'Key': 'Purpose',
'Value': 'Network-Layer-Monitoring'
}
]
}
]
)
print(f"Created VPC Flow Logs: {response['FlowLogIds']}")
except Exception as e:
print(f"Error creating VPC Flow Logs: {str(e)}")
def analyze_network_layer_traffic():
"""Analyze VPC Flow Logs for network layer insights"""
logs = boto3.client('logs')
# Query for traffic patterns between network layers
query = """
fields @timestamp, srcaddr, dstaddr, srcport, dstport, protocol, action, subnet_id
| filter action = "ACCEPT"
| stats count() by srcaddr, dstaddr, dstport
| sort count desc
| limit 20
"""
try:
response = logs.start_query(
logGroupName='/aws/vpc/flowlogs',
startTime=int((datetime.now().timestamp() - 3600) * 1000), # Last hour
endTime=int(datetime.now().timestamp() * 1000),
queryString=query
)
query_id = response['queryId']
print(f"Started CloudWatch Insights query: {query_id}")
# In a real implementation, you would poll for results
# and analyze traffic patterns between network layers
except Exception as e:
print(f"Error starting query: {str(e)}")
# Example usage
if __name__ == "__main__":
setup_vpc_flow_logs()
analyze_network_layer_traffic()AWS services to consider
Amazon VPC (Virtual Private Cloud)
Provides the foundation for creating network layers with subnets, route tables, and security controls. Essential for implementing network segmentation and isolation.
AWS Security Groups
Acts as a virtual firewall for your EC2 instances to control inbound and outbound traffic. Provides stateful packet filtering at the instance level for each network layer.
AWS Network ACLs
Provides an additional layer of security for your VPC that acts as a firewall for controlling traffic in and out of subnets. Offers stateless packet filtering at the subnet level.
AWS NAT Gateway
Enables instances in private subnets to connect to the internet or other AWS services while preventing the internet from initiating connections with those instances.
VPC Endpoints
Enables you to privately connect your VPC to supported AWS services without requiring an internet gateway, NAT device, VPN connection, or AWS Direct Connect connection.
AWS Network Firewall
A managed service that makes it easy to deploy essential network protections for all of your Amazon VPCs. Provides fine-grained control over network traffic at the VPC level.
Benefits of creating network layers
- Reduced attack surface: Limits the exposure of sensitive resources by isolating them in appropriate network layers
- Improved security posture: Enables implementation of defense-in-depth strategies with multiple security controls
- Better compliance: Supports regulatory requirements for network segmentation and data protection
- Enhanced monitoring: Provides clear boundaries for network traffic analysis and security monitoring
- Simplified management: Organizes network resources logically, making configuration and maintenance easier
- Scalable architecture: Supports growth and changes in application requirements without compromising security
- Incident containment: Limits the spread of security incidents by containing them within specific network layers