.. Copyright (c) 2021 Varnish Software AS SPDX-License-Identifier: BSD-2-Clause See LICENSE file for full text of license .. _phk_ip_address: ====================================== IP Addresses - A long expected problem ====================================== I'm old enough to remember `HOSTS.TXT` and the introduction of the DNS system. Those were the days when you got a class B network by sending a polite letter to California, getting a polite letter back, and then, some months later, when `RFC1166 INTERNET NUMBERS `_ arrived with in semi-annual packet of printed RFCs, find out that letter had at typo and you had configured all of the European Parliaments 1200 computers on 136.172/16 instead of 136.173/16. But things were not simpler, if anything they were far more complex, because TCP/IP was not, as today, the only protocol that mattered. In addition to TCP/IP, there were IBM's SNA, Digitals DecNet, ApolloRing, Banyan/VINES, Novell NetWare, X.21, X.25, X.75, and the whole CCITT-OSI-"Intelligent Network" telecom disaster that never got off the ground. This is why DNS packets have a `class` field which can be set to `Hesiod` or `CHAOS` in addition to `the Internet`: The idea was that all the different protocols would get a number each, and we would have "The One Directory To Rule Them All". Largely because of this, a new and "protocol agnostic" lookup functions were designed: `getaddrinfo(3)` and `getnameinfo(3)`, but of course for IP they were supposed to be backwards compatible because there were *thousands* of users out there already. This is why `telnet 80.1440` tries to connect to `80.0.5.160`, why `ping 0x7f000001` becomes `127.0.0.1` and `0127.0.0.1` becomes `87.0.0.1`. If you read the manual page for `getaddrinfo(3)` you will find that it does not tell you that, it merely says it `conforms to IEEE Std 1001`. But everybody knew what that was back in 1990, and nobody had firewalls anyway because Cheswick & Bellowins book `Firewalls and Internet Security `_ was not published until 1994, so no worries ? As is often the case with 'designed for the future' the `getaddrinfo(3)` API instantly fossilized, hit by a freeze-ray in the 'the Unix™ wars'. This is why, when IPv4 numbers started to look like a finite resource, and the old A-, B- and C- class networks got dissolved into Classless Inter-Domain Routing or "CIDR" netmasks of any random size, getaddrinfo(3) did not grow to be able to translate "192.168.61/23" into something useful. I believe there were also some lilliputian dispute about the fact that `192.168.61` would return `192.168.0.61` to stay backwards compatible, whereas `192.168.61/23` would return `192.168.61.0 + 255.255.254.0`. Because of this, Varnish uses `getaddrinfo(3)` everywhere but one single place: Parsing of ACL specifications in VCL. First we have to use our own parser to check if it is a CIDR entry and if not we ask `getaddrinfo(3)`. The reason for this rant, is that somebody noticed that `ping 0127.0.0.1` didn't go to `127.0.0.1` as they expected. That has just become CVE-2021-29418 and CVE-2021-28918 and will probably become a dozen more, once the CVE-trophy-hunters go to town. All IP number strings enter Varnish from trusted points, either as command line arguments (`-a`, `-b`, `-M` etc.), in the VCL source (`backend`, `acl` etc.) or as PROXYv1 header strings from the TLS-stripper in front of Varnish. Of course, VCL allows you to do pretty much anything, including:: if (std.ip(req.http.trustme) ~ important_acl) { ... } If you do something like that, you may want to a) Consider the wisdom of trusting IP#'s from strangers and b) Think about this "critical netmask problem". Otherwise, I do not expect this new "critical netmask problem" to result in any source code changes in Varnish. If and when the various UNIX-oid operating systems, and the smoking remains of the "serious UNIX industry", (IEEE ? The Austin Group ? The Open Group ? Whatever they are called these days) get their act together, and renovate the `getaddrinfo(3)` API, Varnish will automatically pick that up and use it. Should they, in a flash of enlightenment, also make `getaddrinfo(3)` useful for parsing these newfangled CIDR adresses we got in 1993, I will be more than happy to ditch `vcc_acl_try_netnotation()` too. Until next time, Poul-Henning, 2021-03-30