Linux Networking Commands: ip, ss, curl, dig
A practical guide to modern Linux networking tools. Learn ip, ss, curl, and dig to diagnose connectivity, inspect sockets, and resolve DNS issues fast.
What you'll learn
- ✓Why ip and ss have replaced ifconfig and netstat
- ✓How to inspect interfaces, routes, and neighbors with ip
- ✓How to find listening ports and active sockets with ss
- ✓How to probe HTTP endpoints and headers with curl
- ✓How to debug DNS resolution with dig and getent
Prerequisites
- •Comfort with a Linux shell ([Linux essentials](/blog/linux-essential-commands))
- •Basic understanding of the [Linux file system](/blog/linux-file-system)
If you learned Linux networking a decade ago, your muscle memory probably types ifconfig and netstat. Both still ship on some distros, but they have been deprecated for years in favor of the iproute2 suite. The new tools are faster, expose more information, and present a consistent flag style. This guide walks through the four commands you will reach for most often: ip, ss, curl, and dig.
Why ifconfig and netstat are out
ifconfig and netstat come from net-tools, a package that has been unmaintained for years. They cannot show modern features like multiple IPs per interface cleanly, network namespaces, or VRFs. Distributions like RHEL, Fedora, Debian, and Arch no longer install net-tools by default.
The replacement is iproute2, which provides ip and ss. The mental model is simple: ip manages layer 2 and layer 3 (interfaces, addresses, routes, neighbors), and ss inspects sockets.
Inspecting interfaces with ip
ip has subcommands and most of them accept short forms. The two you will use constantly are ip addr and ip route.
# Show all interfaces and IPs (short: ip a)
ip addr show
# Just one interface
ip addr show dev eth0
# Routing table
ip route show
# Which interface and gateway would reach 1.1.1.1?
ip route get 1.1.1.1
# ARP / neighbor table (replacement for `arp -a`)
ip neigh show
Bring an interface up or down, or add an IP for testing:
sudo ip link set eth0 up
sudo ip addr add 10.0.0.5/24 dev eth0
sudo ip route add default via 10.0.0.1
These changes are not persistent. For persistent config, your distro uses NetworkManager, systemd-networkd, or /etc/network/interfaces.
A useful diagnostic is to follow the chain: does the interface have an IP, is there a default route, and does ARP resolve the gateway? If any link breaks, you know where to look.
Sockets and ports with ss
ss (socket statistics) reads directly from kernel structures and is significantly faster than netstat on busy hosts. The classic invocation:
# Listening TCP sockets with process info
sudo ss -tlnp
# All TCP (listening + established), numeric
ss -tan
# UDP listeners
sudo ss -ulnp
# Connections to a specific port
ss -tan '( dport = :443 or sport = :443 )'
# Summary of socket counts by state
ss -s
The flag combo -tlnp is worth memorizing: TCP, listening, numeric, process. When a service refuses to start because the port is in use, this tells you who is squatting on it.
For Unix domain sockets:
ss -lxp
HTTP probing with curl
curl is the universal HTTP client. For diagnostics, the flags matter more than the URL.
# Just headers
curl -I https://example.com
# Follow redirects and show the final response
curl -ILv https://example.com
# Timing breakdown
curl -o /dev/null -s -w \
'dns:%{time_namelookup} connect:%{time_connect} tls:%{time_appconnect} ttfb:%{time_starttransfer} total:%{time_total}\n' \
https://example.com
The -w template is gold for debugging slow APIs. If time_namelookup is high, your DNS is the bottleneck. If time_appconnect is high, TLS handshake or certificate validation is slow. If time_starttransfer dominates, the server itself is slow.
Other flags you will reuse:
# POST JSON
curl -X POST -H 'content-type: application/json' \
-d '{"name":"loom"}' https://api.example.com/v1/items
# Use a specific resolver (skip /etc/hosts and system DNS)
curl --resolve example.com:443:93.184.216.34 https://example.com
# Test from a specific source interface
curl --interface eth0 https://example.com
DNS with dig and getent
DNS issues hide behind a surprising number of “the network is broken” tickets. dig is the right tool for inspecting DNS, but it only queries DNS, while applications go through the system resolver (which may use /etc/hosts, mDNS, or nsswitch). Use getent hosts to see what the resolver actually returns.
# Standard A record lookup
dig example.com
# Short answer only
dig +short example.com
# Ask a specific resolver
dig @1.1.1.1 example.com
# Trace the resolution from the root
dig +trace example.com
# Check MX, TXT, NS
dig example.com MX
dig example.com TXT
# Reverse lookup
dig -x 93.184.216.34
# What does the system resolver say (honors /etc/hosts and nsswitch)?
getent hosts example.com
If dig and getent disagree, suspect /etc/hosts, /etc/nsswitch.conf, or a local stub resolver like systemd-resolved. Check it with resolvectl status on systemd hosts.
A diagnostic flow you can reuse
When a service cannot reach another host, walk down the stack:
- Resolve the name:
dig +short target.example.comandgetent hosts target.example.com. - Confirm a route exists:
ip route get <ip>. - Test the TCP handshake:
nc -vz target.example.com 443orcurl -v https://target.example.com. - Confirm the local listener (if you control the target):
sudo ss -tlnp | grep :443. - Check timing with
curl -wto see whether the slowness is DNS, TCP, TLS, or the application.
This sequence catches most issues without reaching for tcpdump or strace. If you do need packet capture, sudo tcpdump -i any -n port 443 is the starting point, but resist the urge until the cheaper checks rule out the obvious.
Combining with the shell
These tools compose well with the patterns from shell scripting basics. A small wrapper to flag processes holding privileged ports:
#!/usr/bin/env bash
sudo ss -tlnp | awk 'NR>1 && $4 ~ /:(2[0-9]|[1-9][0-9]?)$/ {print $4, $6}'
You can also pair these with process management to find the PID using a port and inspect it further with ps and lsof.
Wrap up
Stop reaching for ifconfig and netstat. ip and ss give you the same answers faster and reveal information the old tools cannot. Pair them with curl for HTTP-level checks and dig plus getent for DNS, and you will resolve most “is it the network” tickets without leaving the terminal. Keep the diagnostic flow in mind: resolve, route, connect, listen, time. The tools are simple; the discipline of walking the stack is what makes the difference.