IP Addresses & Subnets
Every device on a network needs a unique address so that data knows where to go, just like every house on a street needs a postal address. That address is the IP address (IP stands for Internet Protocol, the set of rules computers use to send data to each other). As a DevOps engineer you will read, type, and reason about IP addresses every single day, so getting comfortable with how they are built and how subnets carve them up is one of the highest-value things you can learn early.
What an IPv4 address looks like
An IPv4 address (version 4 of the Internet Protocol, the most common kind) is written as four numbers separated by dots, like 192.168.1.10. Each of those four numbers is called an octet because, under the hood, it is 8 binary bits. Eight bits can hold a value from 0 to 255, so each octet is always somewhere between 0 and 255.
Four octets of 8 bits each gives you 32 bits total. That means there are only about 4.3 billion possible IPv4 addresses in the whole world. That sounds like a lot, but we ran out years ago, which is one reason private addresses and IPv6 (covered below) exist.
An IP address actually carries two pieces of information at once:
- The network part — which network the device belongs to (the “street”).
- The host part — which specific device it is on that network (the “house number”).
The subnet mask, explained later, is what decides where the network part ends and the host part begins.
Public vs private IP addresses
Not all IP addresses are equal. Some are public (reachable from anywhere on the internet) and some are private (only usable inside a local network, like your home, office, or a cloud Virtual Private Cloud).
Private addresses were deliberately set aside in three ranges. Any address inside these ranges is private and will never appear directly on the public internet:
| Range | CIDR | Common use |
|---|---|---|
10.0.0.0 – 10.255.255.255 | 10.0.0.0/8 | Large networks, cloud VPCs (AWS, GCP) |
172.16.0.0 – 172.31.255.255 | 172.16.0.0/12 | Mid-size networks, Docker default bridge |
192.168.0.0 – 192.168.255.255 | 192.168.0.0/16 | Home and small-office routers |
When a device with a private IP needs to reach the internet, a router translates its private address into a shared public one. That trick is called NAT (Network Address Translation), and it has its own page in this section.
Never expose a service that you think is “internal” without checking its bind address. A database listening on
0.0.0.0(all interfaces) instead of127.0.0.1(localhost only) can be reachable from outside even if you assumed it was private. Always confirm withss -tlnp.
When to use which: use private ranges for everything that talks only inside your own network — app servers talking to databases, containers talking to each other. Reserve public IPs for the few things that genuinely must be reachable from the internet, such as a web server or a load balancer.
CIDR notation and subnets
CIDR (Classless Inter-Domain Routing, pronounced “cider”) is the modern way to describe a block of IP addresses. It looks like 192.168.1.0/24. The number after the slash, the prefix length, tells you how many of the 32 bits belong to the network part. The remaining bits are free for hosts.
Here is the gentle math. The slash number is how many bits are “locked” as network. Whatever is left over is for hosts, and the number of host addresses is 2^(32 - prefix).
Take /24 as the everyday example:
/24means 24 network bits, leaving32 - 24 = 8host bits.2^8 = 256total addresses, from.0to.255.- Two of those are reserved:
.0is the network address itself and.255is the broadcast address (used to talk to every host at once). So you get 254 usable addresses.
A quick reference table for the most common subnet sizes:
| CIDR | Subnet mask | Total addresses | Usable hosts |
|---|---|---|---|
/24 | 255.255.255.0 | 256 | 254 |
/25 | 255.255.255.128 | 128 | 126 |
/26 | 255.255.255.192 | 64 | 62 |
/30 | 255.255.255.252 | 4 | 2 |
The bigger the slash number, the smaller the network. A /30 is handy for a point-to-point link between two routers because it gives you exactly two usable addresses and wastes nothing.
When to use this: you will choose CIDR ranges when you create a cloud network. A common, sane starting point is a /16 for the whole VPC and /24 blocks for each subnet inside it, which leaves plenty of room to grow.
IPv6 in brief
Because IPv4 ran out of addresses, IPv6 (version 6) was created. It uses 128 bits instead of 32, which gives an almost unimaginable number of addresses. They are written in hexadecimal (base-16) groups separated by colons, like 2001:0db8:85a3:0000:0000:8a2e:0370:7334. Long runs of zeros can be shortened with ::, so that same address can be written 2001:db8:85a3::8a2e:370:7334.
You do not need to master IPv6 to start with, but you should recognise it. Many cloud providers and modern networks now assign IPv6 addresses by default, and tools will happily show you both.
Finding your IP address on Ubuntu
On a fresh Ubuntu server (22.04 or 24.04 LTS), the modern command is ip addr. It lists every network interface and the addresses assigned to it.
ip addr show
Output:
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN
inet 127.0.0.1/8 scope host lo
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP
inet 10.0.1.42/24 brd 10.0.1.255 scope global dynamic eth0
inet6 2600:1f18:abcd::42/64 scope global dynamic
Reading this: lo is the loopback interface (the machine talking to itself) at 127.0.0.1. eth0 is the real network card with a private IPv4 of 10.0.1.42 in a /24 subnet, plus an IPv6 address. The brd line shows the broadcast address.
To see only your IPv4 addresses without the noise:
ip -4 addr show eth0
That command shows you the private address of the machine. To find the public address the internet sees (the one NAT translates you to), ask an outside service:
curl -s https://ifconfig.me
Output:
203.0.113.57
Best practices
- Always know whether an address is public or private before you open a firewall rule for it — getting this wrong is a top cause of accidental exposure.
- Plan CIDR ranges before building a network; resizing a subnet later usually means rebuilding it.
- Use
/24blocks as your default subnet size unless you have a specific reason to go smaller or larger — they are easy to read and leave room to grow. - Bind sensitive services to
127.0.0.1(localhost) by default and only expose them deliberately. - Prefer the
ipcommand (ip addr,ip route) over the old, deprecatedifconfig, which is not installed on modern Ubuntu by default. - Document your subnet layout so the next engineer knows which range does what.