Kali Linux for DevOps Engineers · Part 6 of 15
Kali Linux Networking Fundamentals for DevOps
Series curriculum (15 lessons)
Almost every infrastructure incident you will ever debug is, at some level, a networking problem: a service that cannot reach its database, a DNS name that resolves to the wrong address, a firewall that silently drops a packet, or a load balancer sending traffic to a port nothing is listening on. Kali Linux ships with a complete, up-to-date networking toolkit already installed, which makes it an excellent environment for learning to read a network the way a DevOps engineer needs to. This lesson builds the mental model and the muscle memory: the core concepts, then the exact commands you will reach for again and again.
You do not need any prior networking or penetration-testing knowledge. We will define each term as it comes up and connect every command back to a real operational question you will face on the job.
The Layers You Actually Need to Know
Networking is often taught as the seven-layer OSI model, but day-to-day troubleshooting only needs a handful of concepts working together. Think of a request leaving your machine as passing through a stack of checkpoints:
| Concept | Question it answers | Command family |
|---|---|---|
| Interface | Do I have a working network card / link? | ip link |
| IP address | What is my address on the network? | ip addr |
| CIDR / subnet | Which hosts are “local” vs. remote? | ip addr, ip route |
| Route | Where does traffic for this destination go? | ip route |
| Default gateway | How do I reach the rest of the world? | ip route |
| ARP / neighbors | What is the MAC address for a local IP? | ip neigh |
| DNS | What IP does this name resolve to? | dig, nslookup |
| TCP / UDP port | Is a service reachable and listening? | ss, ping, traceroute |
| Application | Does the service actually respond correctly? | curl, wget |
Keep this table in mind — the troubleshooting workflow later in the lesson walks these rows top to bottom.
Interfaces and links
A network interface is a connection point between your machine and a network — a physical NIC (eth0), a wireless card (wlan0), the loopback (lo, which is always 127.0.0.1 and lets a machine talk to itself), or a virtual interface created by Docker (docker0), a VPN (tun0), or a bridge. The link is the layer-2 state of that interface: is the cable plugged in / is the virtual link up?
IP addresses and CIDR
An IP address is your machine’s identity on a network, e.g. 10.0.5.23. It never travels alone — it comes with a subnet mask written in CIDR notation, like 10.0.5.23/24. The /24 means the first 24 bits identify the network and the remaining 8 bits identify the host. Practically:
/24→10.0.5.0–10.0.5.255(256 addresses, 254 usable) — everything in10.0.5.xis “local.”/16→10.0.0.0–10.0.255.255(65,536 addresses)./32→ a single exact host.
Why a DevOps engineer cares: the CIDR block tells you which destinations your machine considers local (reached directly) versus remote (sent to the gateway). Misjudged subnet boundaries are behind a surprising number of “why can’t these two servers see each other” tickets and misconfigured security-group / NACL rules.
Default gateway
The default gateway is the router your machine sends traffic to when the destination is not on your local subnet — the on-ramp to everything outside your immediate network, including the internet. If your gateway is wrong or unreachable, local traffic works but everything else fails, which is a classic and very diagnosable symptom.
DNS
DNS (Domain Name System) translates human names like api.example.com into IP addresses. Your app almost always connects by name, so a DNS failure looks identical to the service being down even when the service is perfectly healthy. Separating “name resolution” from “connectivity” is one of the most valuable skills in this lesson.
ARP and the neighbor table
Within a single subnet, machines actually deliver frames using MAC addresses (hardware addresses), not IP addresses. ARP (Address Resolution Protocol) maps a local IP to its MAC, and the results are cached in the neighbor table. When two hosts on the same subnet cannot talk despite correct IPs, a stale or incomplete neighbor entry is a prime suspect.
TCP, UDP, and ports
TCP and UDP are the two transport protocols you will meet constantly:
- TCP is connection-oriented and reliable — it performs a handshake, guarantees ordered delivery, and retransmits lost data. HTTP/HTTPS, SSH, and most databases use TCP.
- UDP is connectionless and fire-and-forget — lower overhead, no delivery guarantee. DNS queries, DHCP, and many metrics/telemetry protocols use UDP.
A port is a 16-bit number (0–65535) that identifies which service on a host a connection is for. 443 is HTTPS, 22 is SSH, 5432 is PostgreSQL. “The service is listening on a port” means a process has bound to that port and is ready to accept connections. A huge share of outages come down to one of three states: nothing is listening on the expected port, something is listening on the wrong interface (e.g. 127.0.0.1 only), or a firewall is blocking the port in between.
💡 Note — Kali is Debian-based, so everything here applies directly to Ubuntu/Debian servers too. The
ipandsscommands come from the moderniproute2suite. You may still see older tutorials useifconfig,route, andnetstat— those are deprecated and sometimes missing on minimal images, so learn the modern equivalents shown below.
Reading Your Machine’s Network: ip addr and ip link
Start every investigation by confirming what interfaces exist and which addresses they carry.
# Show every interface and its IP address(es)
ip addr
# Shorter alias
ip a
Typical output for one interface:
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 ... state UP
link/ether 02:42:ac:11:00:02 brd ff:ff:ff:ff:ff:ff
inet 172.17.0.2/16 brd 172.17.255.255 scope global eth0
What this tells a DevOps engineer, line by line:
state UP— the link is up (layer 2 is healthy).link/ether 02:42:ac:11:00:02— the interface’s MAC address.inet 172.17.0.2/16— the IPv4 address and CIDR. Instantly you know the machine’s address and that its local subnet is172.17.0.0/16.mtu 1500— the maximum packet size. MTU mismatches (common with VPNs and some overlay networks) cause the frustrating “small requests work, large ones hang” class of bug.
To focus on link state without addresses:
# Layer-2 status of every interface (UP/DOWN, MTU, MAC)
ip link show
# Bring an interface administratively up or down (needs sudo)
sudo ip link set eth0 up
ip link answers the very first troubleshooting question — is the interface even up? — before you waste time on higher layers. An interface in state DOWN or a missing interface entirely explains total connectivity loss immediately.
🛠️ DevOps Perspective — On cloud VMs and inside containers you will see interfaces you did not create:
docker0,veth*pairs,cni0,flannel.1,eth0in a namespace. Recognizing which interface carries the traffic you care about (and its CIDR) is essential for debugging container and Kubernetes networking, where a pod’s real address lives on a virtual interface, not the host’seth0.
Where Traffic Goes: ip route and the Default Gateway
The routing table decides, for any destination IP, which interface and next hop to use.
# Show the routing table
ip route
# Alias
ip r
Example:
default via 172.17.0.1 dev eth0
172.17.0.0/16 dev eth0 proto kernel scope link src 172.17.0.2
Read it like this:
default via 172.17.0.1 dev eth0— the default gateway is172.17.0.1; anything not matched by a more specific route goes there viaeth0.172.17.0.0/16 dev eth0— traffic for the local subnet is delivered directly oneth0, no gateway needed.
You can also ask the kernel exactly how it would route a specific destination — extremely useful for confirming whether traffic to a particular service leaves the expected interface (important on multi-homed or VPN-connected hosts):
# "How would I reach this specific address?"
ip route get 1.1.1.1
If ip route shows no default line, your machine cannot reach anything off-subnet — that alone explains “local works, internet fails.” If the default gateway is present but wrong, traffic leaves toward a dead end.
Local Delivery: ip neigh (ARP / Neighbor Table)
When a destination is on your local subnet, your machine needs the target’s MAC address. ip neigh shows that cache.
# Show the neighbor (ARP) table
ip neigh
# Alias
ip n
172.17.0.1 dev eth0 lladdr 02:42:5f:1a:0b:03 REACHABLE
172.17.0.5 dev eth0 INCOMPLETE
Interpreting the states:
REACHABLE— a valid, recently confirmed MAC mapping. Healthy.STALE— cached but not recently verified; usually fine, will be re-checked on use.INCOMPLETE/FAILED— the machine asked “who has this IP?” and got no answer. The host is not responding at layer 2 — it may be down, on a different subnet than you think, or blocked.
🔎 Troubleshooting Tip — When two hosts on the same subnet cannot connect but routing looks correct, check
ip neigh. AnINCOMPLETEentry for the target means the problem is below IP — the peer isn’t answering ARP at all. That points you at a downed host, a wrong subnet assumption, or layer-2 isolation (e.g. a security group / VLAN) rather than anything in your application.
What Is Listening: ss -tulpn
ss (socket statistics, the modern replacement for netstat) answers one of the most important questions in operations: which services are listening, and on which addresses and ports?
# List listening TCP + UDP sockets with process names and port numbers
sudo ss -tulpn
The flags:
-t— TCP sockets.-u— UDP sockets.-l— only listening sockets.-p— show the owning process (needssudoto see other users’ processes).-n— numeric ports and addresses (don’t resolve names — faster and clearer).
Netid State Local Address:Port Peer Address:Port Process
tcp LISTEN 127.0.0.1:5432 0.0.0.0:* users:(("postgres",pid=812,...))
tcp LISTEN 0.0.0.0:80 0.0.0.0:* users:(("nginx",pid=940,...))
The Local Address column is where the real insight lives:
0.0.0.0:80— listening on all interfaces; reachable from the network.127.0.0.1:5432— listening on loopback only; reachable from the local machine but not from other hosts. This single detail explains a huge number of “the database is up but my app on another server times out” incidents.
🛠️ DevOps Perspective —
ss -tulpnis your ground truth for “is the service actually up and bound where I expect?” Before blaming the network, firewall, or DNS, confirm the process is listening on the right address and port. Ifssshows nothing on port 8080, no amount of firewall tweaking will help — the app never bound the port.
🔐 Security Note — Reviewing listening sockets is also a defensive habit: an unexpected process bound to a public
0.0.0.0address is exactly what you want to catch on a server you operate. Auditing your own exposed ports is good hygiene. Only inspect and test systems you own or are explicitly authorized to test.
Reachability and Path: ping and traceroute
ping sends ICMP echo requests to confirm a host is reachable and to measure round-trip latency.
# Send 4 pings and stop (otherwise it runs forever; Ctrl-C to stop)
ping -c 4 1.1.1.1
64 bytes from 1.1.1.1: icmp_seq=1 ttl=57 time=11.9 ms
--- 1.1.1.1 ping statistics ---
4 packets transmitted, 4 received, 0% packet loss
What it tells you: whether basic IP connectivity works, the latency, and whether packets are being lost. Pinging an IP isolates connectivity from DNS; pinging a name additionally tests resolution. A useful trick: if ping 1.1.1.1 succeeds but ping example.com fails, connectivity is fine and your problem is DNS.
💡 Note — Many clouds and hosts deliberately block ICMP, so a failed
pingdoes not always mean the host is down. Treatpingas a positive signal when it works, not proof of failure when it doesn’t — confirm with a TCP-level test likecurlto the actual port.
traceroute maps the hops between you and a destination, showing where latency spikes or where the path dies.
# Trace the route to a host
traceroute example.com
1 172.17.0.1 0.4 ms
2 10.0.0.1 1.2 ms
3 * * *
4 93.184.216.34 12.0 ms
Each line is one router along the path. A run of * * * shows where responses stop — often the edge of your network or a firewall — which helps you tell “the problem is inside my infrastructure” from “the problem is out on the internet.”
Name Resolution: dig and nslookup
DNS deserves special attention because so many “outages” are really resolution problems. dig is the precise, scriptable tool of choice.
# Resolve the A record (IPv4 address) for a name
dig example.com
# Just the answer, no noise
dig +short example.com
# Ask a specific resolver (here, Cloudflare's 1.1.1.1) instead of the system default
dig +short example.com @1.1.1.1
# Look up other record types
dig +short api.example.com CNAME
dig +short example.com MX
What dig tells a DevOps engineer:
- The answer — which IP(s) a name currently resolves to. Compare this against what you expect after a deploy or DNS change.
- Using
@1.1.1.1lets you bypass your local resolver to test whether the problem is your machine’s resolver or the authoritative record itself. - Record types matter: a
CNAMEpointing at a decommissioned host, or anMX/Arecord that changed, are common root causes.
nslookup is the older, more conversational tool — handy and available almost everywhere, including on machines where dig isn’t installed:
# Simple resolution
nslookup example.com
# Query a specific DNS server
nslookup example.com 1.1.1.1
nslookup gives you the resolved address plus which server answered. For deep DNS work, prefer dig; for a quick check on an unfamiliar box, nslookup is fine.
🔎 Troubleshooting Tip — When a name fails, compare
dig +short name @1.1.1.1(a public resolver) withdig +short name(your system resolver). If the public resolver answers correctly but your system one doesn’t, the fault is local — check/etc/resolv.conf, a broken internal resolver, or a caching layer, not the authoritative DNS. For a deeper walkthrough see the DNS troubleshooting lesson.
Talking to the Application: curl and wget
Once you know a host is reachable and its name resolves, you need to confirm the application actually responds. curl is the DevOps Swiss-army knife for exactly this.
# Fetch a URL and print the body
curl https://example.com
# Show only response headers and status (great for a fast health check)
curl -I https://example.com
# Verbose: DNS, TCP connect, TLS handshake, headers — the whole request lifecycle
curl -v https://example.com
# Test a specific host:port directly, bypassing DNS entirely
curl -v http://127.0.0.1:8080/health
Why this is powerful: curl -v narrates every layer of the workflow in one command — it resolves the name, opens the TCP connection, performs the TLS handshake, and shows the HTTP status. Reading that output tells you exactly where a request breaks:
- Fails at “Could not resolve host” → DNS.
- Hangs at “Trying
…” then times out → connectivity / firewall / nothing listening. - Fails during TLS → certificate or TLS problem.
- Returns a
5xx/4xxstatus → the network is fine; the application is the problem.
wget overlaps with curl but shines for downloading files and mirroring:
# Download a file, saving it locally
wget https://example.com/file.tar.gz
# Quietly check that a URL is reachable without saving output
wget -q --spider https://example.com && echo "reachable"
Reach for curl when you are inspecting a request/response (headers, status, TLS, APIs) and wget when you are retrieving files.
🛠️ DevOps Perspective —
curl -vagainst a service’s health endpoint is often the single most efficient troubleshooting command you can run, because it exercises DNS, TCP, TLS, and the application in one shot and tells you which one failed. For deeper HTTP and API debugging — headers, methods, JSON payloads, status codes — continue with the HTTP & API troubleshooting lesson.
DevOps Networking Troubleshooting Workflow
When something can’t connect, resist the urge to guess. Work up the stack in order — each step rules out a whole class of causes so you never chase the wrong layer:
Interface
↓
IP Address
↓
Route
↓
Gateway
↓
DNS
↓
TCP Port
↓
Application
Walk it top to bottom, and stop at the first step that fails — that’s your root cause:
- Interface —
ip link. Is the interfaceUP? If it’sDOWNor missing, nothing else matters. Fix the link first. - IP Address —
ip addr. Does the interface have the address and CIDR you expect? No IP (or a stray169.254.x.xlink-local address) means DHCP failed or config is wrong. - Route —
ip route get <destination>. Does traffic for your target leave the correct interface? On multi-homed or VPN hosts this catches traffic going out the wrong path. - Gateway —
ip routeshows thedefaultgateway;ping <gateway>confirms it answers. If there’s no default route or the gateway is unreachable, off-subnet traffic dies here. - DNS —
dig +short <name>. Does the name resolve to the IP you expect? Compare against a public resolver with@1.1.1.1. If resolution is wrong, fix DNS before touching anything else. - TCP Port —
ss -tulpnlocally (is the service even listening, and on the right address?) andcurl -v telnet-styleornc -vz host portremotely (can you open a connection?). This separates “nothing is listening” from “a firewall is blocking it.” - Application —
curl -v <url>. The connection succeeds but the service returns an error or hangs. The network is exonerated; the problem is the app, its config, or a dependency.
A worked example: your app on web-01 can’t reach the database db-01:5432.
ip link/ip addronweb-01→ interfaceUP, sensible IP. Move on.ip route get <db-01-ip>→ leaves viaeth0as expected. Move on.ping <gateway>→ replies (or the DB is on the same subnet, so skip). Move on.dig +short db-01.internal→ returns10.0.5.9, the address you expect. DNS is fine. Move on.- On
db-01,sudo ss -tulpn | grep 5432→ shows127.0.0.1:5432, not0.0.0.0:5432. Stop — root cause found. PostgreSQL is bound to loopback only, so remote hosts can never connect. Fix the bind address and the incident is resolved — no firewall spelunking required.
That is the entire value of the workflow: it turns “the network is broken” into a specific, provable finding in a few minutes.
🧪 Try It — In your Kali VM (see the installing Kali in a VM lesson if you haven’t set one up), run the whole stack against a benign public target and read each layer’s output:
ip link # is my interface up? ip addr # my IP and CIDR ip route # my default gateway dig +short example.com # DNS resolution ping -c 4 example.com # connectivity + latency curl -I https://example.com # application responds (status line) sudo ss -tulpn # what is listening on THIS machineThen start a tiny local service —
python3 -m http.server 8080— and confirm you can see it appear inss -tulpnand reach it withcurl -v http://127.0.0.1:8080/. You now have the full workflow in your hands. Only run scans or probes against systems you own or are explicitly authorized to test.
Where to Go Next
You now have the fundamentals to inspect a network. The next lessons build directly on this foundation:
- Discovering what’s on a network — map hosts and open ports with Nmap for DevOps (always against your own lab or authorized infrastructure).
- Seeing the actual packets — when higher-level tools aren’t enough, capture and read traffic with tcpdump for DevOps.
- Going deeper on names — the dedicated DNS troubleshooting lesson.
- Debugging services end to end — HTTP & API troubleshooting for status codes, headers, and payloads.
If your day job leans heavily on containers, the same interface, route, and port concepts reappear inside Docker networking — the Docker Academy is a good companion once you’re comfortable here.
What You Learned
- The layered model that matters operationally — interface → IP/CIDR → route → gateway → DNS → port → application — and how each layer maps to a specific concept and command.
- The modern
iproute2toolkit —ip addrandip linkto read interfaces and links,ip routeto inspect routes and the default gateway, andip neighto check local (ARP) delivery. ss -tulpnto see exactly which services are listening and, critically, on which address — the difference between0.0.0.0and127.0.0.1is behind countless connectivity incidents.- The right tool per question —
ping/traceroutefor reachability and path,dig/nslookupfor DNS (and how to test against a public resolver), andcurl/wgetto confirm the application itself responds. - A repeatable troubleshooting workflow that walks up the stack, stops at the first failing layer, and turns vague “the network is broken” reports into specific, provable root causes.
Recommended Reading
- View Book on Amazon Affiliate link
Learning Kali Linux
A hands-on introduction to the Kali Linux toolset for security testing.
- View Book on Amazon Affiliate link
The Ultimate Kali Linux Book
A broad, beginner-friendly walkthrough of Kali Linux and its core toolset.
Affiliate Disclosure: Some links on this page are affiliate links. If you purchase through one of these links, DevOps AI Toolkit may earn a commission at no additional cost to you. See our affiliate disclosure.
← Back to Kali Linux for DevOps Engineers