Home

Linux network commands I actually reach for

When something's off with networking on a Linux box, you don't need to know fifty commands — you need to know the right four or five. This post is a tour of the ones that actually live in my muscle memory, plus the patterns I run when I'm debugging a real problem.

A note on tooling: the classic ifconfig, route, and arp commands ship from the net-tools package and have been deprecated for a decade. Their replacements live in iproute2: ip addr, ip route, ip neigh. The old commands still work via compat shims on most distros, but new scripts and habits should use ip. This post leads with ip.

ip addr shows every interface and the addresses bound to each.

bash
ip addr
js
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 ...    inet 127.0.0.1/8 scope host lo    inet6 ::1/128 scope host2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 ...    inet 10.0.1.42/24 brd 10.0.1.255 scope global dynamic eth0    inet6 fe80::abcd:1234/64 scope link3: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 ...    inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0

The classic interface name conventions:

Single interface only:

bash
ip addr show eth0

ip link is similar but shows just the link layer (state, MAC, MTU) without IP addresses — handy when you only care about whether an interface is up.

bash
ip linkip link set eth0 up      # bring upip link set eth0 down    # bring down

Reachability — ping, mtr

ping sends ICMP echo requests and reports round-trip time. It's still the fastest way to confirm a host is reachable.

bash
ping example.comping -c 4 example.com    # send exactly 4 packets and exitping -i 0.2 example.com  # 200 ms between packets

For tracing where a connection breaks down, mtr is traceroute and ping rolled into one — it traces the path hop-by-hop and updates the packet-loss/latency columns continuously. It's the tool I reach for when latency is bad and I need to find which hop is dropping packets.

bash
mtr example.commtr -r -c 50 example.com  # report mode, 50 packets per hop, then exit

If mtr isn't installed, plain traceroute still works:

bash
traceroute example.com

Routing — ip route

The kernel's routing table tells you where traffic for a given destination goes.

bash
ip route
js
default via 10.0.1.1 dev eth0 proto dhcp src 10.0.1.42 metric 10010.0.1.0/24 dev eth0 proto kernel scope link src 10.0.1.42172.17.0.0/16 dev docker0 proto kernel scope link src 172.17.0.1

Reading it: anything matching 10.0.1.0/24 goes directly out eth0; everything else (the default route) gets sent to the gateway 10.0.1.1.

To check which route the kernel picks for a specific destination — useful when there are multiple interfaces or VPN tunnels in play:

bash
ip route get 8.8.8.8
js
8.8.8.8 via 10.0.1.1 dev eth0 src 10.0.1.42 uid 1000

DNS — dig, host

DNS issues are the source of an outsized share of "the network is broken" pages. Two tools cover almost everything:

bash
host example.comdig example.comdig +short example.com    # just the IP, scriptabledig example.com @1.1.1.1  # query a specific resolverdig MX example.com        # specific record type

For a deeper walkthrough of dig's flags, see my dig post.

Listening sockets — ss

ss (from iproute2) replaces netstat and is significantly faster on busy hosts. The flag combo I use almost daily:

bash
ss -tulpn
js
Netid  State   Recv-Q  Send-Q  Local Address:Port    Peer Address:Port  Processtcp    LISTEN  0       128     0.0.0.0:22           0.0.0.0:*          users:(("sshd",pid=1065,fd=3))tcp    LISTEN  0       511     0.0.0.0:80           0.0.0.0:*          users:(("nginx",pid=742,fd=11))tcp    LISTEN  0       511     0.0.0.0:443          0.0.0.0:*          users:(("nginx",pid=742,fd=14))tcp    LISTEN  0       70      127.0.0.1:3306       0.0.0.0:*          users:(("mariadbd",pid=23070,fd=24))

Filter to a single port — handy when you're trying to figure out what's already squatting on it:

bash
ss -tulpn 'sport = :443'

I covered the same ground from a different angle in listing the ports in use on Linux.

Live packet inspection — tcpdump

When a service "isn't reachable" and you've ruled out DNS and routing, the next stop is watching the actual packets.

bash
sudo tcpdump -i eth0 -n
bash
sudo tcpdump -n port 80                  # only HTTPsudo tcpdump -n host 1.2.3.4             # only a specific peersudo tcpdump -n -i any port 5432         # any interface, Postgressudo tcpdump -n -w out.pcap port 443     # write to a pcap for later analysis

-n skips DNS resolution — both faster and more useful when you're debugging DNS itself. For deeper analysis, wireshark (or its CLI sibling tshark) is the next stop.

ARP / Neighbour table — ip neigh

The kernel's local-network neighbour table — IP-to-MAC mappings it has learned about peers on the same L2 segment.

bash
ip neigh
js
10.0.1.1   dev eth0 lladdr 00:1a:2b:3c:4d:5e REACHABLE10.0.1.50  dev eth0 lladdr aa:bb:cc:dd:ee:ff STALE

Useful when you're chasing duplicate IPs, dead gateways, or STALE/FAILED entries that tell you a peer disappeared.

DNS resolver config — /etc/resolv.conf

The system's recursive DNS resolvers live here:

bash
cat /etc/resolv.conf
js
nameserver 1.1.1.1nameserver 8.8.8.8

Heads up: on most modern distros, /etc/resolv.conf is managed by systemd-resolved or NetworkManager. Edits get clobbered on reboot. To change resolvers permanently, configure the manager (e.g. nmcli or /etc/systemd/resolved.conf) instead of the file.

Local hostname overrides — /etc/hosts

A hand-edited override that's consulted before DNS. Convenient for testing things against an IP without touching real DNS.

bash
cat /etc/hosts

Add a line like:

js
127.0.0.1 my-app.local

…and my-app.local resolves to localhost on this machine.

A real debugging workflow

When someone hands me a "the app can't reach the database" ticket, the rough sequence is:

  1. DNS works? dig db.internal +short — does it resolve?
  2. Route works? ip route get $(dig +short db.internal) — which interface, which gateway?
  3. L4 reachable? nc -vz db.internal 5432 (or curl -v telnet://...) — is the port open?
  4. Service listening? On the DB host, ss -tulpn | grep 5432
  5. Packets making it? On both ends, sudo tcpdump -n port 5432

That five-step sweep eliminates the vast majority of "it's the network" pages without leaving the terminal.

Cheat sheet

JobCommand
List interfacesip addr / ip link
Bring interface up/downip link set <if> up|down
Reachabilityping, mtr
Show routing tableip route
Picked route for a hostip route get <ip>
DNS lookupdig, host
Listening socketsss -tulpn
Watch packetssudo tcpdump -n -i <if> <expr>
Neighbour / ARP tableip neigh
Resolver config/etc/resolv.conf
Local DNS override/etc/hosts

That's the toolkit. Combined with curl, nc, and a healthy distrust of "it works on my machine," this covers most of what you'll need on any Linux host.