
If you have ever set up a Linux server and later discovered that two of your services could not talk to each other, or that your entire network ground to a halt because of a broadcast storm, there is a good chance the root cause was a misconfigured subnet. IPv4 Subnetting on Linux is one of those foundational skills that separates sysadmins who react to problems from those who prevent them. In this guide, you will learn exactly how subnetting works, why it matters in a Linux environment, and how to apply it using real commands that work on Ubuntu, Debian, RHEL, Fedora, and AlmaLinux. No theory without practice. Every concept here gets a working example.
Prerequisites
Before you run any command in this guide, make sure your environment checks these boxes:
- Operating System: Ubuntu 20.04/22.04/24.04, Debian 11/12, RHEL 8/9, Fedora 38+, AlmaLinux 8/9, or Rocky Linux 8/9
- User permissions:
sudoor root access (required for allipandnmclicommands that modify network state) - Tools required:
ipcalc(install instructions in Step 2)iproute2package (provides theipcommand; pre-installed on most modern distros)NetworkManagerwithnmcli(available on all RHEL-family and most Debian-family systems)
- Basic familiarity with: the Linux terminal, reading IP addresses, and knowing what a network interface is
- Network interface name: run
ip link showto confirm your interface name (could beeth0,ens33,enp3s0, etc.)
Step 1: Understand What IPv4 Subnetting Actually Does
Before touching any command, you need to know what problem subnetting solves. Without this context, you will copy-paste commands that work in the lab and break things in production.
What Is a Subnet?
A subnet (short for subnetwork) is a logically divided segment of a larger IP network. When you subnet a network, you split one big address block into smaller, isolated pieces. Each piece has its own range of usable IPs, a network address, and a broadcast address.
Why does this matter on Linux specifically? When you assign an IP address to a Linux network interface, the kernel uses the subnet mask you provide to decide two things:
- Which destination IPs are on the local network (reachable directly)
- Which destination IPs must go through a gateway (routed traffic)
Get the subnet wrong, and traffic that should stay local gets routed out. Traffic that should be routed gets dropped. Security boundaries you thought you configured do not actually exist.
The Three Private IPv4 Ranges Every Sysadmin Must Know
These are the ranges defined in RFC 1918 that you use in private networks:
| Range | CIDR Block | Total Addresses |
|---|---|---|
| Class A private | 10.0.0.0/8 |
16,777,216 |
| Class B private | 172.16.0.0/12 |
1,048,576 |
| Class C private | 192.168.0.0/16 |
65,536 |
You will work within these ranges for almost every Linux server subnet on internal infrastructure.
CIDR Notation vs. Dotted-Decimal Subnet Mask
Linux tools use CIDR notation (e.g., /24) instead of the old dotted-decimal format (e.g., 255.255.255.0). CIDR counts the number of consecutive 1 bits in the subnet mask binary representation. A /24 means the first 24 bits define the network, leaving 8 bits for host addresses.
Here is a quick reference you will use constantly:
| CIDR | Subnet Mask | Usable Hosts | Common Use |
|---|---|---|---|
| /30 | 255.255.255.252 | 2 | Point-to-point links |
| /29 | 255.255.255.248 | 6 | Small VLANs, management |
| /28 | 255.255.255.240 | 14 | Small server clusters |
| /27 | 255.255.255.224 | 30 | Department segments |
| /26 | 255.255.255.192 | 62 | Medium server groups |
| /24 | 255.255.255.0 | 254 | Standard LAN segment |
| /22 | 255.255.252.0 | 1,022 | Large campus networks |
Step 2: Install and Use ipcalc to Plan Your Subnets on Linux
Never configure a subnet on a production Linux server without calculating it first. ipcalc is the command-line tool that does the math for you and eliminates calculation mistakes before they reach your network.
Install ipcalc
On Debian/Ubuntu:
sudo apt update && sudo apt install ipcalc -y
On RHEL/Fedora/AlmaLinux:
sudo dnf install ipcalc -y
Why install this before anything else: ipcalc prevents you from assigning a broadcast address as a host IP or creating overlapping subnets, both of which cause silent networking failures that are painful to debug at 2 AM.
Calculate a Basic Subnet
Run ipcalc against an IP address and CIDR prefix:
ipcalc 192.168.10.0/24
Expected output:
Address: 192.168.10.0 11000000.10101000.00001010. 00000000
Netmask: 255.255.255.0 = 24 11111111.11111111.11111111. 00000000
Wildcard: 0.0.0.255 00000000.00000000.00000000. 11111111
=>
Network: 192.168.10.0/24 11000000.10101000.00001010. 00000000
HostMin: 192.168.10.1 11000000.10101000.00001010. 00000001
HostMax: 192.168.10.254 11000000.10101000.00001010. 11111110
Broadcast: 192.168.10.255 11000000.10101000.00001010. 11111111
Hosts/Net: 254 Class C, Private Internet
Read the output carefully:
- Network:
192.168.10.0is the network address; never assign this to any interface - HostMin/HostMax: the valid assignable IP range for your interfaces
- Broadcast:
192.168.10.255is reserved for broadcast; assigning this to a host breaks ARP responses for the entire subnet - Hosts/Net: tells you the maximum number of devices this subnet can support
Split a Network into Multiple Subnets
Suppose you manage a /24 and need to split it into segments of at least 15 hosts each:
ipcalc 172.16.1.0/24 -s 15 15
Expected output (trimmed):
Network: 172.16.1.0/24
...
1. Requested size: 15 hosts
Netmask: 255.255.255.224 = 27
Network: 172.16.1.0/27
HostMin: 172.16.1.1
HostMax: 172.16.1.30
Broadcast: 172.16.1.31
Hosts/Net: 30
2. Requested size: 15 hosts
Network: 172.16.1.32/27
HostMin: 172.16.1.33
HostMax: 172.16.1.62
Broadcast: 172.16.1.63
Hosts/Net: 30
Unused:
172.16.1.64/26
172.16.1.128/25
The Unused section at the bottom shows remaining address space. This is critical for growth planning. You know exactly how much room you have before you need to expand the base network.
Step 3: Check Your Current Linux Network and Subnet Configuration
Before you change anything, always audit the existing state. Knowing what is already configured prevents you from breaking something that works.
View All IP Addresses and Subnet Masks
ip addr show
Or limit output to a specific interface and IPv4 only:
ip -4 addr show eth0
Expected output:
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
inet 192.168.1.50/24 brd 192.168.1.255 scope global dynamic eth0
valid_lft 85873sec preferred_lft 85873sec
The inet line gives you the assigned IP (192.168.1.50), the CIDR prefix (/24), and the broadcast address (brd 192.168.1.255).
Why use ip addr and not ifconfig: ifconfig is part of the deprecated net-tools package. Modern Linux kernels expose network namespace and policy routing features that only ip from the iproute2 package can display correctly. Running ifconfig on a server with multiple routing tables gives you an incomplete picture.
View the Routing Table
ip route show
Expected output:
default via 192.168.1.1 dev eth0 proto dhcp src 192.168.1.50 metric 100
192.168.1.0/24 dev eth0 proto kernel scope link src 192.168.1.50
The default route is where traffic goes when no specific route matches. The second line is the connected route that the kernel adds automatically when you assign an IP to an interface. This connected route is what makes local subnet communication work without any manual routing rules.
Step 4: Configure IPv4 Subnetting on Linux with the ip Command
The ip command from iproute2 is how you apply subnet configuration at the kernel level. Changes made with ip are immediate but temporary; they do not survive a reboot. This makes it perfect for testing subnet changes before making them permanent.
Assign an IP Address with a Specific Subnet
sudo ip addr add 192.168.10.1/26 dev eth0
Why /26 and not /24 in this example: a /26 gives you exactly 62 usable host addresses (192.168.10.1 through 192.168.10.62). If you are setting up an isolated segment for a server group, using a /26 instead of /24 means devices outside that /26 range cannot accidentally be on the same local segment. This enforces a network boundary without any firewall rule.
Verify the assignment worked:
ip -4 addr show eth0
You should see both the original IP and the new one listed under the same interface.
Add a Secondary IP on a Different Subnet
Linux interfaces support multiple IP addresses. You can assign a second IP on a completely different subnet to the same physical interface:
sudo ip addr add 10.10.1.1/27 dev eth0
Why this is useful: in a VLSM setup (Variable Length Subnet Masking), a Linux router often needs a gateway IP in each subnet it connects. One physical interface can serve multiple logical subnet segments through secondary IP assignment.
Add a Static Route Between Two Subnets
Just assigning IPs is not enough when you need traffic to flow between two different subnets. You need an explicit route:
sudo ip route add 192.168.20.0/24 via 192.168.10.1
Why add this manually: the Linux kernel only installs connected routes automatically (the subnets directly assigned to interfaces). For any other network segment, you must tell the kernel which gateway to send traffic through. Without this route, packets destined for 192.168.20.x go to the default gateway, which may drop them entirely.
Verify the route was added:
ip route show
You should see 192.168.20.0/24 via 192.168.10.1 in the output.
Remove an IP Address
sudo ip addr del 192.168.10.1/26 dev eth0
Always specify the full CIDR prefix when deleting. Without the prefix, the command fails if multiple IPs exist on the interface.
Step 5: Make Subnet Configuration Persistent with nmcli
This is the step that most tutorials bury or skip. Runtime ip commands vanish on reboot. For a production Linux server, you must write the configuration through NetworkManager using nmcli.
List Existing Connection Profiles
nmcli con show
Expected output:
NAME UUID TYPE DEVICE
eth0 a1b2c3d4-e5f6-7890-abcd-ef1234567890 ethernet eth0
The NAME column is what you use in subsequent nmcli commands.
Configure a Static IP, Gateway, and Subnet
sudo nmcli con mod eth0 ipv4.addresses 192.168.10.1/26
sudo nmcli con mod eth0 ipv4.gateway 192.168.10.254
sudo nmcli con mod eth0 ipv4.dns "8.8.8.8,1.1.1.1"
sudo nmcli con mod eth0 ipv4.method manual
Why ipv4.method manual is required: if you skip this step, NetworkManager keeps DHCP active and overwrites your static IP on the next DHCP lease renewal or reboot. Setting manual tells NetworkManager to stop asking the DHCP server and use only what you defined.
Apply the Changes
sudo nmcli con up eth0
Why use nmcli con up instead of just restarting the interface: this command tells NetworkManager to re-read the saved profile and apply it to the live interface atomically. A plain ip link set eth0 down && ip link set eth0 up does not reload the nmcli profile.
Verify the Persistent Configuration
Run both commands to confirm what is configured and what is active:
nmcli con show eth0 | grep ipv4
ip addr show eth0
If both commands agree on the IP and subnet, your configuration is correct and will survive reboots.
Step 6: Real-World VLSM Example: Subnet a Company Network on Linux
VLSM (Variable Length Subnet Masking) is how you allocate IP space efficiently when different departments or services need different numbers of hosts. Here is a real scenario encountered multiple times when managing production infrastructure.
The Scenario
You have the block 10.10.0.0/22 (1,022 usable hosts). You need three segments:
- Engineering: 200 hosts
- Operations: 50 hosts
- Management: 10 hosts
VLSM Calculation
Always allocate from largest to smallest. This prevents fragmentation.
Engineering (200 hosts needed):
ipcalc 10.10.0.0/24
# /24 gives 254 usable hosts. Assigned: 10.10.0.0/24
# Gateway: 10.10.0.1
Operations (50 hosts needed):
ipcalc 10.10.1.0/26
# /26 gives 62 usable hosts. Assigned: 10.10.1.0/26
# Gateway: 10.10.1.1
Management (10 hosts needed):
ipcalc 10.10.1.64/28
# /28 gives 14 usable hosts. Assigned: 10.10.1.64/28
# Gateway: 10.10.1.65
None of these ranges overlap. The subnets sit cleanly inside the parent 10.10.0.0/22 block.
Apply the VLSM Subnets to a Linux Router
If a Linux machine acts as the router between these segments, assign a gateway IP on each interface:
sudo ip addr add 10.10.0.1/24 dev eth0
sudo ip addr add 10.10.1.1/26 dev eth1
sudo ip addr add 10.10.1.65/28 dev eth2
Confirm the routing table now shows connected routes for all three:
ip route show
Expected output includes:
10.10.0.0/24 dev eth0 proto kernel scope link src 10.10.0.1
10.10.1.0/26 dev eth1 proto kernel scope link src 10.10.1.1
10.10.1.64/28 dev eth2 proto kernel scope link src 10.10.1.65
Each subnet now has a connected route. Hosts on each segment can reach their gateway, and the Linux router can forward between them without needing a separate routing daemon for simple setups like this.
Troubleshooting Common IPv4 Subnetting Errors on Linux
Even experienced sysadmins run into these. Here are the five issues that come up most often in the field, along with the exact fix for each.
Error 1: RTNETLINK answers: File exists
Cause: You are trying to add a route that already exists in the routing table, or the subnet you are adding overlaps with an existing one.
Fix:
ip route show
# Identify the conflicting route, then:
sudo ip route del 192.168.20.0/24
sudo ip route add 192.168.20.0/24 via 192.168.10.1
Alternatively, use replace to avoid the two-step:
sudo ip route replace 192.168.20.0/24 via 192.168.10.1
Error 2: Host Is Unreachable Even Though Both Are in the Same Network
Cause: The prefix length assigned to one of the hosts is wrong. For example, one host has 192.168.10.50/24 but the interface it should reach has 192.168.10.50/28. From the /28 host’s perspective, anything above 192.168.10.62 is off-subnet and gets routed to the gateway instead of resolved locally.
Fix:
ip -4 addr show
# Compare prefix lengths on both machines
# Correct the mismatched one:
sudo ip addr del 192.168.10.50/28 dev eth0
sudo ip addr add 192.168.10.50/24 dev eth0
Error 3: Subnet Configuration Disappeared After Reboot
Cause: You used ip addr add without saving through nmcli or a network config file. Runtime kernel state does not persist.
Fix: Reconfigure using nmcli as shown in Step 5. For Ubuntu systems using Netplan, write your subnet to /etc/netplan/01-netcfg.yaml:
network:
version: 2
ethernets:
eth0:
addresses:
- 192.168.10.1/26
gateway4: 192.168.10.254
nameservers:
addresses: [8.8.8.8, 1.1.1.1]
Then apply:
sudo netplan apply
Error 4: nmcli con mod Applied But IP Did Not Change
Cause: You modified the profile but never brought the connection back up. nmcli con mod writes to disk; nmcli con up applies it.
Fix:
sudo nmcli con up eth0
If the interface is active and shows the old IP, force a full reconnect:
sudo nmcli con down eth0 && sudo nmcli con up eth0
Error 5: ipcalc Gives Different Output Than Expected on RHEL
Cause: RHEL ships a different version of ipcalc from the initscripts package that uses different syntax flags compared to the Debian/standalone version.
Fix: On RHEL 8+, use ipcalc from the ipcalc package (not initscripts) for full CIDR splitting support:
sudo dnf install ipcalc -y
ipcalc --version
Confirm the version is ipcalc 1.0.0 or higher for CIDR subnet splitting with the -s flag.
IPv4 Subnetting on Linux: Best Practices Before You Go Live
You can subnet correctly in a lab and still cause outages in production if you skip these steps:
- Document every subnet assignment in an IPAM spreadsheet or tool before applying any
nmclichange to a running server - Use
/30for point-to-point links between routers or VMs; it wastes only 2 addresses but keeps your address space clean - Isolate management interfaces on a dedicated
/28or/29subnet, separate from application traffic; this limits lateral movement in a breach scenario - Always run
ipcalcbefore configuring, even for subnets you think you know by heart; a single off-by-one bit error in a prefix causes hours of debugging - Verify with two commands after every change:
nmcli con show [interface] | grep ipv4(what is saved) andip addr show [interface](what is running); a mismatch means the configuration did not apply cleanly - Test subnet changes in a VM or staging environment before touching production interfaces, especially when modifying the interface you use for SSH access (you can lock yourself out)