Short answer: a private IP address only works inside a local network and is never routed on the internet: anything in 10.0.0.0/8, 172.16.0.0/12 or 192.168.0.0/16 (RFC 1918). A public IP address is globally unique and reachable from the internet. Your router translates between the two with NAT, which is why every device at home shares one public address.
ip -4 -br addr # Linux: the private (or local) address of each interface
ipconfig # Windows: "IPv4 Address" under your adapter
curl -4 ifconfig.me # Linux, macOS (Windows: curl.exe -4 ifconfig.me): the public address the internet seesIf the first two show an address from the ranges above and the third shows something else, you are behind NAT. If all of them show the same address, the machine has its public IP directly on its network interface, which is the normal case for a server. The what is my IP tool does the outside check in a browser.
Public vs private IP at a glance
| Public IP | Private IP | |
|---|---|---|
| Reachable from the internet | Yes, unless a firewall blocks it | No: routers on the internet drop these destinations |
| Unique | Globally: one holder per address | Only inside its own network; millions of homes use 192.168.1.10 |
| Who assigns it | Your ISP or hosting provider, from blocks allocated by a regional internet registry | Your router (DHCP) or you, by hand |
| Cost | Scarce for IPv4, so it is often part of the price | Free: use as many as you like |
| Typical holder | A home router's WAN side, a server, a VPS | Laptops, phones, printers, containers, VPN tunnels |
| Reaches the internet | Directly | Through NAT on a router or gateway |
| Can host a public server | Yes | Only through port forwarding, a tunnel or a proxy |
Private IP address ranges (and the other special ones)
RFC 1918 reserves three blocks for private networks. Anyone may use them without asking, and because nobody owns them, internet routers do not carry them. The full list of special-purpose blocks is the IANA IPv4 Special-Purpose Address Registry (RFC 6890); these are the ones you actually meet:
| Range | CIDR | Addresses | Used for | Defined in |
|---|---|---|---|---|
| 10.0.0.0 to 10.255.255.255 | 10.0.0.0/8 | 16,777,216 | Large private networks, cloud and VPN subnets, Kubernetes pods | RFC 1918 |
| 172.16.0.0 to 172.31.255.255 | 172.16.0.0/12 | 1,048,576 | Private networks; Docker's default bridge uses 172.17.0.0/16 | RFC 1918 |
| 192.168.0.0 to 192.168.255.255 | 192.168.0.0/16 | 65,536 | Home and office routers (192.168.0.x, 192.168.1.x) | RFC 1918 |
| 100.64.0.0 to 100.127.255.255 | 100.64.0.0/10 | 4,194,304 | Carrier-grade NAT between an ISP and its customers | RFC 6598 |
| 127.0.0.0 to 127.255.255.255 | 127.0.0.0/8 | 16,777,216 | Loopback: 127.0.0.1 is the machine itself | RFC 1122 |
| 169.254.0.0 to 169.254.255.255 | 169.254.0.0/16 | 65,536 | Link-local: self-assigned when DHCP fails (Windows calls it APIPA) | RFC 3927 |
| 192.0.2.0/24, 198.51.100.0/24, 203.0.113.0/24 | three /24s | 768 | Documentation and examples only, like the addresses on this page | RFC 5737 |
Two mistakes come up again and again. First, 172.16.0.0/12 ends at 172.31.255.255: 172.32.0.1 and 172.15.0.1 are ordinary public addresses. Second, 100.64.0.0/10 is not RFC 1918 space. It is shared address space for ISPs, so a router that shows a WAN address like 100.72.14.9 is itself behind your provider’s NAT. The subnet mask cheat sheet explains how a prefix such as /12 turns into these start and end addresses, and the subnet calculator works them out for any block.
Private addresses in IPv6
IPv6 has enough addresses that every device can have a public one, so it needs no NAT. A typical interface carries several addresses at once, and only one kind is public:
| Prefix | Name | Scope |
|---|---|---|
2000::/3 | Global unicast | Public: routed on the internet (addresses starting with 2 or 3) |
fc00::/7 | Unique local address (ULA), RFC 4193 | Private; in practice fd00::/8, the IPv6 counterpart of 10.0.0.0/8 |
fe80::/10 | Link-local, RFC 4291 | Only the local link; every IPv6 interface has one |
::1/128 | Loopback | The machine itself, like 127.0.0.1 |
2001:db8::/32 | Documentation, RFC 3849 | Examples only, never routed |
So when ip -6 addr shows only fe80:: addresses (plus ::1 on the loopback), the machine has no public IPv6 at all. The IPv4 vs IPv6 comparison covers notation, prefixes and why IPv6 drops NAT.
How NAT connects private addresses to the internet
Network address translation is what lets a whole household share one public IPv4 address. When your laptop at 192.168.1.23 opens a connection to a website, the router rewrites the packet’s source address to its own public address, picks a free source port, and remembers the pair in a translation table:
inside (private) outside (public) remote server
192.168.1.23:51544 -> 198.51.100.7:40312 -> 203.0.113.80:443
192.168.1.40:60210 -> 198.51.100.7:40313 -> 203.0.113.80:443The website only ever sees 198.51.100.7. When its reply arrives on port 40312, the router looks up the table and forwards it to the laptop. A connection that starts outside has no entry in the table, so the router has nowhere to send it and drops it. That is the whole reason a game server, a camera or a website at home is unreachable until you configure something.
- Port forwarding is a static entry you add by hand: “anything arriving on public port 25565 goes to 192.168.1.40”. It only works if the router’s WAN side really has a public address.
- Carrier-grade NAT (CGNAT) is the same trick one level up: your ISP gives your router an address from
100.64.0.0/10and shares one public address among many customers. You cannot forward ports on the provider’s NAT, so incoming IPv4 connections never reach you. - Double NAT happens when two routers sit in a row (an ISP modem in router mode plus your own router). Forwarding then has to be set up on both, or the first one switched to bridge mode.
- NAT is not a firewall. It blocks unsolicited inbound traffic as a side effect, but anything you forward is exposed, and IPv6 devices behind the same router may be reachable directly. Firewall rules are what actually decide.
Am I behind CGNAT?
Compare two numbers: the WAN or internet address on your router’s status page, and the address an outside service reports (curl -4 ifconfig.me). If they match, your router holds a public IPv4 and port forwarding can work. If the router shows an address from 100.64.0.0/10 or any RFC 1918 range, or simply a different address, there is another NAT in front of it. Some ISPs give you a public IPv4 on request, often for a fee; otherwise the workarounds are below.
How to find your private and public IP
| System | Private / local address | Public address |
|---|---|---|
| Linux | ip -4 -br addr | curl -4 ifconfig.me |
| Windows | ipconfig or Get-NetIPAddress -AddressFamily IPv4 | curl.exe -4 ifconfig.me |
| macOS | ipconfig getifaddr en0 | curl -4 ifconfig.me |
| Phone | Wi-Fi settings, details of the connected network | A what-is-my-IP page in the browser |
On Linux, checking the IP address goes into ip addr, hostname -I and finding the interface your traffic really leaves through. On Windows, ipconfig prints a block per adapter; the private address is the IPv4 Address line, and the router is the Default Gateway:
Ethernet adapter Ethernet:
IPv4 Address. . . . . . . . . . . : 192.168.1.23
Subnet Mask . . . . . . . . . . . : 255.255.255.0
Default Gateway . . . . . . . . . : 192.168.1.1Checking an address in a script
Python’s standard ipaddress module classifies addresses for you, and it shows the CGNAT trap clearly: 100.64.0.1 is neither private nor global. Run on Debian 12 with Python 3.11.2 on 21 October 2026:
$ python3 -c "
import ipaddress
for a in ['192.168.1.10','172.20.0.5','172.32.0.1','100.64.0.1',
'169.254.169.254','8.8.8.8','fd12:3456:789a::1','2001:4860:4860::8888']:
ip = ipaddress.ip_address(a)
print(f'{a:22} is_private={ip.is_private!s:5} is_global={ip.is_global}')
"
192.168.1.10 is_private=True is_global=False
172.20.0.5 is_private=True is_global=False
172.32.0.1 is_private=False is_global=True
100.64.0.1 is_private=False is_global=False
169.254.169.254 is_private=True is_global=False
8.8.8.8 is_private=False is_global=True
fd12:3456:789a::1 is_private=True is_global=False
2001:4860:4860::8888 is_private=False is_global=TrueTest is_global when the question is “can the internet reach this?”, not is_private: in Python’s definition, loopback, link-local and the documentation ranges count as private too. Later Python releases have refined these lists for a few rare ranges, so check edge cases on the version you run.
Why a server needs a public IP
A server waits for other people to connect, and NAT drops exactly those connections. So anything the public should reach needs a public address somewhere in front of it:
- DNS points at it. The A record of your domain must hold the public address. A private one such as
10.0.0.5in a public A record works only for visitors inside that network, which is a classic way to build a site that loads for you and nobody else. Pointing a domain at a VPS walks through the records. - Certificates and mail need it. Let’s Encrypt’s HTTP check connects to your public address on port 80, and receiving mail servers check the reverse DNS of the public IP your mail leaves from.
- It should not change. Home connections usually get a dynamic address that changes on reconnect; a server needs a static IP address so DNS stays right.
Servers still use private addresses all the time, just not for the public side: a database that listens on 127.0.0.1 only, containers on Docker’s 172.17.0.0/16 bridge, a WireGuard tunnel on 10.8.0.0/24, or a Tailscale network, which numbers its devices out of 100.64.0.0/10. Binding an admin panel or a database to a private address is the simplest way to keep it off the internet while the web server answers on the public one.
Port forwarding at home vs a server with its own IP
| Home connection with port forwarding | VPS or dedicated server | |
|---|---|---|
| Public IPv4 | Only if the ISP gives you one (no CGNAT) | On the server itself |
| Address changes | Often, unless you pay for a static one | Stays the same for the life of the server |
| Inbound ports | Some ISPs block incoming web ports such as 80 on home lines | You open what you need in the server's own firewall |
| Upload speed | Usually a fraction of the download speed | A data centre uplink, built for serving traffic |
| Exposure | Your home network sits behind the same address | Separate from your home and your devices |
| Uptime | Depends on your power, router and line | Data centre power and network |
Behind CGNAT there is a middle way: rent a small server with a public address and connect your home machine to it through a tunnel. With a WireGuard server on a VPS and the home machine as a client, one forwarding (DNAT) rule on the VPS passes a port on its public IP through the tunnel, and Headscale gives you a private mesh across all your devices without forwarding anything.
Public addresses on a VMHeaven server
Every VMHeaven VPS in Amsterdam or Frankfurt gets its own public IPv4 address, plus an IPv6 prefix when the location’s pool has one free. The address sits on the server’s own network interface, so ip a on a Linux VPS shows the same address the rest of the internet connects to, and nothing has to be forwarded.
Frequently asked
What are the private IP address ranges?
RFC 1918 reserves three blocks: 10.0.0.0 to 10.255.255.255 (10.0.0.0/8), 172.16.0.0 to 172.31.255.255 (172.16.0.0/12) and 192.168.0.0 to 192.168.255.255 (192.168.0.0/16). They are not routed on the internet. 100.64.0.0/10 is a separate block for carrier-grade NAT, and IPv6 uses fc00::/7, in practice fd00::/8, for private networks.
Is 172.32.0.1 a private IP address?
No. The private block 172.16.0.0/12 runs from 172.16.0.0 to 172.31.255.255 only, so addresses starting with 172.32 or 172.15 are ordinary public addresses.
How do I find my public IP address?
Ask a server outside your network: run curl -4 ifconfig.me on Linux or macOS, curl.exe -4 ifconfig.me on Windows, or open a what-is-my-IP page in the browser. ip addr and ipconfig only show the address of your own network interface, which is a private one when you are behind a router.
Can I host a server on a private IP address?
Only for devices on the same network. To reach it from the internet you need port forwarding on a router that has a public IPv4 address (not one behind carrier-grade NAT), a tunnel to a machine with a public address, or a server such as a VPS that has its own public IP.