🏠 Home / Hub

Linux 05 — Networking Commands

Linux networking tools let you inspect interfaces, trace routes, transfer files, manage remote servers via SSH, and diagnose connectivity problems. These commands are daily tools for any sysadmin or DevOps engineer.

1. ip — Network Interface and Route Management

The ip command (from iproute2 package) replaces the older ifconfig and route commands. Use this on modern systems.

# ip addr — show IP addresses
$ ip addr show                          # all interfaces
$ ip addr show eth0                     # specific interface
$ ip addr show up                       # only active interfaces
$ ip a                                  # shorthand

# Example output:
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP
    link/ether 52:54:00:12:34:56 brd ff:ff:ff:ff:ff:ff
    inet 192.168.1.100/24 brd 192.168.1.255 scope global dynamic eth0
    inet6 fe80::5054:ff:fe12:3456/64 scope link

# Add/remove IP address (as root)
$ ip addr add 192.168.1.200/24 dev eth0
$ ip addr del 192.168.1.200/24 dev eth0

# ip link — network interface control
$ ip link show                          # show all interfaces
$ ip link set eth0 up                   # bring interface up
$ ip link set eth0 down                 # bring interface down
$ ip link set eth0 mtu 9000             # set MTU (jumbo frames)

# ip route — routing table
$ ip route show                         # show routing table
$ ip route                              # shorthand
$ ip route show default                 # show default gateway
$ ip route get 8.8.8.8                  # show route to specific IP

# Example routing table:
default via 192.168.1.1 dev eth0 proto dhcp metric 100
192.168.1.0/24 dev eth0 proto kernel scope link src 192.168.1.100

# Add/remove routes
$ ip route add 10.0.0.0/8 via 192.168.1.1     # add static route
$ ip route del 10.0.0.0/8                      # remove route
$ ip route add default via 192.168.1.1         # add default gateway

2. ss — Socket Statistics (Port Scanner)

ss is the modern replacement for netstat. It shows socket (connection/port) information.

# ss — socket statistics
$ ss -tulpen                    # TCP+UDP, listening, process, numeric, extended
# Flags: t=TCP, u=UDP, l=listening, p=process, e=extended, n=numeric (no DNS)

$ ss -an                        # all sockets, numeric
$ ss -tn                        # TCP only, numeric
$ ss -tnp                       # TCP with process names (run as root)
$ ss -tlnp                      # TCP listening ports only
$ ss -ulnp                      # UDP listening ports only
$ ss -s                         # summary statistics

# Example output:
Netid State   Recv-Q Send-Q  Local Address:Port    Peer Address:Port   Process
tcp   LISTEN  0      128          0.0.0.0:22       0.0.0.0:*       users:(("sshd",pid=1234,fd=3))
tcp   LISTEN  0      511          0.0.0.0:80       0.0.0.0:*       users:(("nginx",pid=5678,fd=6))
tcp   ESTAB   0      0      192.168.1.100:22  203.0.113.10:54321 users:(("sshd",pid=9012,fd=4))

# Filter by port
$ ss -tnp | grep :80            # find processes on port 80
$ ss -tnp state established     # only established connections
$ ss -tnp state listening       # only listening sockets
$ ss -tnp src :80               # connections FROM port 80
$ ss -tnp dst :443              # connections TO port 443
$ ss dst 192.168.1.0/24         # connections to subnet

# Summary
$ ss -s
Total: 623
TCP:   45 (estab 12, closed 20, orphaned 0, timewait 20)
# timewait: connections being gracefully closed

netstat (older systems)

# If ss is not available or for familiarity
$ netstat -tulpen               # same flags as ss, similar output
$ netstat -an | grep :80        # connections on port 80
$ netstat -r                    # routing table (like ip route)

3. ping — Test Network Connectivity

# Basic ping
$ ping google.com               # ping continuously (Ctrl+C to stop)
$ ping 8.8.8.8                  # ping by IP
$ ping -c 4 google.com          # send exactly 4 packets
$ ping -c 4 -i 0.5 google.com   # send 4 packets, 0.5 seconds apart
$ ping -c 10 -q google.com      # quiet mode (only shows summary)
$ ping -s 1400 google.com       # set packet size (test MTU issues)
$ ping -t 64 google.com         # set TTL (time to live)
$ ping -W 1 google.com          # 1 second timeout per packet
$ ping6 ::1                     # ping IPv6

# Example output:
PING google.com (142.250.185.14) 56(84) bytes of data.
64 bytes from lga34s32-in-f14.1e100.net: icmp_seq=1 ttl=118 time=12.4 ms
64 bytes from lga34s32-in-f14.1e100.net: icmp_seq=2 ttl=118 time=11.8 ms
--- google.com ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 3004ms
rtt min/avg/max/mdev = 11.8/12.1/12.4/0.2 ms

