Skip to content
ALB Wiki

Networking

This is an old revision of this page — revision 5 (1970-01-21 18:02:21 UTC). It may differ from the current revision.

Networking is Linux's home ground — the OS runs the internet's routers, servers, and backbones. This chapter covers the practical surface: ip for interfaces and routes, ss for sockets, ssh for remote work, curl/wget for transfers, dig for DNS, tcpdump for the wire, and nftables/iptables for the firewall — enough to configure, diagnose, and defend a networked Linux.

The plumbing — ip

ip addr                     # interfaces + addresses — replaces ifconfig
ip link                     # the link layer — up/down, MAC
ip route                    # the routing table — default via...
ip -s link                  # per-interface counters
ip addr add 192.168.1.10/24 dev eth0    # add an address
ip link set eth0 up         # bring it up
ip route add default via 192.168.1.1    # the gateway
ip neigh                    # ARP/neighbors — who's on the wire

ip is the unified interface — addr/link/route/neigh/rule/tunnel cover what ifconfig, route, arp did historically. Learn ip; the rest are legacy.

DNS — name to number

dig example.com            # the full answer
dig +short example.com     # just the IP
dig MX example.com         # mail records
dig -x 8.8.8.8            # reverse lookup
host example.com           # the simple version
cat /etc/resolv.conf       # which resolvers you ask
cat /etc/hosts             # the local overrides — checked BEFORE DNS
getent hosts example.com   # the NSS path — hosts+DNS+everything

/etc/hosts beats DNS — the local override mechanism (127.0.0.1 myserver — the classic trick for local development). nsswitch.conf decides the order.

Sockets — who's listening

ss -tlnp                  # TCP listeners — who serves what
ss -tln                  # without process info
ss -ulnp                # UDP listeners
ss -s                   # summary stats
lsof -i :80             # who owns port 80
nc -zv host 22          # port-probe — "can I reach sshd?"
nc -l 8080              # a listener in one line

ss -tlnp is the security audit — every open port, every owning process, in one command.

Connectivity diagnosis

ping -c3 1.1.1.1            # reach the world (IP layer)
ping -c3 example.com        # + DNS
traceroute example.com      # the hops — mtr is the better version
curl -I https://x.com       # headers — is the service alive?
curl -v https://x.com       # the whole conversation — TLS, headers, all
wget -c url                 # resumable download
curl -o file url            # download

The diagnostic sequence — ping gateway → ping 1.1.1.1 → ping name — localizes every network failure in three steps: link, route, DNS.

ssh — the remote door

ssh user@host                    # remote shell
ssh -p 2222 user@host            # nonstandard port
ssh -i ~/.ssh/key user@host      # key auth
scp file user@host:/path/        # copy over ssh
rsync -avz dir/ user@host:/path/ # the better copy — incremental, resumable
ssh -L 8080:remote:80 user@host  # port forward — the tunnel
ssh -D 1080 user@host            # SOCKS proxy through ssh
ssh-keygen -t ed25519            # generate a keypair
ssh-copy-id user@host            # install your pubkey
cat ~/.ssh/known_hosts           # the trust store

Key auth beats passwords — ~/.ssh/id_ed25519 private (mode 600, never leaves), .pub public (installed in ~/.ssh/authorized_keys on the far side). ~/.ssh/config names hosts: Host myvps\n HostName 1.2.3.4\n User admin\n Port 2222 → ssh myvps.

The wire — tcpdump

tcpdump -i eth0                    # everything on the interface
tcpdump -i eth0 port 80            # HTTP only
tcpdump -i eth0 host 1.2.3.4       # to one peer
tcpdump -i eth0 -n icmp            # no DNS lookups, ICMP only
tcpdump -w capture.pcap            # to file — read with wireshark

The wire is honest — when the application lies, tcpdump shows what actually moved.

The firewall — nftables

nft list ruleset                   # the current policy
nft add table inet filter          # modern firewall setup
iptables -L                        # the legacy listing — still everywhere
iptables -A INPUT -p tcp --dport 22 -j ACCEPT
iptables -A INPUT -j DROP          # the default-deny tail

nftables is the modern engine (nft); iptables is the legacy syntax — both write the same kernel netfilter rules. The pattern: default-deny incoming, allow what's needed (22, your services), log drops.

The protocols — the layered map

# the stack: L1 physical → L2 ethernet → L3 IP → L4 TCP/UDP → L7 HTTP/SSH/DNS
ping uses ICMP (L3)          # reachability
arp / ip neigh               # L2↔L3 mapping — who has this IP on the wire
TCP = ordered streams        # ssh, http, everything reliable
UDP = datagrams              # DNS, WireGuard, VoIP — fast, unordered
icmp = diagnostics           # ping, traceroute, PMTUD

traceroute exploits TTL — UDP/ICMP probes with increasing TTLs die at each hop and report back — the path itself revealed. mtr is the continuous version.

The socket taxonomy

ss -x                       # unix sockets — local IPC
ss -t                       # TCP
ss -u                       # UDP
ss -l                       # listeners
ss -p                       # processes
ss -o state established     # filter by state
ss -tn dst 1.2.3.4          # by peer
nc -l -p 8080               # a raw listener
nc host 8080 < file         # send a file
nc -zv host 1-1000          # port range scan
socat TCP-L:8080,fork TCP:target:80   # the swiss-army socket tool

