Modern Linux Networking Has Two Toolchains
If you learned Linux networking before 2015 you know ifconfig, route, netstat, and arp. Those are deprecated. The modern replacements — all bundled in iproute2 — are ip, ss, and bridge. They’re faster, more featureful, and consistent.
This article is a working reference for Linux networking on the command line: addressing, routing, sockets, DNS, and the everyday tools (ssh, scp, rsync, curl, wget, dig).
Interface and Address — ip
ip addr # all interfaces and their IPs
ip a # short form
ip a show eth0 # one interface
ip -4 a # IPv4 only
ip -6 a # IPv6 only
ip link # interfaces without addresses
ip link set eth0 up # bring interface up
ip link set eth0 down # bring it down
ip addr add 10.0.0.5/24 dev eth0 # assign address
ip addr del 10.0.0.5/24 dev eth0 # remove
ip -s link # interface counters (RX/TX, errors, drops)
Forget ifconfig. It doesn’t show all addresses (only one IPv4 per interface) and is missing on minimal modern installs.
Routing — ip route
ip route # routing table
ip r # short form
ip route get 8.8.8.8 # which route would be used
ip route add 10.10.0.0/16 via 10.0.0.1 # add a static route
ip route del 10.10.0.0/16
ip route flush cache # clear route cache
ip route show table all # all tables (policy routing)
ip route get DESTINATION is the secret weapon — tells you exactly which route the kernel would pick for that destination.
Sockets — ss (replaces netstat)
ss -tunlp # all listening, TCP+UDP, with PIDs
ss -tan # all TCP, all states
ss -tan state established # only established
ss -s # summary statistics
ss -tnp dst :443 # connections to port 443
ss -i # internal TCP info (cwnd, rtt)
Translation: -t TCP, -u UDP, -n numeric (no DNS lookups), -l listening, -p show process, -a all states.
Connectivity — ping, mtr, traceroute
ping -c 4 host # 4 packets and exit
ping -i 0.2 -c 20 host # 200ms interval (rapid)
ping -W 1 host # 1-second timeout
ping6 host # IPv6 explicitly
traceroute host # path to destination
traceroute -T -p 443 host # TCP traceroute on port 443
mtr host # ping + traceroute combined, live
mtr is the right tool for “network is flaky.” Continuously refreshes per-hop loss and latency. If hop 4 is dropping 30% packets while hops 1-3 and 5-9 are clean, that’s the culprit.
DNS — dig, nslookup, host
dig example.com # full output
dig +short example.com # just the answers
dig example.com MX # mail records
dig @8.8.8.8 example.com # use specific resolver
dig +trace example.com # trace from root
host example.com # short
nslookup example.com # legacy but still works
getent hosts example.com # uses /etc/nsswitch.conf order
dig +short is the everyday answer. dig +trace when DNS is misbehaving and you need to see whether the issue is at root, TLD, or authoritative.
SSH — The One You’ll Live In
ssh user@host # interactive
ssh -p 2222 user@host # custom port
ssh -i ~/.ssh/key user@host # explicit key
ssh -L 8080:localhost:80 user@host # local port-forward
ssh -R 9000:localhost:22 user@host # remote port-forward (reverse tunnel)
ssh -D 1080 user@host # SOCKS proxy
ssh -J jumphost user@target # jump-host (ProxyJump)
ssh-keygen -t ed25519 # generate ed25519 keypair
ssh-copy-id user@host # install your pubkey on remote
Set up ~/.ssh/config for hosts you connect to often:
Host prod-edge
HostName 198.51.100.5
User alice
Port 2222
IdentityFile ~/.ssh/prod-key
ServerAliveInterval 60
Now ssh prod-edge uses all those settings.
File Transfer — scp, rsync
scp file.txt user@host:/path/ # one file
scp -r dir/ user@host:/path/ # directory
scp -P 2222 file user@host:/ # custom port (capital P, unlike ssh)
rsync -avP src/ user@host:dst/ # rsync over ssh, archive + progress
rsync -avzP src/ user@host:dst/ # add compression
rsync -avP --delete src/ user@host:dst/ # delete files in dst not in src
rsync -avPn src/ user@host:dst/ # dry-run first
Trailing slash on rsync source matters. src/ means “contents of src,” src means “the src directory itself.” Always test with -n dry-run before destructive sync.
HTTP — curl and wget
curl https://example.com # GET
curl -I https://example.com # headers only
curl -L https://example.com # follow redirects
curl -o out.html https://example.com # save to file
curl -O https://example.com/file.zip # save with original filename
curl -X POST -d '{"k":"v"}' -H "Content-Type: application/json" api.com/x
curl -u user:pass https://api.com # basic auth
curl -k https://self-signed # ignore cert errors
curl -v https://example.com # verbose: see request & response
wget https://example.com/file.zip # download
wget -c URL # continue partial download
wget -m URL # mirror
curl for API work and quick checks; wget for resumable downloads and full-site mirrors.
Packet Capture — tcpdump
tcpdump -i eth0 # capture on eth0
tcpdump -i any port 80 # any interface, port 80
tcpdump -i eth0 -n -c 100 # numeric (no DNS), 100 packets
tcpdump -i eth0 host 10.0.0.5 # to/from one host
tcpdump -w capture.pcap -i eth0 # save to file (analyze in Wireshark)
tcpdump -r capture.pcap # read back
Common Pitfalls
- Using deprecated tools.
ifconfigshows wrong info on multi-IP interfaces. Useip a. - DNS issues looking like network issues.
ping 8.8.8.8works butping google.comfails = DNS, not network. scpuses-P,sshuses-p. Capitals differ. Endless source of typos.rsynctrailing slash. Always test with-nfirst, especially with--delete.- Firewall hiding the problem. If a service is bound to
0.0.0.0:443(visible inss -tlnp) but unreachable, checkiptables -Lorfirewall-cmd --list-all. - MTU mismatches over VPN/tunnels. Ping with
-M do -s 1472tests the path MTU. If it fails at standard size, fragmentation is broken upstream.
Conclusion
Five habits:
ip a,ip r,ss -tunlpare your three orientation commands.ssh ~/.ssh/config— never type host details twice.mtrinstead of single ping when investigating flaky networks.rsync -avPndry-run before any destructive sync.curl -vwhen an HTTPS request misbehaves — the headers tell the story.
Related Linux Admin troubleshooting
For common errors and fixes related to this topic, see: