Understanding CIDR Notation: IPv4 Subnetting Explained for Developers


3 views

When working with cloud services like AWS EC2 or configuring network security groups, you'll often encounter IP addresses followed by a slash and number (e.g., 192.168.2.0/24). This is called CIDR (Classless Inter-Domain Routing) notation, a compact way to specify both an IP address and its associated routing prefix.

The format is: IP_address/prefix_length

Where:

  • IP_address: The base network address (e.g., 192.168.2.0)
  • prefix_length: The number of significant bits in the subnet mask (e.g., /24)

Let's examine common CIDR blocks:

192.168.1.0/24 = 192.168.1.0 - 192.168.1.255
10.0.0.0/8 = 10.0.0.0 - 10.255.255.255
172.16.0.0/12 = 172.16.0.0 - 172.31.255.255
0.0.0.0/0 = All possible IPv4 addresses

Here's a Python function to calculate the network range:

import ipaddress

def cidr_to_range(cidr):
    network = ipaddress.IPv4Network(cidr)
    return str(network.network_address), str(network.broadcast_address)

# Example usage:
print(cidr_to_range("192.168.1.0/24"))
# Output: ('192.168.1.0', '192.168.1.255')

In AWS security groups, 0.0.0.0/0 means "allow from any IPv4 address." This is equivalent to a wildcard and should be used cautiously. More secure alternatives:

# Restrict to your office IP
203.0.113.42/32

# Allow your entire office subnet
203.0.113.0/24

# Allow private network only
10.0.0.0/8

For network administrators, understanding how to split larger networks is crucial. Here's how to create smaller subnets from a /16 block:

original_network = ipaddress.IPv4Network("10.0.0.0/16")
subnets = list(original_network.subnets(new_prefix=24))

# This creates 256 /24 subnets (10.0.0.0/24 to 10.0.255.0/24)

  • Using overly permissive CIDR ranges (like /0) in production
  • Confusing network address (x.x.x.0) with usable IP range
  • Mixing up prefix lengths between IPv4 and IPv6

When you see an IP address followed by a forward slash and a number (e.g., 192.168.2.0/24), you're looking at Classless Inter-Domain Routing (CIDR) notation. This compact representation combines two crucial pieces of information:

IP Address: 192.168.2.0
Subnet Mask: 255.255.255.0 (equivalent to /24)

The number after the slash represents the number of network bits in the subnet mask. In IPv4 addresses:

  • /32 = Single host (255.255.255.255)
  • /24 = Classic Class C (255.255.255.0)
  • /16 = Classic Class B (255.255.0.0)
  • /8 = Classic Class A (255.0.0.0)

Let's examine how AWS security groups use this notation:

# Allow all IPv4 addresses (0.0.0.0/0)
aws ec2 authorize-security-group-ingress \
    --group-id sg-903004f8 \
    --protocol tcp \
    --port 22 \
    --cidr 0.0.0.0/0

# Restrict to local network (192.168.2.0/24)
aws ec2 authorize-security-group-ingress \
    --group-id sg-903004f8 \
    --protocol tcp \
    --port 3306 \
    --cidr 192.168.2.0/24

Here's a Python function to convert CIDR to IP range:

import ipaddress

def cidr_to_range(cidr):
    network = ipaddress.IPv4Network(cidr)
    return str(network.network_address), str(network.broadcast_address)

# Example usage
print(cidr_to_range("192.168.2.0/24"))  
# Output: ('192.168.2.0', '192.168.2.255')

Understanding CIDR is crucial for proper access control:

  • 0.0.0.0/0 means "any IPv4 address"
  • 192.168.2.0/24 covers 192.168.2.1 through 192.168.2.254
  • 10.0.0.0/8 spans all 10.x.x.x addresses (16.7 million IPs)

In cloud environments, always restrict access using the most specific CIDR possible rather than using overly broad ranges like 0.0.0.0/0.