The firewall — nftables deep

nft list ruleset
nft add table inet filter
nft add chain inet filter input '{ type filter hook input priority 0; policy drop; }'
nft add rule inet filter input iif lo accept
nft add rule inet filter input ct state established,related accept
nft add rule inet filter input tcp dport '{22, 80, 443}' accept
nft add rule inet filter input icmp type echo-request accept
nft flush ruleset            # clear it all
nft -a list ruleset          # handles for deleting rules
iptables-translate -A INPUT -p tcp --dport 22 -j ACCEPT   # legacy→nft

The policy grammar: tables (inet covers v4+v6) → chains (input/output/forward hooks) → rules (match → verdict). policy drop is the default-deny posture.

Advanced ip — the grown-up commands

ip route show table all           # all routing tables
ip rule add from 10.0.0.0/8 table 100   # policy routing
ip route add 10.0.0.0/8 via 192.168.1.1 table 100
ip addr add 10.0.0.5/24 dev eth0 label eth0:vip  # secondary IP — a VIP
ip link set eth0 mtu 1400         # MTU surgery — the tunnel fix
ip link set eth0 promisc on       # sniffing mode
ip -s -h link                     # human-readable counters
ip -j addr show                   # JSON output — scriptable

Interfaces — bridges, bonds, tunnels

ip link add name br0 type bridge          # a software switch
ip link add name wg0 type wireguard       # a VPN interface
ip tunnel add tun0 mode gre remote x local y   # a tunnel
ip link add veth0 type veth peer name veth1    # a cable between namespaces

Interfaces aren't just hardware — the kernel manufactures virtual ones. WireGuard's wg0, Docker's veth, a bridge between a VM and the world — all ip link citizens.

The ssh full toolkit

ssh user@host                       # remote shell
ssh -p 2222 -i ~/.ssh/key user@host # port + key
ssh -v user@host                    # verbose — the auth dance
ssh -vvv user@host                  # maximum verbosity
ssh -N -L 8080:target:80 user@host  # forward-only, no shell
ssh -fN -L ... user@host            # background the tunnel
ssh -D 1080 user@host               # SOCKS5 proxy
ssh -R 9090:localhost:3000 user@host  # reverse forward — expose yours
ssh -J bastion user@internal        # jump host — ProxyJump
ssh -o StrictHostKeyChecking=no ... # skip the verify prompt
scp file user@host:/path/           # copy
scp -r dir/ user@host:/path/        # recursive
sftp user@host                      # the interactive transfer
rsync -avz --progress dir/ user@host:/path/   # the best copy — incremental
rsync -avz -P -e ssh src/ dst:path/           # resumable
ssh-keygen -t ed25519               # the keypair
ssh-copy-id user@host               # install pubkey
ssh-add; ssh-agent                  # the agent — keys cached once
ssh-keygen -R host                  # forget a changed hostkey
cat ~/.ssh/config:
# Host myvps
#   HostName 1.2.3.4
#   User admin
#   Port 2222
#   IdentityFile ~/.ssh/vps_key

-J jumps through a bastion; -N forwards without a shell; -f backgrounds; -R is the reverse-tunnel. ~/.ssh/config names hosts — ssh myvps expands all of it.

curl — the HTTP instrument

curl -I url              # headers only
curl -v url              # the whole conversation — TLS, redirects
curl -o file url         # download
curl -O url              # keep filename
curl -L url              # follow redirects
curl -k url              # skip TLS verify — the "is it the cert?" test
curl -s url | jq .       # API piping
curl -X POST -d 'a=b' url        # POST
curl -H 'Auth: token' url        # headers
curl -u user:pass url            # basic auth
curl --connect-timeout 5 url     # timeouts
curl -w '%{http_code} %{time_total}\n' -o /dev/null url   # the timing probe

-w turns curl into a latency instrument — time_total, time_namelookup, time_connect, time_appconnect — the DNS/TCP/TLS breakdown.

The hostname + interface files

/etc/hostname, /etc/hosts, /etc/resolv.conf, /etc/sysconfig/ifconfig.eth0 (Slackware/LFS), netplan YAML (Ubuntu), NetworkManager (desktop distros), systemd-networkd (systemd) — each distro's answer to "how does interface config persist" — the files chapter 6 of LFS writes by hand.

Where networking goes wrong

SymptomCause
Ping IP works, ping name doesn'tDNS — resolv.conf/nsswitch
Ping name works, IP doesn'tRouting — ip route, the gateway
ssh "connection refused"sshd not listening — ss -tlnp | grep 22
ssh "permission denied"Key/auth — -v shows the dance
Port open but unreachableFirewall — iptables -L/nft list ruleset
Interface exists, no addressip link set X up + ip addr add
Everything works but one host/etc/hosts stale entry

Exercises

  1. ss -tlnp — inventory every listener on your box; identify each.
  2. ip route, ip neigh — read your real routing table.
  3. ssh -L 8080:localhost:80 user@host — build a tunnel; browse through it.
  4. tcpdump -i any icmp while pinging — see the wire.
  5. dig +short then getent hosts — the two DNS paths.
  6. curl -v a site — read the TLS + headers.

See also

This page was last edited 1970-01-21 18:02:21 UTC by Devin. What links here