Linux Admin

Linux Networking Commands: ip, ss, ssh, curl, dig, tcpdump

Part of pathway: Linux Mastery: 300 Commands

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. ifconfig shows wrong info on multi-IP interfaces. Use ip a.
  • DNS issues looking like network issues. ping 8.8.8.8 works but ping google.com fails = DNS, not network.
  • scp uses -P, ssh uses -p. Capitals differ. Endless source of typos.
  • rsync trailing slash. Always test with -n first, especially with --delete.
  • Firewall hiding the problem. If a service is bound to 0.0.0.0:443 (visible in ss -tlnp) but unreachable, check iptables -L or firewall-cmd --list-all.
  • MTU mismatches over VPN/tunnels. Ping with -M do -s 1472 tests the path MTU. If it fails at standard size, fragmentation is broken upstream.

Conclusion

Five habits:

  1. ip a, ip r, ss -tunlp are your three orientation commands.
  2. ssh ~/.ssh/config — never type host details twice.
  3. mtr instead of single ping when investigating flaky networks.
  4. rsync -avPn dry-run before any destructive sync.
  5. curl -v when an HTTPS request misbehaves — the headers tell the story.

Related Linux Admin troubleshooting

For common errors and fixes related to this topic, see:

Leave a Reply