Gendi Notes

Networking Basics

Every "it can't connect" problem is one of four things: wrong address, wrong port, a firewall, or nothing listening.

Level 1 guide networkingtcpipports

What is it?#

Networking is how one machine reaches another. To make a connection you need exactly two pieces of information:

  • an IP address — which machine
  • a port — which program on that machine

Together they form a socket: 10.0.1.5:5432 means "the program listening on port 5432 of the machine at 10.0.1.5".

Why the layers exist#

Rather than one enormous protocol, networking is split into layers, each solving one problem and trusting the layer below.

your app (HTTP: "GET /users") │ ↓ needs a reliable ordered stream TCP (ports, retransmission, ordering) │ ↓ needs to find the machine IP (addresses, routing between networks) │ ↓ needs to reach the next hop Ethernet / WiFi (MAC addresses, one physical link)

The value of the split: your app never thinks about cables, and IP never thinks about retransmitting lost data. When you debug, you work down this stack — and each layer you rule out eliminates a whole class of cause.

What it is made of#

IP addresses and subnets#

An IPv4 address is four numbers, 0–255 each: 10.0.1.5.

Some ranges are private — usable inside your own network, never routable on the internet:

RangeWritten asWhere you meet it
10.0.0.0–10.255.255.25510.0.0.0/8Cloud VPCs, Kubernetes pods
172.16.0.0–172.31.255.255172.16.0.0/12Docker's default bridge
192.168.0.0–192.168.255.255192.168.0.0/16Home routers
127.0.0.1127.0.0.0/8Loopback — this machine only

The /8 and /24 suffix is CIDR notation: how many leading bits are fixed as the network, leaving the rest for hosts.

10.0.1.0/24 └────┬───┘ └┬┘ │ └── 24 bits fixed → 8 bits left → 256 addresses │ usable range 10.0.1.1 – 10.0.1.254 │ (.0 is the network, .255 the broadcast) └───────── the network part /24 → 256 addresses /16 → 65,536 /28 → 16 /8 → 16.7 million Rule of thumb: bigger number = smaller network.

Ports#

Ports separate programs on one machine. The ones worth memorising:

PortService
22SSH
53DNS
80HTTP
443HTTPS
3306MySQL
5432PostgreSQL
6379Redis
27017MongoDB

Ports below 1024 require root to bind. This is why a container listening on 80 often runs its app on 8080 internally and maps the port instead.

TCP versus UDP#

TCPUDP
GuaranteesOrdered, no loss, no duplicatesNone
Setup3-way handshake firstJust send
SpeedSlowerFaster
Used byHTTP, SSH, databasesDNS, video, metrics

TCP is a phone call: you connect, confirm the other side can hear you, then talk. UDP is a postcard: you send it and hope.

The TCP handshake#

Worth knowing because it explains what "connection refused" means:

client server │ ── SYN ────────────────────→ │ "can we talk?" │ ←──────────── SYN-ACK ────── │ "yes, can you hear me?" │ ── ACK ────────────────────→ │ "yes" connected — data can now flow

Three messages, because two cannot prove both directions work.

How to use it#

Is it listening?#

On the server itself
# -l listening  -n numeric (no DNS lookups)  -t TCP  -p which process
sudo ss -lntp

# Is anything on port 5432 specifically?
sudo ss -lntp | grep 5432

Look at the Local Address column carefully:

Shown asMeans
0.0.0.0:5432Listening on all interfaces — reachable from outside
127.0.0.1:5432Loopback only — nothing outside the machine can connect
[::]:5432All interfaces, IPv6

Can I reach it?#

Work through these in order — each one rules out a layer.

# 1. Does the name resolve? (rules out DNS)
getent hosts api.example.com

# 2. Does the machine respond at all? (rules out routing)
#    Note: many cloud hosts block ICMP, so a failed ping is not proof of a problem.
ping -c 3 10.0.1.5

# 3. Is the PORT open? This is the important one.
#    -z scan only, -v verbose, -w timeout in seconds
nc -zv 10.0.1.5 5432

# 4. Does the application actually answer?
curl -v https://api.example.com/health

Reading the result of step 3 is most of the skill:

ResultMeaningNext step
succeeded / openSomething is listening and reachableProblem is in the app or the protocol
Connection refusedReached the machine, nothing listening on that portStart the service, or check the port
Timeout / hangsPackets are being dropped — a firewallCheck firewall rules and cloud security groups

Which route does traffic take?#

