RFC 1918 defines three sacred private address blocks that every network engineer should engrave in their memory:
10.0.0.0/8 (16,777,216 hosts)
172.16.0.0/12 (1,048,576 hosts)
192.168.0.0/16 (65,536 hosts)
The eternal debate between network purists and pragmatists:
- Round Subnet Zealots: "Stick to /8, /16, /24 boundaries for clean binary divisions"
- CIDR Realists: "VLSM all the way - waste no addresses!"
Religious wars over gateway placement:
# Traditionalists
interface VLAN10
ip address 192.168.1.1 255.255.255.0
# Radicals
interface VLAN20
ip address 10.0.42.254 255.255.255.0
# Heretics
interface VLAN30
ip address 172.16.23.187 255.255.255.0
Sample Python code for systematic IP assignment:
def generate_ip_pool(subnet, reserved=20):
"""Generate IP addresses excluding network/broadcast and reserved range"""
network = ipaddress.IPv4Network(subnet)
hosts = list(network.hosts())
# Reserve first N for infrastructure
infrastructure = hosts[:reserved]
user_pool = hosts[reserved:]
return {
'gateway': infrastructure[0],
'dns_servers': infrastructure[1:3],
'user_pool': user_pool
}
# Usage
print(generate_ip_pool('192.168.1.0/24'))
Example DHCP reservation config (ISC DHCPd):
subnet 10.42.0.0 netmask 255.255.0.0 {
range 10.42.1.100 10.42.1.200;
option routers 10.42.0.1;
host webserver {
hardware ethernet 00:1a:2b:3c:4d:5e;
fixed-address 10.42.0.10;
}
host printer {
hardware ethernet 00:1b:3c:4d:5e:6f;
fixed-address 10.42.0.20;
}
}
When designing IPv4 subnets today, always consider:
- Dual-stack implementation possibilities
- Future renumbering to IPv6
- NAT64/DNS64 requirements
When architecting private networks, we operate within three sanctioned ranges:
10.0.0.0/8 (16,777,216 hosts)
172.16.0.0/12 (1,048,576 hosts)
192.168.0.0/16 (65,536 hosts)
Consider these approaches for subnet allocation:
- Minimalist: /24 for small offices (254 hosts)
- Moderate: /23 for department VLANs (510 hosts)
- Future-proof: /22 for dynamic environments (1022 hosts)
# Example subnet calculation
$ ipcalc 10.42.0.0/22
Address: 10.42.0.0
Netmask: 255.255.252.0 = 22
Wildcard: 0.0.3.255
Network: 10.42.0.0/22
HostMin: 10.42.0.1
HostMax: 10.42.3.254
Broadcast: 10.42.3.255
Hosts/Net: 1022
Common gateway placement conventions:
# Conservative approach
gateway = network_address + 1 (e.g., 192.168.1.1)
# Alternative scheme
gateway = broadcast_address - 1 (e.g., 192.168.1.254)
# Infrastructure devices often occupy lower ranges:
- .1 to .9: Network equipment (routers, switches)
- .10 to .19: Servers and critical services
- .20 to .199: DHCP pool
- .200 to .254: Static assignments
Best practice hybrid approach:
# Sample DHCPd configuration for mixed environment
subnet 10.100.20.0 netmask 255.255.255.0 {
range 10.100.20.50 10.100.20.199;
option routers 10.100.20.1;
option domain-name-servers 10.100.20.2, 10.100.20.3;
# Static reservations
host webserver {
hardware ethernet 00:1a:2b:3c:4d:5e;
fixed-address 10.100.20.10;
}
host printer {
hardware ethernet 00:1b:2a:3d:4e:5f;
fixed-address 10.100.20.201;
}
}
While waiting for full IPv6 adoption:
# Dual-stack configuration example
interface GigabitEthernet0/1
ip address 10.55.77.1 255.255.255.0
ipv6 address 2001:db8:cafe:55::1/64
ipv6 nd managed-config-flag
ipv6 dhcp server LAN_POOL
Always maintain an IPAM (IP Address Management) system:
# Example Ansible inventory with network metadata
[web_servers]
web01 ansible_host=10.20.30.41 vlan=30 role=frontend
web02 ansible_host=10.20.30.42 vlan=30 role=backend
[network_devices:children]
routers
switches
[routers]
core01 ansible_host=10.20.1.1 device_type=cisco_ios
[switches]
access01 ansible_host=10.20.1.11 device_type=cisco_ios