I have recently been configuring squid proxy behind loadbalancer, in order for squid to allow incoming PROXY protocol connections from loadbalancer, I quickly decided easiest option would be either whole vpc CIDR range:
acl loadbalancer src 10.139.0.0/17 proxy_protocol_access allow loadbalancer
or list of subnets from 3 AZs where loadbalancer is running:
acl loadbalancer src 10.139.64.64/28 10.139.64.96/28 10.139.64.80/28 proxy_protocol_access allow loadbalancer
Even though both configurations are valid, my pull request quickly caught attention of more experienced in networking(in fact ex CCNP guy) colleague of mine. But that is the beauty of modern operations teams working in devops fashion, while he may catch this sort of issues, I (ex developer guy) for instance can easily spot how duplication in piece of bash or python code could be avoided by refactoring it into a reusable function/template.
So back to our problem, as I said, while both ranges are valid, first in fact is much wider than actually required, and second is too redundant.
Enter supernetting.
So what is that?
Just like subnets divide a single big network into smaller subnetworks, supernets combine a smaller networks into a bigger network. This means we need to take our subnets:
10.139.64.64/28 10.139.64.96/28 10.139.64.80/28 and make a bigger network, but how?
Once you know how it works, it is quite easy, so let’s show our network address in binary to understand how it works.
➜ ~ ipcalc 10.139.64.64 | grep -i address
Address: 10.139.64.64 00001010.10001011.01000000. 01000000
➜ ~ ipcalc 10.139.64.80 | grep -i address
Address: 10.139.64.80 00001010.10001011.01000000. 01010000
➜ ~ ipcalc 10.139.64.96 | grep -i address
Address: 10.139.64.96 00001010.10001011.01000000. 01100000
➜ ~
As you can see 00001010.10001011.01000000.01 part is same for all. That is first 3 octets + first two bits of 4th octet, now we revert it back to decimal and then use number of similar bits as CIDR number:
10.139.64.64/26
Lets prove that network includes our smaller networks:
ipcalc 10.139.64.64/26 -b --s $(for i in {1..3};do echo 8; done) Address: 10.139.64.64 Netmask: 255.255.255.192 = 26 Wildcard: 0.0.0.63 => Network: 10.139.64.64/26 HostMin: 10.139.64.65 HostMax: 10.139.64.126 Broadcast: 10.139.64.127 Hosts/Net: 62 Class A, Private Internet 1. Requested size: 8 hosts Netmask: 255.255.255.240 = 28 Network: 10.139.64.64/28 HostMin: 10.139.64.65 HostMax: 10.139.64.78 Broadcast: 10.139.64.79 Hosts/Net: 14 Class A, Private Internet 2. Requested size: 8 hosts Netmask: 255.255.255.240 = 28 Network: 10.139.64.80/28 HostMin: 10.139.64.81 HostMax: 10.139.64.94 Broadcast: 10.139.64.95 Hosts/Net: 14 Class A, Private Internet 3. Requested size: 8 hosts Netmask: 255.255.255.240 = 28 Network: 10.139.64.96/28 HostMin: 10.139.64.97 HostMax: 10.139.64.110 Broadcast: 10.139.64.111 Hosts/Net: 14 Class A, Private Internet
As you can see, we have a bigger network now 10.139.64.64/26 which includes smaller 10.139.64.64/28 10.139.64.96/28 10.139.64.80/28 networks.
This technic is very popular and can be used in other places as well, like routing tables, NACLs, security groups etc.