What is it? #
An IP address identifies a machine on a network. A port identifies which program on that machine should receive the traffic.
Together they form an endpoint: 203.0.113.10:443 means "the program listening on port 443 of that machine".
Some address ranges are private — 10.x, 172.16–31.x and 192.168.x. They work only inside a local network and are not routable on the internet, which is why your laptop and your server can both be 192.168.1.5 without conflict.
IPv4 addresses ran out years ago, which is why NAT and IPv6 exist. Most systems now speak both.
Think of it like this #
An IP address is the street address of an office building. The port is the room number.
Post arriving at the building still needs a room to go to. Two different services can run at the same address as long as they occupy different rooms.
Simple example #
Your server has one public IP address. Nginx listens on ports 80 and 443, your application on 3000, PostgreSQL on 5432 and Redis on 6379. Only the first two should be reachable from the internet.
Code #
Address ranges
Public routable on the internet, e.g. 203.0.113.10
Private 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16 local networks only
Loopback 127.0.0.1 this machine only
IPv6 2001:db8::1 vastly larger space
Common ports
22 SSH 80 HTTP 443 HTTPS
3306 MySQL 5432 PostgreSQL 6379 Redis
27017 MongoDB 3000 common app dev port
# What addresses does this machine have?
ip addr show # Linux
ipconfig # Windows
# What is my public address, as the internet sees it?
curl -s https://api.ipify.org
# What is listening, and on which address?
sudo ss -tulpn
# Is a port reachable from here?
nc -zv example.com 443
# Which process is holding a port?
sudo lsof -i :3000
Binding address matters
0.0.0.0:3000 reachable from anywhere the firewall allows
127.0.0.1:3000 reachable only from this machine
10.0.0.5:3000 reachable only on the private network
Database services should bind to 127.0.0.1 or a private address,
never to 0.0.0.0 with no firewall.
How it works #
ss -tulpn lists listening sockets: the protocol, the local address and port, and the owning process. It is the fastest way to answer "what is running on this machine and who can reach it".
The binding address decides exposure before any firewall rule. A database bound to 127.0.0.1 cannot be reached from another machine at all, regardless of firewall configuration. That is the strongest and simplest protection.
Private addresses are not routable across the internet. Your home router has one public address and hands out private ones to every device, translating between them — that is NAT, network address translation.
NAT is why incoming connections to a device behind a router do not work without port forwarding: the router does not know which internal device the traffic is for.
IPv6 removes the shortage that made NAT necessary, giving every device a globally unique address. Most servers now have both an IPv4 and an IPv6 address, and DNS AAAA records point at the latter.
Ports below 1024 are privileged on Linux, which is why web servers start as root to bind port 80 and then drop to an unprivileged user.
Real-world use #
The practical security rule follows directly from all this: expose only what must be public. On a typical server that is ports 22, 80 and 443, with the database and cache bound to localhost.
Misconfigured databases exposed on public IPs with default credentials remain one of the most common causes of data breaches. Scanners find them within minutes of being exposed.
In cloud environments, private networking replaces this manual work. Services communicate over a private network, and only a load balancer has a public address.
When debugging connectivity, the order is always: does the name resolve, is the port open, is anything listening, and does the firewall allow it. Those four checks resolve most problems.
Common mistakes #
- Binding a database to 0.0.0.0 on a public server.
- Assuming a firewall protects a service that is also reachable another way.
- Confusing the private address of a cloud instance with its public one.
- Forgetting that changing an IP address requires a DNS update and a TTL wait.
- Running an application as root just to bind port 80, instead of using a reverse proxy.
Practice #
On any machine you control, list every listening socket with ss -tulpn and write down which are bound to localhost and which to all interfaces. For anything bound broadly, decide whether it should be, and note what you would change.