Host networking: ip, ss, routes
How to inspect a server's network setup: interfaces and addresses via ip, open ports via ss, and the routing table.
How to look at a server's network configuration: interfaces and addresses through ip, open
ports through ss, the routing table through ip route.
Why this matters
In the networking track, we covered IP, ports and routing as concepts. Now let's look at them on an actual server: what interfaces and addresses it has, which ports it's listening on, where its packets go. This is the first thing you check when a service is unreachable or won't talk to the outside.
The old commands (ifconfig, netstat, route) from the net-tools package aren't installed by
default on many distributions anymore. They've been replaced by ip and ss from the iproute2
package.
Concepts
Network interface — the point through which a host sends and receives packets. It can be
physical (a network card, named something like eth0 or enp3s0) or virtual (lo, container
interfaces).
Socket — the endpoint of a network connection inside a process. When a program is "listening
on a port," the kernel keeps a listening socket for it with an address and a port, for example
0.0.0.0:80.
Route — a rule: "send packets for this network through this interface, and through this gateway if needed." Gateway — a neighboring host that forwards packets onward, into networks our host can't reach directly.
ip: interfaces and addresses
ip addr (shorthand ip a) shows network interfaces and their addresses:
ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
link/ether 52:54:00:12:34:56 brd ff:ff:ff:ff:ff:ff
inet 10.0.5.14/24 brd 10.0.5.255 scope global eth0
valid_lft forever preferred_lft forever
lo is the loopback interface (127.0.0.1), eth0 is the main interface with the address
10.0.5.14/24. The /24 notation is the subnet mask from the IP and ports lesson: an address
plus a network size. Here the network is 10.0.5.0/24, with addresses from 10.0.5.1 to
10.0.5.254.
Status shows up in two places. The UP flag in angle brackets means the interface was enabled by
an administrator; LOWER_UP means there's a link at the physical layer (a cable is plugged in, a
virtual pair is connected). The word after state gives the summary: UP means it's working,
DOWN means it isn't. For lo it's usually UNKNOWN, and that's normal. If an interface is
DOWN or has no inet line with an address, networking on that host won't work, and that's the
first thing to check.
When there are many interfaces, the short view is more convenient: one line per interface.
ip -br addr
lo UNKNOWN 127.0.0.1/8
eth0 UP 10.0.5.14/24
ss: who's listening on ports
ss shows sockets: which ports the server is listening on and which connections are open. A
common call for checking listening TCP ports:
sudo ss -ltnp
State Recv-Q Send-Q Local Address:Port Peer Address:Port Process
LISTEN 0 511 0.0.0.0:80 0.0.0.0:* users:(("nginx",pid=812,fd=6))
LISTEN 0 200 127.0.0.1:5432 0.0.0.0:* users:(("postgres",pid=640,fd=7))
Flags: -l listening sockets, -t TCP, -n don't resolve addresses and ports into names (faster
and clearer), -p show the process. Without sudo, the Process column is empty for other
users' processes: the kernel doesn't reveal them to a regular user.
The key column here is Local Address:Port. nginx is listening on 0.0.0.0:80, meaning port 80
on all of the host's IPv4 addresses, and it's reachable over the network (unless a firewall gets
in the way). postgres is listening on 127.0.0.1:5432, loopback only: you can connect only from
this same host. [::]:80 or *:80 means the same as 0.0.0.0, but including IPv6.
If "the port isn't responding," the first thing to check is whether anyone is listening on it at
all, and on which address. No line with the port you need means the process isn't running or has
crashed. If the line is there but the address is 127.0.0.1, the service is invisible from the
outside no matter how much you open up the firewall.
ss -tn without -l shows already-established TCP connections: who's connected to whom right
now.
Routes: where packets go
ip route shows the host's routing table: where to send packets for different addresses.
ip route
default via 10.0.5.1 dev eth0 proto dhcp src 10.0.5.14 metric 100
10.0.5.0/24 dev eth0 proto kernel scope link src 10.0.5.14
default via 10.0.5.1 is the default gateway: anything without a more specific route goes there.
The 10.0.5.0/24 dev eth0 line means the host reaches that subnet directly through eth0, with
no gateway. The kernel adds it automatically when an address is assigned to the interface
(proto kernel).
The kernel picks the most specific route that matches the destination address. Both lines match
10.0.5.20, but /24 is more specific than default, so the packet goes directly. Only
default matches 8.8.8.8. You can check the kernel's choice for a specific address like this:
ip route get 8.8.8.8
8.8.8.8 via 10.0.5.1 dev eth0 src 10.0.5.14 uid 1000
cache
No default route, and the server won't reach the internet even though everything works locally. The opposite happens too: there's a default route, but the internal network you need sits behind a different gateway. Then you add a route specifically for it:
sudo ip route add 192.168.50.0/24 via 10.0.5.254
The gateway in via must be in a network the host reaches directly (here, 10.0.5.0/24),
otherwise the kernel responds with Nexthop has invalid gateway (Network unreachable on
busybox). A route added this way lives until the next reboot. Making it permanent means writing
it into the distribution's network configuration (netplan, NetworkManager, systemd-networkd),
which is a separate topic.
Common mistakes
- The service listens on
127.0.0.1, but requests come from outside. Especially common in containers: the port is published withdocker run -p, but the app inside is listening on the container's loopback, andcurlgetsEmpty reply from serverorConnection reset by peer. You can see it withss -ltninside the container. ss -pwithoutsudo. The process column is empty, and it looks like nothing is holding the port. Something is holding it, you just weren't shown who.- Checking only
ping.pingtests address reachability over ICMP, not a port. A host can respond topingwhile the service on it isn't listening, and the other way around: firewalls often block ICMP. - Confusing "no route" with "no answer".
Network unreachableis printed by the kernel itself: no route matched the address. A timeout means the packet went out but got no answer: the gateway didn't forward it, a firewall dropped it, or the reply went somewhere else. - Docker's built-in DNS showing up in
ss. In containers on user-defined Docker networks,ss -ltnshows an extra line like127.0.0.11:37999. That's Docker's resolver, it has nothing to do with your service. - Looking for
ipandsson macOS. They're not there: macOS has its ownifconfig,netstatandroute. All the tasks in this lesson run inside Linux containers, so the commands are the same on macOS and in WSL2.
What you'll need for the tasks
Both labs run in containers on the alpine:3.20.3 image with the iproute2-ss package, so they
work the same way on Linux, macOS and in WSL2. Commands run inside the container through
docker exec:
docker exec <container> ss -ltnp— who's listening on which TCP ports and on what address;docker exec <container> ip addr— interfaces and addresses with masks;docker exec <container> ip routeandip route get <address>— routes and the kernel's choice;docker exec <container> ip route add <network> via <gateway>— add a route (in the lab, the container has permission to change its own network, nosudoneeded);docker exec <container> cat <file>anddocker restart <container>— check the service's settings and restart it;- the sections "ss: who's listening on ports" and "Routes: where packets go".
Inside the containers, ip comes from busybox; its output is a bit shorter than iproute2's on a
real server (no group default, proto kernel), but the lines mean the same thing.
What to remember
ip addr shows interfaces, addresses with their mask and status; ss -ltnp shows listening ports
with the address and process; ip route shows routes and the default gateway.
When a service is unreachable, check in order: is the interface up and does it have an address,
is anyone listening on the port and on what address (127.0.0.1 versus 0.0.0.0), is there a
route to the destination.
The next lesson covers regular expressions for pattern search and replace.
Done reading?
Mark the lesson as read to move your track progress forward.
Lesson marked as done.
Go through it with an AI agent
The agent explains anything unclear in plain words, gives you 2 labs for this lesson and drills you on interview questions. $49 one-time, lifetime access.
Tell the agent: use MCP izi, give me lesson linux-tools-02-networking-host
Progress saved in this browser
Clear your history or open this on your phone, and the marks will be gone. Leave your email and they'll move to your account. No password needed.
Done. moved to your account. You can see your progress on any device. My progress