# TTL explained:
# Each router hop decrements TTL by 1
# Starting TTL reveals OS: Linux=64, Windows=128, Cisco=255
# Low TTL means many hops (or restricted TTL)

4. traceroute / tracepath — Trace Network Path

# traceroute — show each hop to destination
$ traceroute google.com                  # trace route (uses UDP by default)
$ traceroute -T google.com               # use TCP (better through firewalls)
$ traceroute -I google.com               # use ICMP
$ traceroute -n google.com               # don't resolve hostnames (faster)
$ traceroute -m 30 google.com            # max 30 hops
$ traceroute -p 443 google.com           # use specific port

# tracepath — simpler, no root required
$ tracepath google.com
$ tracepath -n google.com                # no hostname resolution

# Example output:
 1:  192.168.1.1          1.2ms
 2:  10.0.0.1             5.4ms
 3:  203.0.113.1         12.3ms
 4:  * * *               # no response (filtered ICMP)
 5:  142.250.185.14      15.6ms  google.com

# * * * means router is not responding to probes (not necessarily broken)

5. curl — HTTP Client and Data Transfer

curl is the Swiss Army knife of HTTP. It supports HTTP, HTTPS, FTP, SFTP, and dozens of other protocols.

# Basic usage
$ curl https://example.com              # GET request, print response body
$ curl -s https://example.com           # silent (no progress meter)
$ curl -o output.html https://example.com  # save to file
$ curl -O https://example.com/file.zip  # save with original filename

# HTTP methods
$ curl -X GET https://api.example.com/users
$ curl -X POST https://api.example.com/users
$ curl -X PUT https://api.example.com/users/1
$ curl -X DELETE https://api.example.com/users/1
$ curl -X PATCH https://api.example.com/users/1

# Headers
$ curl -I https://example.com           # headers only (HEAD request)
$ curl -H "Authorization: Bearer token123" https://api.example.com
$ curl -H "Content-Type: application/json" https://api.example.com
$ curl -A "MyBot/1.0" https://example.com   # custom User-Agent

# POST data
$ curl -d "name=alice&age=30" https://api.example.com/users   # form data
$ curl -d '{"name":"alice","age":30}' \
       -H "Content-Type: application/json" \
       https://api.example.com/users                          # JSON POST

# Follow redirects and auth
$ curl -L https://short.url/xyz         # -L: follow redirects
$ curl -u username:password https://api.example.com  # basic auth
$ curl -k https://self-signed.example.com  # -k: ignore SSL cert errors

# Response details
$ curl -v https://example.com           # verbose (shows headers, handshake)
$ curl -w "%{http_code}" -o /dev/null https://example.com  # just status code
$ curl -w "\nTime: %{time_total}s\n" -o /dev/null -s https://example.com

# Download with resume
$ curl -C - -O https://example.com/large-file.iso  # resume interrupted download

# Multiple URLs
$ curl https://site1.com https://site2.com  # fetch both

# Practical API testing
$ curl -s https://api.github.com/users/torvalds | python3 -m json.tool
$ curl -s ifconfig.me                   # get your public IP address
$ curl -s https://api.ipify.org?format=json  # public IP in JSON

6. wget — Download Files

# wget — non-interactive file downloader
$ wget https://example.com/file.tar.gz          # download file
$ wget -O output.tar.gz https://example.com/f   # custom output filename
$ wget -q https://example.com/file              # quiet mode
$ wget --limit-rate=1m https://example.com/f    # limit download speed to 1MB/s
$ wget -c https://example.com/large-file.iso    # continue partial download
$ wget -b https://example.com/large-file.iso    # background download

# Authentication
$ wget --user=alice --password=secret https://protected.example.com/file

# Recursive download (mirror a website)
$ wget -r https://example.com/docs/             # recursive download
$ wget -r -l 2 https://example.com/             # limit to 2 levels deep
$ wget -r -k -p https://example.com/            # download with page assets
$ wget --mirror https://example.com/            # full mirror

# Headers and timeouts
$ wget --timeout=30 https://example.com/file    # 30 second timeout
$ wget --tries=3 https://example.com/file       # retry 3 times

7. SSH — Secure Shell

# Basic SSH connection
$ ssh user@hostname                              # connect
$ ssh user@192.168.1.100                        # connect by IP
$ ssh -p 2222 user@hostname                     # custom port
$ ssh -i ~/.ssh/mykey.pem user@hostname         # use specific private key
$ ssh -v user@hostname                          # verbose (debug connection)
$ ssh root@hostname                             # connect as root (avoid this)

# Execute commands remotely
$ ssh user@hostname "ls -la /var/www"           # run single command
$ ssh user@hostname "sudo systemctl status nginx"
$ ssh user@hostname "cat /var/log/nginx/error.log | tail -50"

