Skip to content
Networking
Lab 7 of 7·30mChallengeIntermediate

Challenge: it pings but it cannot resolve

A host reaches addresses and not names, and a service on it is unreachable from outside. Two independent faults, diagnosed in the right order.

You need

  • A Linux VM with sudo access
  • netcat (apt-get install -y netcat-openbsd)

Do first

Everything you need is in labs 1 to 6. The discipline being tested is working _up_ the stack instead of guessing: addresses, then routes, then names, then ports.

Set up the scenario

Run this exactly as written. It saves what it breaks so cleanup restores you.

sudo cp /etc/resolv.conf /root/resolv.conf.lab-backup
sudo mkdir -p /srv/lab
sudo tee /srv/lab/serve.sh >/dev/null <<'SCRIPT'
#!/bin/bash
while true; do
  printf 'HTTP/1.1 200 OK\r\nContent-Length: 3\r\n\r\nok\n' \
    | nc -l 127.0.0.1 8088 >/dev/null 2>&1
done
SCRIPT
sudo chmod 755 /srv/lab/serve.sh
sudo bash -c 'nohup /srv/lab/serve.sh >/dev/null 2>&1 &'
printf 'nameserver 203.0.113.53\noptions timeout:1 attempts:1\n' \
  | sudo tee /etc/resolv.conf >/dev/null
echo "scenario ready"

The situation

Two complaints have come in.

One: the box cannot resolve anything.

ping -c1 -W2 1.1.1.1; echo "ping by address: exit=$?"
getent hosts example.com; echo "resolve a name: exit=$?"

Two: a colleague says the service on port 8088 is unreachable from their machine, though you can see it running.

curl -s -m 3 http://127.0.0.1:8088; echo "from this box: exit=$?"

Your goal

  1. Say which layer each fault is at, before changing anything. Addresses, routes, names, or ports?
  2. Make getent hosts example.com return a public address.
  3. Make the service on 8088 reachable from another host on the network — without changing any firewall rule, because the firewall is not the problem.
  4. Prove #3 from the machine's own non-loopback address, not from 127.0.0.1.

Constraints

  • Do not edit /srv/lab/serve.sh beyond the one thing that is wrong with it.
  • Do not disable or flush any firewall. If your fix involves iptables -F, it is the wrong fix.
  • For #2, find out why the resolver fails rather than pasting a nameserver in and moving on. Name the specific evidence.
  • Fault one and fault two are unrelated. Fixing either does not affect the other.

Hints, in increasing order of spoiler

  • Lab 1's four questions, in order. ping 1.1.1.1 already told you addresses and routes are fine, so start below names.
  • dig @1.1.1.1 example.com versus plain dig example.com separates "DNS is broken" from "my resolver is broken". One of those two works here.
  • 203.0.113.0/24 is reserved by RFC 5737 for documentation. Nothing there answers, ever. So the resolver is configured to ask a server that cannot exist.
  • Fault two is not DNS, not routing, and not the firewall. Re-read the nc invocation in the script and compare it to lab 4's table of bind addresses.
  • ss -tlnp 'sport = :8088' shows the Local Address column. Compare what it says to what a remote client would need it to say.

What success looks like

Verify

getent hosts example.com | awk '{print $1}' # a public address, not empty

Verify

MYIP=$(ip route get 1.1.1.1 | grep -oP 'src \K\S+') sudo ss -tln 'sport = :8088' | tail -n +2 # a LISTEN row on 0.0.0.0:8088 or on $MYIP:8088, not 127.0.0.1:8088

Verify

MYIP=$(ip route get 1.1.1.1 | grep -oP 'src \K\S+') nc -z -w2 "$MYIP" 8088; echo "reachable on the real address: exit=$?" # exit=0

Clean up

sudo pkill -f "/srv/lab/serve.sh" 2>/dev/null
sudo pkill -f "nc -l" 2>/dev/null
sudo cp /root/resolv.conf.lab-backup /etc/resolv.conf
sudo rm -f /root/resolv.conf.lab-backup
sudo rm -rf /srv/lab
getent hosts example.com | awk '{print $1}'

If your system uses systemd-resolved, /etc/resolv.conf is normally a symlink that the copy above replaced with a regular file. Restore it with:

sudo ln -sf ../run/systemd/resolve/stub-resolv.conf /etc/resolv.conf
resolvectl status | head -n 5

Where this goes next

Addresses, prefixes, names, ports, routes, NAT and TLS — that is the vocabulary every cloud console assumes. The Cloud Engineering track uses all of it from the CLI, and Security starts from the same primitives.