ip addr              # this machine's addresses (replaces ifconfig)
ip route             # the routing table. "default via ..." is your gateway
traceroute 8.8.8.8   # each hop along the way
mtr 8.8.8.8          # traceroute + live loss stats. Better for intermittent issues

Reading curl -v#

curl -v https://api.example.com/health
Line in the outputTells you
Trying 10.0.1.5:443...DNS resolved — to this address
Connected to ...TCP succeeded. Address and port are correct
TLS handshake / certificate linesHTTPS negotiation; cert problems appear here
> GET /healthWhat was sent
< HTTP/1.1 200The status the server returned

If it stops after "Trying", it is a firewall. If it stops at TLS, it is a certificate. If you get a 5xx, the network is fine and the application is not.

Firewalls: two layers on any cloud VM#

This catches almost everyone once.

internet │ ↓ ① CLOUD firewall ← AWS security group / Azure NSG / OCI security list │ configured in the web console, NOT over SSH ↓ ② HOST firewall ← ufw or iptables, on the machine itself │ ↓ ③ the service ← and it must be bound to 0.0.0.0, not 127.0.0.1

All three must allow the traffic. Opening only the host firewall and wondering why the port is still closed is the single most common cloud networking mistake.

sudo ufw status                       # if ufw is installed
sudo iptables -L INPUT -n --line-numbers   # if it is not

Interview corner · الأسئلة اللي بتتسأل#

"The service is unreachable." Walk me through it. · «السيرفيس مش بيرد»

This is the most common troubleshooting question in DevOps interviews, and the answer is a method, not a tool list. Narrow it one layer at a time, out loud:

# 1. Does the name resolve, and to what?      (rules out DNS)
getent hosts api.example.com

# 2. Is the PORT open?                        (rules out firewall vs service)
nc -zv 10.0.1.5 5432

# 3. On the server: is anything listening, and on which interface?
sudo ss -lntp | grep 5432

# 4. Does the application answer?             (rules out app vs network)
curl -v https://api.example.com/health

Then read step 2's result, because it splits the problem in half:

ResultEliminatedRemaining
refusedFirewall, routing, DNS — the machine repliedService down, wrong port, or bound to 127.0.0.1
timeoutNothing — you got silenceFirewall: cloud security group, or host ufw
succeededThe whole network stackThe application or the protocol above it
A large file transfer hangs at exactly the same point every time, but small requests work fine. What is it?

Almost certainly MTU / path MTU discovery, and this question exists to find people who have debugged real networks.

Small packets fit anywhere. Once a packet exceeds the smallest MTU on the path, the router must either fragment it or reply ICMP fragmentation needed. If a firewall blocks that ICMP message, the sender never learns and just retransmits the too-large packet forever — a PMTUD black hole.

client (MTU 1500) ──→ router (MTU 1400) ──→ server │ │ │ small packet │ fits, fine │ 1500-byte packet │ too big │ │ │ ←── ICMP "frag needed, use 1400" │ ✘ BLOCKED by a firewall │ └── never learns. retransmits 1500 forever. hangs.
# Find the real path MTU: -M do = do not fragment, -s = payload size
ping -M do -s 1472 8.8.8.8      # 1472 + 28 header = 1500
ping -M do -s 1372 8.8.8.8      # try lower until it succeeds

Where it bites in practice: VPNs and tunnels (WireGuard, IPsec) and overlay networks — including several Kubernetes CNIs, which encapsulate packets and so reduce the usable MTU. The signature is always the same: handshakes and small responses fine, large payloads hang.

Why does a TCP connection need three messages and not two?

Because two messages can only prove one direction works.

client server │ ── SYN ────────────────────→ │ "can you hear me?" │ ←──────────── SYN-ACK ────── │ "yes — can you hear me?" │ ── ACK ────────────────────→ │ "yes" both directions now proven

After SYN → SYN-ACK, the client knows both directions work — it sent and it received. But the server has only proved that its own send worked; it has no evidence the client received anything. The third message supplies that. Each side also uses the exchange to communicate its initial sequence number, which is what makes ordering and retransmission possible at all.

Key takeaways#

  • A connection is address + port. Get either wrong and nothing works.
  • Refused = nothing listening. Timeout = firewall. Opposite problems.
  • ss -lntp answers "is it listening, and on which interface?" — and 127.0.0.1 there means local-only.
  • In containers, bind to 0.0.0.0, never 127.0.0.1.
  • On a cloud VM there are two firewalls. The cloud one is not editable over SSH.
  • Debug downward: name → route → port → application. Each step eliminates a layer.
  • Large transfers hanging while small ones work is MTU, not bandwidth.

Last updated 2026-09-08