The Internet Assigned Numbers Authority (IANA) designated three IP address blocks as private under RFC 1918:
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)
192.168.0.0/16 (192.168.0.0 - 192.168.255.255)
At the network protocol level, several mechanisms prevent private IP routing:
- BGP Route Filtering: ISPs implement route filters that explicitly reject private IP announcements
- Router Configuration: Enterprise routers are typically configured to drop packets with private source IPs on external interfaces
Example Cisco router ACL to block private IPs:
access-list 101 deny ip 10.0.0.0 0.255.255.255 any
access-list 101 deny ip 172.16.0.0 0.15.255.255 any
access-list 101 deny ip 192.168.0.0 0.0.255.255 any
access-list 101 permit ip any any
Network Address Translation (NAT) enables private IP networks to communicate with the Internet:
# Linux iptables NAT example
iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
Simple Python script to detect private IP ranges:
import ipaddress
def is_private(ip):
private_ranges = [
ipaddress.ip_network('10.0.0.0/8'),
ipaddress.ip_network('172.16.0.0/12'),
ipaddress.ip_network('192.168.0.0/16')
]
ip_obj = ipaddress.ip_address(ip)
return any(ip_obj in network for network in private_ranges)
print(is_private('192.168.1.1')) # Returns True
print(is_private('8.8.8.8')) # Returns False
Misconfigurations can sometimes cause private IPs to appear in public routing tables. Tools like traceroute
and BGP looking glasses help identify these leaks:
traceroute 192.168.1.1
# Should timeout or show private hops only
Private IP addresses are non-routable by design, as defined in RFC 1918 published by the IETF (not IANA directly). This standardization occurred because:
- IPv4 address exhaustion concerns (32-bit limitation)
- Need for reusable address space behind NAT
- Security through network isolation
ISPs implement BGP (Border Gateway Protocol) policies that explicitly drop packets containing private IP ranges. Here's a simplified Cisco IOS example:
router bgp 64512
no network 10.0.0.0
no network 172.16.0.0
no network 192.168.0.0
!
ip prefix-list PRIVATE-RFC1918 seq 5 deny 10.0.0.0/8
ip prefix-list PRIVATE-RFC1918 seq 10 deny 172.16.0.0/12
ip prefix-list PRIVATE-RFC1918 seq 15 deny 192.168.0.0/16
ip prefix-list PRIVATE-RFC1918 seq 20 permit 0.0.0.0/0 le 32
If a misconfigured router attempts to forward private IP traffic:
- Traceroute shows hops terminating at ISP edge
- Packet captures reveal ICMP Admin Prohibited messages
- Enterprise firewalls log NAT violation attempts
When coding network applications:
# Python example validating IP ranges
import ipaddress
def is_private(ip):
private_ranges = [
ipaddress.IPv4Network('10.0.0.0/8'),
ipaddress.IPv4Network('172.16.0.0/12'),
ipaddress.IPv4Network('192.168.0.0/16')
]
ip_obj = ipaddress.IPv4Address(ip)
return any(ip_obj in network for network in private_ranges)
print(is_private('192.168.1.1')) # Returns True
RFC 4193 defines Unique Local Addresses (fc00::/7) as IPv6's equivalent, with similar routing restrictions implemented via BGP policies.