# Port forwarding
$ ssh -L 8080:localhost:80 user@hostname        # local forwarding
# Access localhost:8080 → tunnel → hostname:80

$ ssh -R 9090:localhost:3000 user@hostname      # remote forwarding
# hostname:9090 → tunnel → localhost:3000

$ ssh -D 1080 user@hostname                     # SOCKS5 proxy on port 1080
# Configure browser to use SOCKS5 proxy at 127.0.0.1:1080

# Keep alive options
$ ssh -o ServerAliveInterval=60 user@hostname   # send keepalive every 60s
$ ssh -o StrictHostKeyChecking=no user@hostname # don't verify host key

# SSH config file (~/.ssh/config)
Host myserver
    HostName 192.168.1.100
    User alice
    Port 2222
    IdentityFile ~/.ssh/myserver_key
    ServerAliveInterval 60
    ServerAliveCountMax 3

Host bastion
    HostName bastion.example.com
    User admin
    IdentityFile ~/.ssh/bastion_key

Host internal
    HostName 10.0.0.50
    User admin
    ProxyJump bastion                   # connect through bastion host

# With config, just type:
$ ssh myserver
$ ssh internal                          # automatically proxies through bastion

8. scp — Secure Copy

# Copy local file to remote
$ scp file.txt user@hostname:/home/user/
$ scp file.txt user@hostname:~               # shorthand for home dir
$ scp -P 2222 file.txt user@hostname:/tmp/   # custom port (uppercase P!)

# Copy remote file to local
$ scp user@hostname:/var/log/nginx/access.log .  # copy to current dir
$ scp user@hostname:~/config.txt ./config.txt     # rename while copying

# Copy directories
$ scp -r ./myproject user@hostname:/opt/          # recursive

# Use SSH config aliases
$ scp file.txt myserver:/tmp/            # uses ~/.ssh/config settings

# Copy between two remote servers
$ scp user1@host1:/path/file user2@host2:/path/

# Multiple files
$ scp file1.txt file2.txt user@hostname:/tmp/
$ scp *.log user@hostname:/var/backup/logs/

9. rsync — Efficient File Synchronization

rsync only transfers changed parts of files — much faster than scp for repeated synchronization tasks.

# Basic syntax: rsync [options] source destination

# Local sync
$ rsync -av /source/dir/ /backup/dir/           # sync directories
$ rsync -av /source/dir/ /backup/dir/           # trailing slash matters!
# /source/dir/ → contents of dir
# /source/dir  → the dir itself

# Remote sync
$ rsync -avz /local/dir/ user@hostname:/remote/dir/   # push to remote
$ rsync -avz user@hostname:/remote/dir/ /local/dir/   # pull from remote

# Common flags
# -a  archive mode: recursive, preserves perms, timestamps, symlinks, owner
# -v  verbose
# -z  compress during transfer
# -P  show progress + allow resume (= --progress --partial)
# -n  dry run (show what WOULD be transferred, don't actually do it)
# --delete      delete files in dest that don't exist in source
# --exclude     exclude files/dirs matching pattern
# --exclude-from  read exclude patterns from file
# --checksum    compare by checksum instead of size+time (slower, accurate)
# --bwlimit=1024  limit bandwidth to 1 MB/s

# Useful combinations
$ rsync -avzP --delete /local/ user@server:/backup/     # full mirror
$ rsync -avz --exclude='*.log' --exclude='.git' /src/ /dst/  # exclude files
$ rsync -avzn /source/ user@server:/dest/               # dry run first

# Sync using SSH with custom port
$ rsync -avz -e "ssh -p 2222" /local/ user@server:/remote/

# Create timestamped backups
$ rsync -av --backup --backup-dir=/backup/$(date +%Y%m%d) /source/ /dest/

# Monitor progress on large transfers
$ rsync -avP --stats /large_dir/ user@server:/backup/

10. DNS Tools — dig, nslookup, host

# dig — DNS lookup (most powerful)
$ dig google.com                        # A record (IPv4 address)
$ dig google.com A                      # explicit A record query
$ dig google.com AAAA                   # IPv6 address
$ dig google.com MX                     # mail exchange records
$ dig google.com NS                     # name servers
$ dig google.com TXT                    # TXT records (SPF, DKIM, etc.)
$ dig google.com SOA                    # start of authority
$ dig google.com CNAME                  # canonical name
$ dig -x 8.8.8.8                        # reverse DNS lookup (PTR record)

# Use specific DNS server
$ dig @8.8.8.8 google.com               # query Google DNS
$ dig @1.1.1.1 google.com               # query Cloudflare DNS
$ dig @192.168.1.1 google.com           # query local DNS server

# dig output options
$ dig +short google.com                 # just the IP address
$ dig +noall +answer google.com         # only show answer section
$ dig +trace google.com                 # trace full resolution path

