Getting Wild[card masks]
If you ask most people what a wildcard mask is they’ll probably say it’s an inverse subnet mask. That is a massive under-representation of the power of a wildcard mask and does not do fair justice to the range of useful tricks you can do with a wildcard mask.
We’ll start with why people think it’s an inverse subnet mask:
If you want to use a wildcard mask to describe 192.168.1.0 255.255.255.0 you would use 192.168.1.0 0.0.0.255. In this case there is a direct inverse relationship between the subnet mask and the wildcard mask. For a lot of people that’s about as far as you would want to go in to wildcard masks for basic ACLs on routers and switches if you’re not following a security track.
Suppose you want to get a little cleverer with your wildcard masks though. How about you have a bunch of sites that all have IP ranges 192.168.x.0/24 and your site DNS servers are always 192.168.x.10 and 192.168.x.11. In your datacenter you have a couple of top tier DNS servers and you want them to be protected from potentially malicious queries from any hosts other than those two specific DNS servers on each site. We’re going to create ACLs that permit DNS traffic from those hosts and then implicitly deny all the rest of the hosts. With a subnet mask you would need to specify access rules for each site however with a wildcard mask you can do it with a single statement.
You can do this because a wildcard mask is actually very different from a subnet mask and works in the way that a wildcard works in a regex or in many find and replace tools. In many filing systems an asterisk is a wildcard so matches any string of 0 or more characters. Say you want to match files in a filing system that end in .txt you could search for *.txt and if you wanted to find files in the format picture1.bmp, picture2.bmp and picture3.bmp you could use picture*.bmp. Wildcard masks work by looking at the 32 bit binary string that makes up the IP address and matching where there is a 0 while wildcarding where there is a 1. Simply put it doesn’t care about matching where the wildcard bit is set to 1.
In a single octet, if the wildcard mask is 0 for that octet it is all zero bits and so it matches exactly whereas if it’s 255 it is all ones so it wildcards all bits. This is why the aforementioned 192.168.1.0 0.0.0.255 matches with 192.168.1.0, 192.168.1.1,192.168.1.2,192.168.1.3 etc to 192.168.1.255
You can also select across the classful boundaries so if you had a class B address space that you had subnetted into /21 subnets with 2046 hosts you would have a subnet bitmap like this:
If we use the wildcard bits to disregard the host bits we can match any hosts in one of the individual subnets.
This translates in dotted decimal notation:
So back to the example of the remote sites, we want to match the first couple of octets as all our stores start 192.168 and the next octet is variable. The fourth octet is our host so we know what that is supposed to be.
With this bit map we use the following mask to wildcard the subnet bits and match the network and host bits.
We can specify 192.168.x.10 and 192.168.x.11 across all sites with the following wildcard mask statements.
But I did say we can do it with one; that’s because the only difference between the two is 1 bit in the last octet. We can match all of the last octet apart from that bit and the two possibilities are .10 and .11
If you have a predictable IP address schema within your network you can use it to do all sorts of things. Say you had a bunch of routers and the PCI router always had an even number in the last octet of the loopback and the non PCI routers always had an odd numbered loopback. You might want to match just the odds or just the evens in an ACL for management network access; this can be achieved using the wildcard string below.
The above wildcard mask wildcards all but the last bit which is set to match.