What makes a private IP address not routable?
Private IP addresses are routable, albeit they are not publicly routed. Basically, a router will route a private address to private/internal LAN, rather than to the internet.
To expand my answer: a router can route a private address to the public side, via its default gateway. However, the packet will be "lost" in transit due to other routers dropping it, or due to packet's TTL reaching 0.
For example, give a look at this (partially obfuscated) traceroute -I -n 192.168.200.1
:
[root@myhost ~]# traceroute -I -n 192.168.200.1
traceroute to 192.168.200.1 (192.168.200.1), 30 hops max, 60 byte packets
1 x.x.x.x 0.851 ms 0.841 ms 0.818 ms
2 6x.xx.xx.xx 0.791 ms 0.791 ms 0.849 ms
3 15x.xx.xx.xx 1.350 ms 1.347 ms 1.373 ms
4 15x.x.xx.xx 1.446 ms 1.435 ms 1.428 ms
5 151.6.68.20 2.272 ms 2.266 ms 2.251 ms
6 151.6.0.91 8.818 ms 8.256 ms 8.326 ms
7 * * *
8 * * *
9 * * *
10 * * *
...
...
29 * * *
30 * * *
As you can see, the packet is routed to the public internet via the machine's default gateway. However, it is dropped during the transit and never reaches any proper destination.
After all, private IPs/classes are (by definition) overlapped between customer, so on which of the thousands 192.168.200.x/24 networks should be routed this packet?
An interesting side note: internet providers often uses private addresses for their internal routing. If, for example, a private 192.168.200.x/24 classes is used for internal routing, the first router/machine with IP 192.168.200.1 will receive but drop the packet, because it was unsolicited. ICMP are an interesting exception, as router/machines generally replies to unsolicided PINGs. This means you sometime can use private address scans to map your ISP private network.
Usually, private IP addresses are filtered by the ISP. Your access router should also be configured to not make them leak.
Private IP addresses can't be used on the Internet because anyone could be using them. There are probably many million devices using 192.168.1.1 privately - which one is an Internet router supposed to send the packet?
Zeroconf addresses (169.254.0.0/16) are actually not routable. These can be used anywhere in an ad-hoc fashion but they can't access the Internet or any subnet but their local one. They can't be routed because they can only be valid inside the broadcast domain where each device can select an unused address by itself. By definition, zeroconf has no management instance like a DHCP server.
However, what exactly is stopping these addresses from being routable?
Accepted standards that are enforced by entities communicating. These are enforced in software, hardware, and configurations.
Do ISPs implement ACLs that prevent these networks from routing or is it something higher up?
They can but what is really being stopped is merely an invalid translation that does not follow standards.
If you are like most home users, you have one IP address assigned to you as a public IP address. In order for traffic from all of your connected devices to communicate, the router performs translation of those internal IP addresses using NAT (network address translation) or PAT (port address translation).
Basically, your router remembers which internal IP addresses in your LAN (local area network) started a session reaching outside of your LAN, through the router, and out the WAN (wide area network) interface. When data exits the router it contains that single IP address assigned to you as the source IP. When it enters, the packet contains the same address as the destination IP. The router decides then where it gets directed from there.
To the outside, you have only one single IP address which is actually the IP of the router. The router is able to track those sessions and determine which traffic belongs to each internal IP address on it's LAN and directs that traffic accordingly. It's a complex management process but the idea is actually quite simple once you understand that everything is being translated at each router.
Furthermore, most home routers have switching ports, whereby the traffic is delivered via MAC address, not IP address. The source MAC address in the packet remains the same until it hits a router. The router strips that source MAC address and inserts the MAC address of it's own WAN interface.
Also, is it IANA that created this design?
These standards were not originally designed by IANA. Today, although they take the lead on setting standards, they certainly do not enforce them through any means of law. They are standards that are enforced through consensus. Search RFC 791.
They have "authority" to to the extent that everyone is willing to adhere to them. It is completely possible to defy these standards but you will eventually run into an ISP somewhere along the path that will demand that you do adhere or they will drop your traffic.
I hope that helps..
As a point of clarification from the other answers, private IP address ranges that you are using locally do not route to the Internet because they have their own explicit entries in the routing table. Here's my route table from my desktop at home, for example:
$ ip route
default via 192.168.1.1 dev enp5s0 proto dhcp src 192.168.1.104 metric 1024
172.17.0.0/16 dev docker0 proto kernel scope link src 172.17.0.1 linkdown
172.18.0.0/16 dev br-90a372f4b373 proto kernel scope link src 172.18.0.1 linkdown
192.168.1.0/24 dev enp5s0 proto kernel scope link src 192.168.1.104
192.168.1.1 dev enp5s0 proto dhcp scope link src 192.168.1.104 metric 1024
Note the 172.17.0.0/16
and 172.18.0.0/16
. Packets to these networks will go straight to my docker bridges, without ever leaving my computer, because they have a specific entry in my route table. The 192.168.1.0/24
entry explicitly says traffic to that network will go out the enp5s0
interface. My router's route table will have a similar entry that will send all traffic for that private network out the interface my desktop is connected to.
It's only packets for networks that aren't explicitly in the table that will go to the default route. You can explicitly mark a network as unreachable by:
$ ip route add unreachable 10.0.0.0/8
This changes my route table to:
$ ip route
default via 192.168.1.1 dev enp5s0 proto dhcp src 192.168.1.104 metric 1024
unreachable 10.0.0.0/8
172.17.0.0/16 dev docker0 proto kernel scope link src 172.17.0.1 linkdown
172.18.0.0/16 dev br-90a372f4b373 proto kernel scope link src 172.18.0.1 linkdown
192.168.1.0/24 dev enp5s0 proto kernel scope link src 192.168.1.104
192.168.1.1 dev enp5s0 proto dhcp scope link src 192.168.1.104 metric 1024
Now, my desktop won't even try to ask the default gateway about addresses in that range. Lookups for that address immediately return "No route to host."
$ traceroute 10.0.0.1
traceroute to 10.0.0.1 (10.0.0.1), 30 hops max, 60 byte packets
connect: No route to host
Packets for unreachable networks that aren't explicitly marked as unreachable in the route table will just keep being forwarded via the default routes, until the packet either reaches a router that explicitly knows the network is unreachable, or the TTL expires.