# nslookup — simpler DNS tool
$ nslookup google.com                   # basic lookup
$ nslookup google.com 8.8.8.8           # use specific server
$ nslookup -type=mx google.com          # MX records

# host — simple DNS lookup
$ host google.com                       # forward lookup
$ host 8.8.8.8                          # reverse lookup
$ host -t mx google.com                 # MX records
$ host -t ns google.com                 # name servers

# whois
$ whois google.com                      # domain registration info
$ whois 8.8.8.8                         # IP ownership info

11. nmap — Network Scanner (Educational)

Legal notice: Only scan systems you own or have explicit written permission to scan. Unauthorized scanning is illegal in many jurisdictions.
# nmap — network exploration and security auditing
# Install: sudo apt install nmap

# Host discovery (ping scan only)
$ nmap -sn 192.168.1.0/24              # find live hosts on subnet
$ nmap -sn 192.168.1.1-50              # range of IPs

# Port scanning
$ nmap 192.168.1.100                   # scan top 1000 common ports
$ nmap -p 80,443,8080 192.168.1.100    # specific ports
$ nmap -p 1-1024 192.168.1.100         # port range 1-1024
$ nmap -p- 192.168.1.100               # ALL 65535 ports (slow)
$ nmap --open 192.168.1.100            # only show open ports

# Service and version detection
$ nmap -sV 192.168.1.100               # detect service versions
$ nmap -O 192.168.1.100                # OS detection (needs root)
$ nmap -A 192.168.1.100                # aggressive: OS + version + scripts + traceroute

# Scan types
$ nmap -sT 192.168.1.100               # TCP connect scan (default, no root needed)
$ nmap -sS 192.168.1.100               # TCP SYN scan (stealth, needs root)
$ nmap -sU 192.168.1.100               # UDP scan (slow)

# Output
$ nmap -oN scan.txt 192.168.1.100      # save normal output
$ nmap -oX scan.xml 192.168.1.100      # save XML output
$ nmap -oG scan.grep 192.168.1.100     # grepable output

12. Network Configuration Files

# /etc/hosts — local DNS override (checked before DNS)
$ cat /etc/hosts
127.0.0.1     localhost
127.0.1.1     myserver.local myserver
192.168.1.100 dbserver.local dbserver
10.0.0.50     redis.internal

# Add an entry
$ echo "192.168.1.200 testserver" | sudo tee -a /etc/hosts

# /etc/resolv.conf — DNS resolver configuration
$ cat /etc/resolv.conf
nameserver 8.8.8.8            # primary DNS server
nameserver 1.1.1.1            # secondary DNS server
search example.com local      # domain search list
options ndots:5               # dots needed before adding search domains

# /etc/nsswitch.conf — name service switch
# Defines order: hosts, files, dns
hosts:          files dns      # check /etc/hosts first, then DNS

# On Debian/Ubuntu: NetworkManager or netplan
# /etc/netplan/*.yaml (Ubuntu 18.04+)
$ cat /etc/netplan/00-installer-config.yaml
network:
  version: 2
  ethernets:
    eth0:
      dhcp4: true
    eth1:
      addresses: [192.168.1.100/24]
      gateway4: 192.168.1.1
      nameservers:
        addresses: [8.8.8.8, 1.1.1.1]

$ sudo netplan apply            # apply changes

# On CentOS/RHEL: /etc/sysconfig/network-scripts/
$ cat /etc/sysconfig/network-scripts/ifcfg-eth0
DEVICE=eth0
BOOTPROTO=static
IPADDR=192.168.1.100
NETMASK=255.255.255.0
GATEWAY=192.168.1.1
DNS1=8.8.8.8

13. Practical Networking Tasks

# Check what's running on a port
$ ss -tlnp | grep :80
$ lsof -i :80

# Test if a port is open remotely
$ nc -zv 192.168.1.100 80       # netcat: -z=scan, -v=verbose
$ nc -zv -w 3 hostname 443      # 3 second timeout
$ curl -v telnet://hostname:25  # test SMTP port

# Quick HTTP test
$ curl -I http://192.168.1.100          # check HTTP headers
$ curl -w "%{http_code}" -o /dev/null -s http://hostname  # just status

# Check DNS resolution speed
$ time dig google.com A +short           # measure DNS query time

# Get your public IP
$ curl ifconfig.me
$ curl -s https://api.ipify.org
$ dig +short myip.opendns.com @resolver1.opendns.com

# Test bandwidth
$ curl -o /dev/null http://speedtest.example.com/100mb-file.bin  # download test

# Quick port scan of your own server
$ nmap -sT -p 22,80,443,3306,5432 localhost

# Monitor network traffic in real time
$ iftop -n                              # install: apt install iftop
$ nethogs                               # per-process bandwidth: apt install nethogs
$ watch -n 1 "ss -s"                    # watch socket summary every second

📌 Study Checklist