Learn Subnets or Invite Thieves
Reading Time:
Reading Time:
In an era of relentless cyber threats, from sophisticated data breaches to the opportunistic attacks of bad actors, the old adage "an ounce of prevention is worth a pound of cure" has never been more relevant.
For anyone building and deploying applications, particularly in the cloud or with container technologies like Docker, this prevention comes in the form of a seemingly simple concept: subnets.
Too often, subnets are seen as a dry, technical detail—just another box to check in a configuration menu. This perspective is dangerously misguided. A failure to properly design and utilize subnets is akin to leaving the doors and windows of your digital home unlocked while the most valuable possessions—your data and your users' privacy—are in plain sight.
This is especially critical for applications handling sensitive information, such as financial, personal, or medical data. Privacy regulations like HIPAA and GDPR mandate strict controls over data access. Subnets provide the foundational structure to enforce these controls, ensuring that medical records, for instance, are isolated from the public internet and accessible only to authorized services on a specific, secured network segment.
This article will explore why subnets are not just a best practice, but an essential defense strategy. We'll start with a non-technical explanation, dive into the technical implementation in both cloud and Docker, and conclude with an advanced use case for building a completely isolated, internal-only application.
Imagine your entire digital infrastructure—all your servers, databases, and application components—as a massive office building. A single, flat network is like having one enormous, open-plan office where everyone can see and talk to everyone else, and the front door is left wide open.
A subnet is like building a series of separate, secure rooms within that office.
This is where visitors (internet traffic) are allowed. It's heavily monitored, and only the receptionist (your web server) is allowed to interact with the outside world.
This room is for your employees (application servers). It has a locked door and a strict rule: you can only enter if you're coming from the lobby. No one from the outside can ever just walk in.
This is the most secure room, where your most sensitive information is stored. It has multiple layers of locks and a rule that's even stricter: only staff from the lounge can enter, and only on a specific business-related errand (a data query).
By creating these separate rooms—these subnets—you gain control. An intruder who manages to sneak past the receptionist in the lobby still can't get into the vault. This segmentation is a multi-layered defense that is far more effective than trying to protect a single, open space.
To truly understand how subnets work, you need to look at the anatomy of an IP address and a notation known as CIDR, or Classless Inter-Domain Routing. This is the simple yet powerful language that network engineers use to define network boundaries.
An IPv4 address is a 32-bit number, usually written in four "octets" separated by dots (e.g., 192.168.1.10). Each octet represents 8 bits and can have a value from 0 to 255.
This is the number you see after the slash, like /16 or /24. It tells you exactly how many bits from the left side of the IP address are fixed and represent the network part. The remaining bits are for the host part, which can change to identify individual devices within that network.
Let's break down some examples:
10.0.0.0/16/16/16 means the first two octets (10.0) are the network portion.10.0 (16 bits) are fixed.0.0 (16 bits) are available for hosts.2^(32-N), where N is the CIDR suffix. In this case, 2^(32-16) = 2^16 = 65,536 total addresses. This is why it's a "large, private address space" suitable for an entire VPC.10.0.1.0/24/2410.0.1 (24 bits) are fixed.0 (8 bits) are available for hosts.2^(32-24) = 2^8 = 256 total addresses. This is a much smaller, more manageable segment. All devices on this subnet will have an IP address starting with 10.0.1.192.168.100.0/28/28192.168.100.0 (28 bits) are fixed.0000 (4 bits) are available for hosts.2^(32-28) = 2^4 = 16 total addresses. However, in practice, you lose 2 addresses: one for the network address (192.168.100.0) and one for the broadcast address (192.168.100.15). This leaves exactly 14 usable addresses.192.168.100.1 through 192.168.100.12.This structure is the very essence of subnetting: you take a large block of addresses (the VPC's /16 network) and subdivide it into smaller, more granular blocks (the subnets with /24s, /28s, etc.).
Let's break down the math step by step so you can calculate subnet sizes yourself:
Total Addresses = 2^(32 - CIDR_Suffix)
Here's why this works:
Example 1: /16 Network
Example 2: /24 Network
Example 3: /28 Network
| CIDR Suffix | Total Addresses | Usable Addresses | Use Case |
|---|---|---|---|
/16 |
65,536 | 65,534 | Large VPC, Enterprise |
/20 |
4,096 | 4,094 | Medium Organization |
/24 |
256 | 254 | Department, Team |
/26 |
64 | 62 | Small Office |
/28 |
16 | 14 | Small Team |
/30 |
4 | 2 | Point-to-Point |
/31 |
2 | 0 | Point-to-Point (special) |
/32 |
1 | 1 | Single Host |
Formula: Choose CIDR where 2^(32-CIDR) - 2 ≥ Number of devices you need
Examples:
Pro Tip: Always round up to the next power of 2 to give yourself room for growth. If you need 50 devices, don't use /26 (62 usable) - use /25 (126 usable) for future expansion.
Understanding this structure gives you the power to create highly specific security rules. Instead of allowing traffic from an entire subnet, you can create rules that only permit a single, specific IP address.
For example, in a cloud security group, you might have a rule on your database that says:
10.0.1.5/32The /32 CIDR notation is a key tool here. It signifies that all 32 bits of the IP address are part of the network, meaning the "network" is a single host. This rule explicitly allows a connection only from the device at 10.0.1.5, not from any other device on the 10.0.1.0/24 subnet. This is a crucial defense-in-depth strategy that provides the ultimate in network isolation.
In a cloud environment like Amazon Web Services (AWS), your primary network is a Virtual Private Cloud (VPC). The VPC is your own logically isolated network, and subnets are the subdivisions within it.
A classic, secure cloud application architecture utilizes subnets to enforce a layered defense.
This subnet contains resources that need to be accessible from the internet, such as a web server or a load balancer. It has a route table that points to an Internet Gateway (IGW), allowing inbound and outbound traffic. You secure it using Network ACLs and Security Groups that permit only necessary traffic (e.g., HTTP/HTTPS).
This subnet hosts your application servers. It has no direct route to the Internet Gateway. Instead, any outbound internet access for tasks like software updates is routed through a NAT Gateway in the public subnet. This design prevents attackers from directly accessing your application from the internet.
This is where your databases reside. Like the application subnet, it has no direct internet connectivity. Security groups on the database instances are configured to allow connections only from the application servers in the private subnet, locking down the most critical data layer.
This structure ensures that even if a web server is compromised, the attacker cannot pivot to the database without first breaching the security rules between the subnets.
Docker's networking model provides its own form of subnets for container-level communication. While the default bridge network is a good start, it's too flat for production applications. The real power comes from creating user-defined networks.
Let's illustrate how to use Docker networks for isolation.
version: '3.8'
services:
web:
image: my-web-app:latest
ports:
- "80:80"
networks:
- web-network
- internal-db-network
database:
image: postgres:14
environment:
- POSTGRES_PASSWORD=mysecretpassword
networks:
- internal-db-network
networks:
web-network:
driver: bridge
internal-db-network:
driver: bridgedatabase).The key is that no one from outside can access the database service directly. It is completely walled off from the host's network and any other containers not on the internal-db-network. This level of isolation is crucial for microservices architectures where different services need to talk to each other but not to the outside world.
Now, let's combine cloud and Docker concepts to build a fully private application that is never exposed to the public internet, a common requirement for internal-facing corporate tools or applications handling highly sensitive data like patient records.
This architecture involves creating an application that is only accessible from within a trusted, controlled network, like a corporate office VPN.
Start by creating a new VPC in AWS. We will not create any public subnets or an Internet Gateway. The entire VPC will be private.
10.0.0.0/16 (a large, private address space)10.0.1.0/24 in us-east-1a10.0.2.0/24 in us-east-1b (for high availability)To manage and deploy the application, you need a way to securely connect to this private VPC. You'll create a small EC2 instance (e.g., a "bastion host") with a public IP address in a small, tightly controlled public subnet. This subnet will have a security group that only allows SSH access from your trusted IP address.
10.0.0.0/24 with a route to an Internet Gateway.10.0.1.0/24 and 10.0.2.0/24).On each private EC2 instance, use Docker Compose to deploy your application. You will create private Docker networks just like in the previous example. The key difference is that no container port is ever published to the host with -p.
EXPOSE instruction in your Dockerfile, not published with -p.The only way to access the application is through a secure tunnel or a VPN connection that allows you to connect to the private VPC's address space. A common method is to use your VPN to access the internal 10.0.0.0/16 network, and then access your application via its internal IP address (e.g., http://10.0.1.100).
This setup ensures that all data traffic, including web requests and database queries, remains entirely within your private network and never traverses the public internet, satisfying the highest standards for data privacy and security.
This advanced model demonstrates the true power of subnets: they enable you to design and build highly specialized, secure environments where access is not just restricted, but architecturally impossible for unauthorized parties from the outside.
While the techniques we've discussed are essential for current IPv4 networks, there's an elephant in the room that could fundamentally change the subnetting landscape: IPv6. Understanding IPv6 subnetting is crucial because it represents both the future of networking and a potential solution to many of the address conservation challenges we face today.
The core concept of a "subnet" – a logical division of a network – remains the same in IPv6. However, the implementation and common practices are significantly different due to IPv6's enormous address space and design.
192.168.1.0/24 means the first 24 bits are the network, leaving 8 bits for hosts (254 usable addresses).2001:0db8:0000:...)...:ABCD:...)Let's use an example:
Your ISP gives your organization the global routing prefix 2001:0db8:ABCD::/48.
2001:0db8:ABCD: - This is your organization's unique identifier.::/48 - Means the first 48 bits are fixed for your organization.Now, you want to create subnets for different departments or network segments:
2001:0db8:ABCD:0001::/64 - This subnet has 2001:0db8:ABCD:0001 as its network portion. The :: represents the last 64 bits, which are available for hosts.2001:0db8:ABCD:0002::/642001:0db8:ABCD:0003::/64Each of these /64 subnets can contain an enormous number of devices.
The Promise of IPv6:
The Reality of IPv6 Adoption:
Despite these advantages, IPv6 adoption has been slower than expected. Here's why:
While IPv6 solves many problems, it's not a panacea:
In summary, While both IPv4 and IPv6 use subnetting to segment networks, IPv6's vast address space simplifies the process significantly by allowing for a standard /64 prefix for most subnets, removing the need for complex address conservation calculations common in IPv4. IPv6 subnetting is more about creating a logical, hierarchical structure for your network than it is about squeezing every last usable address out of a block.
However, IPv6 adoption is not yet universal, and the security principles we've discussed remain critical regardless of the IP version you're using. Think of IPv6 as the future that will eventually make many of our current IPv4 challenges irrelevant, but for now, mastering IPv4 subnetting remains essential for building secure, scalable networks.
The key takeaway is that subnetting – whether in IPv4 or IPv6 – is fundamentally about network organization and security, not just address management. The principles of segmentation, isolation, and defense-in-depth apply regardless of the underlying protocol.
Subnets are far more than a simple networking feature; they are the architectural manifestation of a security-first mindset. In a world where data breaches are a constant threat, mastering the art of subnetting is no longer optional. It's the critical skill that allows you to segment your network, isolate sensitive assets, and build the kind of resilient, secure applications that protect not only your data but the trust of your users.