Sign in
← Linux: tools
12 min · medium · Lesson 2 of 4

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

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:

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.

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.

Get access for $49

Tell the agent: use MCP izi, give me lesson linux-tools-02-networking-host