One of the most difficult components to grasp with ACLs is the wildcard mask. Wildcard masks are used to match on a range of IP addresses in a condition. For example, imagine that you want to allow a device to access any address in 192.168.1.0/24. One approach is to have 254 permit statements for these addresses: 192.168.1.1 through 192.168.1.254. This takes a lot of time to configure and places an extra burden on the router to process all of these statements. Instead, the Cisco IOS uses a feature called wildcard masks. Wildcard masks enable you to match on a range of addresses in a single condition, such as 192.168.1.0/24. A wildcard mask can match on all 256 of these addresses.
The greatest confusion involving wildcard masks concerns how they are configured to match on a range of addresses. Like IP addresses and subnet masks, wildcard masks are 32 bits in length. When comparing a wildcard mask to a subnet mask, however, the bit values used in both (0 and 1) mean different things. Table 6-2 compares the bit values in subnet and wildcard masks and tells what they represent.
Mask | Binary 1 | Binary 0 |
---|---|---|
Subnet mask | A bit in the corresponding address is a network component. | A bit in the corresponding address is a host component. |
Wildcard mask | A bit in the corresponding condition address is ignored. | A bit in the corresponding condition address must match. |
NOTE
With standard IP ACLs, the wildcard mask is optional. If you omit it, the wildcard mask defaults to 0.0.0.0. With extended IP ACLs, the wildcard mask is required for both the source and destination addresses.
Probably the best way to look at a wildcard mask is to compare it to an inverted subnet mask. For example, say that you want to match on network 192.168.1.0/24. This network is a subnet mask of 255.255.255.0. To invert this mask, flip all the 1 bits to 0s and all the 0 bits to 1s. This results in twenty-four 0 bits and eight 1 bits, or 0.0.0.255. Therefore, to match on all addresses in network 192.168.1.0/24, you would use a wildcard mask of 0.0.0.255.
TIP
I have developed a quick trick to perform the conversion process from subnet mask to wildcard mask. First, write down the subnet mask in dotted decimal. Subtract each octet from 255, resulting in the corresponding wildcard mask value for that octet.
Take a look at some examples of performing the conversion. In the first example, I want to figure out the wildcard mask that will match on any packet. In IP, the default network (any address) is 0.0.0.0/0, resulting in a subnet mask of 0.0.0.0. When performing the conversion, the resulting wildcard mask for all address is 255.255.255.255 (subtract each subnet mask octet from 255). To match on any address, you would use an IP address of 0.0.0.0 and a wildcard mask of 255.255.255.255. Like a subnet mask, the context of the wildcard mask is based on the address associated with the mask.
TIP
When configuring an ACL condition and specifying a source address and a wildcard mask that will match on any address, you can either use 0.0.0.0 255.255.255.255 or the keyword any. Both mean the same thing.
In this example, I want to match on one specific address, 192.168.1.1. In subnetting, to represent a single address, you use a /32 (255.255.255.255) mask. To convert this to a wildcard mask, subtract each subnet mask octet from 255. This results in a wildcard mask of 0.0.0.0. Therefore, to match on this specific address, you would use 192.168.1.1 0.0.0.0 in your condition.
TIP
When configuring an ACL condition and specifying a source address and a wildcard mask that will match on a specific address, such as 192.168.1.1, you can use either 192.168.1.1 0.0.0.0 or the keyword host followed by the host address (host 192.168.1.1). Both mean the same thing.
In this third example, I want to create a wildcard mask that will match this range of address: 192.168.1.16/28 (255.255.255.240). To convert this to a wildcard mask, subtract each subnet mask octet from 255, resulting in a wildcard mask of 0.0.0.15. Therefore, to match on 192.168.1.16/28 addresses, you would use the following in your condition: 192.168.1.16 0.0.0.15. As you can see, using this simple trick makes converting subnet masks to wildcard masks an easy process.
NOTE
Unlike subnet masks, wildcard masks support discontiguous 1s and 0s, which enables you to match on a range of values with a specific octet, such as any packet that has a number of 0 to 7 in the third octet.
In this last illustration, I use an example that you might see on a CCIE Routing and Switching or Security written or lab exams. In this example, you are given the following network: 172.16.0.0/16. In this network, you want to match on the first address in each subnet, where the subnet mask is /24. You do not care about the subnet number; you care only about the first address in every subnet, such as 172.16.0.1, 172.16.1.1, 172.16.2.1, and so on. Given these requirements, what kind of address and wildcard mask would you use for your condition? Given the requirements, the address must begin with 172.16. Therefore, the first two octets in the wildcard mask are 0.0. You do not care about the subnet number in the third octet, so the wildcard mask is 255 here. But you do care about the last octet. You want to match on the first address (.1), resulting in a 0 in the fourth octet of the wildcard mask. Therefore, the resulting address and wildcard mask in the condition would be 172.16.0.1 0.0.255.0.
One interesting point to make about this partial condition is that 172.16.0.1 0.0.255.0 and 172.16.1.1 0.0.255.0 mean the same thing. Remember that the wildcard mask specifies that you do not care what is in the third octet; anything matches in this octet. Therefore, it does not matter what number you put here in the address part of the condition. This can be useful if you use the same address in a subnet for a particular type of device, such as a router, and want to match on these addresses. Of course, the example I gave here was simple; CCIEs would be expected to configure something much harder than this.
NOTE
One item to point out is that the Cisco IOS converts any value in an address to 0 if the corresponding wildcard mask value in the octet is 255. For example, if you specified 172.16.1.1 0.0.255.0, the Cisco IOS would change this to 172.16.0.1 0.0.255.0. Note that when the Cisco IOS performs matching, it ignores all values in the third octet. Cisco uses this process to remove any ambiguity about command configuration.
Because of the complexities of wildcard masks, many people make mistakes when configuring the wildcard mask for the address or range of addresses that they want to match on. Here are some common mistakes:
192.168.1.0 255.255.255.0 matches on any packet with any values in the first three octets and a 0 in the last octet. Remember that the mask that you put in is a wildcard mask, not a subnet mask!
192.168.1.1 255.255.255.255 matches on any address. The wildcard mask says to match on all addresses and ignores what you put in for the IP address (192.168.1.1).
192.168.1.0 0.0.0.0 matches on any packet that has an address of 192.168.1.0, which is a network number. Actually, if you see an address like this in a packet, it is a spoofing attack. Probably what the administrator meant to use as a wildcard mask was 0.0.0.255, which is any address in the 192.168.1.0/24 network.