USING WILDCARD MASKS TO FILTER ODD OR EVEN NUMBERED IP ADDRESSES: JUNIPER JUNOS & CISCO IOS
Here’s an interesting problem: imagine a user who says they’re only able to access even-numbered IPs in a destination subnet. “Help!”, they say in the ticket. “I can’t leave the office until this is fixed, and I need to leave now because my seven large sons require their tri-daily feed of protein shakes. They will whither and die unless I nourish them immediately. The fate of my powerful sons is in your hands, and yours alone.”
This exact problem came in to us recently. Well, apart from the bit about the large sons.
Now, even if you’re an experienced network engineer it wouldn’t surprise me if you didn’t know what technology could cause this problem – because even though you’ve used the technology for your whole networking career, it’s taught so badly that not even 2% of engineers actually know it. Where did I get that 2% number? The most reliable of all sources: my imagination.
The answer lies in an interesting quirk of wildcard masks: something we’re taught when we first do our CCN… sorry, I mean when we do our certification with “other vendors”. 😉 See, we’re only told part of the wildcard mask story. They’re actually really powerful, and allow you to easily and elegantly do things far beyond the strict rules of subnet masks. If this is news to you, then gosh darnit this is the blog post you’ve spent your entire life hoping for!
BUT WAIT! YOU CLAIM THIS IS A JUNIPER BLOG – AND YET, THIS POST IS 80% CISCO IOS EXAMPLES! EXPLAIN YOURSELF, YOU SCOUNDREL / LIAR / FRAUD / CHARLATAN ETC. EXPLAIN YOURSELF BEFORE I SUE YOU FOR PRECISELY £20.
Yep: my reasoning is that most people are far more familiar with wildcard masks on Cisco, because you *have* to use them in access lists on routers.
When you make firewall filters in Junos, you configure what appears to be a subnet mask, so people don’t immediately associate wildcards with Juniper. But as we’ll see, you can absolutely use them on Juniper too – and, in my humble fanboy opinion, Junos makes them a h*ck (heck) of a lot easier to conceptualise and use.
So, we’ll do it Cisco first, because if you’re reading this then you’re almost certainly more used to Cisco wildcard logic. Then, once you’ve got that down, we’ll do Junos – and in doing so, I’ll take you to levels of pleasure that you didn’t even know you were capable of feeling.
BACK TO BASICS: HOW ARE WILDCARD MASKS DIFFERENT TO SUBNET MASKS?
So, if you’re anything like me (ie a geek who mainly got into networking to make sure that his access to memes adheres to a strict 99.99999% uptime SLA), you probably felt very frustrated back in the day when you went to your introduction-to-networking course, and learned that the “subnet” part of a Cisco access list is configured differently to a normal subnet mask.
For example, when you configure an interface, you set the IP as “192.168.1.1 255.255.255.0” – but when you configure an access list, you do it as “access-list 1 permit 192.168.1.0 0.0.0.255“. Why? WHY??
Three separate teachers gave me this answer: “for backwards compatibility purposes”. They told me that wildcard masks came about before subnetting – in other words, when IPs were classful – and because they’ve always been configured in this way, we still do it today. Now, this may or may not be true. I don’t know. And sadly, the 1980s were so long ago that there’s literally no-one alive on the planet today from those times who we could ask. Don’t trust anyone in the comments who claims to be from those times, and therefore knows the truth: they’re no more reliable a source of historical fact than the Bayeux Tapestry, or the first season of Friends.
(Jokes: if you actually know if this is true or not, please comment!)
But in any case, it turns out that they missed a perfect opportunity to explain a crucial concept to me. And indeed, the truth of wildcard masks is almost never covered in any CCNA training, whether official or unofficial.
See, it turns out that a wildcard mask isn’t *just* a subnet mask with the bits inverted. Yes, it’s true that you write 255.255.255.0 as 0.0.0.255 – in other words, “the first three octets of the IP address have to stay the same, but the fourth octet can be whatever you like”. But did you know that you could have a wildcard mask of 0.0.255.0?
Imagine this:
access-list 101 permit ip any 192.168.0.1 0.0.255.0
This access list would permit you access to 192.168.0.1, 192.68.1.1, 192.168.2.1… in other words, the real difference is that with wildcard masks, the “significant bits” don’t all need to be contiguous (in a row) like they do in a subnet mask. That means that you can actually do some incredibly precise and powerful stuff with them!
HOW DO WE FILTER JUST-ODD OR JUST-EVEN IP ADDRESSES WITH A WILDCARD MASK?
Good question!
Take a look at this sweet topology:
Then, believe me when I tell you, with my hand on my heart, that I’ve put an access list on Router 1’s Fa2/0 interface, filtering inbound traffic:
access-list 101 permit ip any 10.10.10.0 0.0.0.254 interface FastEthernet2/0 ip access-group 101 in
So what’s happening here? Well, let’s write the IP address out in binary (in green), and then write the wildcard mask out in binary underneath it (in blue):
00001010 . 00001010 . 00001010 . 00000000
00000000 . 00000000 . 00000000 . 11111110
When we compare an IP address against a Cisco wildcard, we’re saying that if a bit in the wildcard mask is a 0, then the equivalent bit in the IP address has to stay the same. But if the bit in the wildcard mask is a 1, then we don’t care about the equivalent bit in the IP address.
In our access list, the first seven bits of the final octet are all 1s, which means that these seven octets can be anything. We don’t mind, or care.
The final bit in the last octet of our wildcard mask is a 0. This means that the equivalent bit in the IP address always has to stay the same.
In this case, the last bit in our IP address is a 0 – because of course, 0 in decimal is also 0 in binary! The result of this rule is that the very last bit in any destination IP address coming into this interface always has to be zero. But – and this is crucial – the rest of the bits in that final octet can be anything. Anything!
Think about what IP addresses this rule would match: if the final bit is a 0, and the rest of the bits in the octet can be anything, the result is that this access list matches every even numbered IP address!
Want proof? Of course you do. Let’s try pinging the four IP addresses in the 10.10.10.0/24 LAN:
Well, how about that! Every even-numbered IP address responds to ping, just like our wildcard mask said!
What if you want to allow access only to odd-numbered IP addresses? No problem – you just start the IP address in your access list at an odd number:
no access-list 101 access-list 101 permit ip any 10.10.10.1 0.0.0.254
Now, the final bit in the last octet of the IP address we gave is a 1 – which means it always has to be a 1 for any destination address going through this interface. In other words, all the odd numbers!
And here’s the result:
Wowzer! We truly are heroes.
Now, in the real world it’s unlikely that you’d ever need to block access only to odd or even numbered IPs (but you’ll definitely need to know about this logic for when customers do it by mistake!) – but there is actually a real-world case for this functionality that you’ll find very handy indeed.
Before we look at this real-world use-case, let’s see how Juniper made wildcards a little bit (ie a lot) more readable.
WILDCARD MASKS IN JUNOS: FIREWALL FILTERS AND SECURITY POLICIES
Cast your mind back to the customer I mentioned at the start of this post. You can easily see how someone might mean to use a wildcard mask of 0.0.0.1, but accidentally type 0.0.0.254. It’s all to easy to mistake subnet logic with wildcard logic. Like how sometimes I mistake salad for cake. It’s all too easy to make that mistake when I’m not concentrating.
Well, in Junos there’s no such wildcard mistakes. Let’s “cut” to the “chase”: Juniper does away with the inverse mask thing, and instead you just write a wildcard mask like a normal subnet mask – while still retaining the wildcard flexibility! In other words, everything you previously knew about subnet mask binary is still true, and it’s infinitely more easy to understand.
To achieve what we did with that access list, let’s make a firewall filter to block even-numbered IP addresses.
Notice that in this example, I’m using an action of discard in the rule, whereas in the Cisco example I used a permit. You can use either, as long as your logic is right, and as long as you’ve got a rule underneath permitting or denying other traffic as required! I just wanted to give examples of both permit/accept and deny/discard, to show you that you can do it either way – as long as you change your starting address accordingly:
[edit firewall] root# show filter WILDCARD_EXAMPLE { term BLOCK_EVENS { from { destination-address { 10.10.10.0/255.255.255.1; } } then { discard; } } term PERMIT_ALL_ELSE { then accept; } } [edit interfaces em1] root# show unit 0 { family inet { filter { input WILDCARD_EXAMPLE; } address 12.12.12.1/24; } }
In other words, “The last bit in the mask is a 1, which means I care what the last bit of the IP address is. The last bit in the IP address is a 0, which means that I’m interested in matching any even-numbered IP address. If an address matches this rule, discard it. Discard it into the pits of hell.”
Here’s the results: as you’d imagine, odd-numbers reply to pings, and even-numbers are blocked. As with our example earlier, you can block odd-numbered IPs by putting the destination address as 10.10.10.1.
What’s that? You want to know how to do the same thing on an SRX? No problem, Karen! Just make an address book entry like normal, but use the command “wildcard-address” before you enter it:
[edit security zones security-zone trust] root# show address-book { address 10.10.10.x_BLOCK_EVENS { wildcard-address 10.10.10.0/255.255.255.1; } }
(In fairness, you can do this on Cisco ASA too – but the downside is that you’d have to use a Cisco ASA. See, there’s always a trade-off.)
A REAL-WORLD CASE FOR THIS
Let’s go back to that very first example I gave earlier, and imagine a perfect network, with logical, elegant subnetting. I know I know, it’s the stuff of science fiction, but try to imagine it.
You might choose to use the private range 192.168.0.0/16 across your entire network, which you’ve subnetted into as many /24s as you like. And perhaps on each subnet, a machine with the IP address of 192.168.x.4 is acting as a server of some kind, offering the same functionality on each subnet.
Let’s say that you want to write a rule somewhere, allow access only to the 192.168.x.4 address on each subnet. Such a rule would take a lot of lines in a normal firewall rule or access list. You’d need a firewall rule or access list for each subnet. Well, with our newfound power, we can do it in no time at all. On Cisco:
access-list 101 permit ip any 192.168.0.4 0.0.255.0
access-list 101 deny ip any any
And on Juniper:
set firewall filter WILDCARD_EXAMPLE term ALLOW_192.168.x.4 from destination-address 192.168.0.4/255.255.0.255
set firewall filter WILDCARD_EXAMPLE term ALLOW_192.168.x.4 then accept
set firewall filter WILDCARD_EXAMPLE term BLOCK_ALL_ELSE then discard
We’ve successfully allowed access to 192.168.1.4, 192.168.1.4, 192.168.2.4, and so on. In doing so we’ve solved all geo-political crises, ended all wars, and made ourselves billionaires. Time to retire? You betcha!
THAT’S IT!
In my experience, the vast majority of network engineers don’t actually know how powerful wildcard masks can be, because wildcard masks simply aren’t taught properly. And in fairness, it’s probably rare that we’d need to do this kind of filtering. But because it’s so easy to make a mistake in a wildcard, especially when dealing with inverse bits, it’s far more common for customers to accidentally break things. Luckily, with this new knowledge, we can fix these problems, and be a hero for all of, oh, I don’t know, 15 minutes? Maybe less? Probably less.
I hope you’ve learned a thing or two from this post, and had some laughs and smiles along the way! If you enjoy my nonsense writing, then you’ll always make my day if you share this post on your favourite social media of choice.
If you’re on Mastodon, follow me to find out when I make new posts. (2024 edit: I’m also on BlueSky nowadays too. I was once on Twitter, but I’ve given up on it, on account of… well, I don’t need to finish that sentence, do I.)
Fun fact: I’m currently running a competition where I’ll give away a trillion pounds when I reach a trillion followers. So make sure you follow me immediately to be a part of this historic, and very real, event.
And if you fancy some more learning, take a look through my other posts. I’ve got plenty of cool new networking knowledge for you on this website, especially covering Juniper tech and service provider goodness.
It’s all free for you, although I’ll never say no to a donation. This website is 100% a non-profit endeavour, in fact it costs me money to run. I don’t mind that one bit, but it would be cool if I could break even on the web hosting, and the licenses I buy to bring you this sweet sweet content.
Hi, Chris!
It’s a really powerful technology and I can’t understand how could I manage my network without it. But I have only one question.
What about IPv6? As far as I know Cisco supports only prefixes and do not supports masks and wildcards. Does Juniper do that too?
Thank you for nice article.
Hi there Mikhail!
I believe this is the answer to your question: https://www.juniper.net/documentation/en_US/junos/topics/concept/firewall-filter-flexible-match-conditions-overview.html
It’s definitely not as easy to get your head around, but I *think* that with a bit of experimenting, you could get it do do the same thing. It looks like the “flexible-match-mask” command lets you filter on the entire header – in other words, the power we previously had in wildcard masks for IP addresses, we now have over every single field in the packet!! I might be wrong on that – as I say, I’ve not used it before myself, and it looks quite complicated so I think I’ll have to lab it up sometime to be sure.
Thank you for the link. I am not using any one of Juniper devices now but this feature looks interesting that I want to try this 🙂
Thank you so much indeed! I didn’t know how to use WC Mask to ouput even ip addresses.Now, I know clearly.
Thank you sire! you explained it clearly. Love your sense of humour 🙂