Network › Module 4 › Lesson 4
Lab — Public vs App Listener on Loopback
Start (public) and (app) — never 0.0.0.0, never WAN DMZ.
Visual · dmz_two_listeners_lab
Two listeners, both loopback: public 8783, app 8793. http://192.168.0.1/ YOUR lab.
Opening
If both toys answer, you can finally point at a porch and a kitchen on the same computer.
Start two HTTP processes. Public greets as zone=public on and does not print dummy secrets. App greets as zone=app on You curl public, then app, then grep bodies. That is a DMZ cartoon without a datacenter rack. Original Cyberlium.
1. Write two servers, one HOST, two ports
Same bind discipline as segmentation: HOST = 127.0.0.1 or do not run it. Public port 8783, app port 8793. first; router still means STOP on the gateway.
If 8783 is already a teaching server you own, you may reuse it as public and only start 8793 — still no LAN hunt for free ports.
Command guide
Write two servers, one HOST, two ports
═══ INSTALL ═══
Linux (Debian/Ubuntu):
Command — copy this
sudo apt install python3
macOS:
Command — copy this
brew install python3
Windows: Download https://python.org/downloads/
═══ COMMANDS ═══
Command — copy this
cat > "$HOME/cyberlium-lab/t11-m04-dmz-toy.py" << 'PY'
from http.server import BaseHTTPRequestHandler, ThreadingHTTPServer
import threading
HOST = "127.0.0.1"
if HOST != "127.0.0.1":
raise SystemExit("refusing non-loopback bind")
def make(port, zone):
class H(BaseHTTPRequestHandler):
def do_GET(self):
if zone == "public" and "secret" in self.path:
body = b"public refuses secret paths
"
else:
body = ("zone=%s port=%s bind=127.0.0.1
" % (zone, port)).encode()
self.send_response(200); self.end_headers(); self.wfile.write(body)
def log_message(self, fmt, *args):
pass
return ThreadingHTTPServer((HOST, port), H)
pub, app = make(8783, "public"), make(8793, "app")
threading.Thread(target=pub.serve_forever, daemon=True).start()
print("listening", HOST, 8783, 8793, flush=True)
app.serve_forever()
PYCommand — copy this
if [ -f "$HOME/cyberlium-lab/t11-m04-dmz-toy.pid" ]; then kill "$(cat "$HOME/cyberlium-lab/t11-m04-dmz-toy.pid")" || true; fi python3 "$HOME/cyberlium-lab/t11-m04-dmz-toy.py" & sleep 1
2. Curl public, curl app, prove they are different rooms
Bodies should disagree on zone=. Public /secret path should refuse, not dump t11-m04-app-secret.note. App may say zone=app. If both bodies are identical and unnamed, you started one process twice or curled one dest twice — fix YOUR curls, do not nmap.
Stay on 127.0.0.1. No DEMO repeat. No phone-on-Wi-Fi.
Command guide
Curl public, curl app, prove they are different rooms
═══ INSTALL ═══
Linux (Debian/Ubuntu):
Command — copy this
sudo apt install curl
macOS: Built-in
Windows: Built-in (PowerShell: Invoke-WebRequest)
═══ COMMANDS ═══
Command — copy this
curl -sS -m 2 "http://127.0.0.1:8783/" | tee "$HOME/cyberlium-lab/t11-m04-lab-public.body" curl -sS -m 2 "http://127.0.0.1:8793/" | tee "$HOME/cyberlium-lab/t11-m04-lab-app.body" curl -sS -m 2 "http://127.0.0.1:8783/secret" | tee "$HOME/cyberlium-lab/t11-m04-lab-public-secret.body" grep "zone=" "$HOME/cyberlium-lab/t11-m04-lab-public.body" "$HOME/cyberlium-lab/t11-m04-lab-app.body"
3. Bind audit, never-list reminder, stop YOUR pid
grep the toy for 127.0.0.1 and ensure 0.0.0.0 is absent. Re-read t11-m04-never.txt. Kill the pid you started. That is a complete beginner DMZ lab — not a WAN experiment.
If a guide says forward 8783 on the home router so classmates can hit your public toy, refuse. They run their own loopback pair.
Command guide
Bind audit, never-list reminder, stop YOUR pid
═══ INSTALL ═══
Linux (Debian/Ubuntu): Built-in (binutils)
macOS: Built-in
Windows: Use WSL or install binutils
═══ COMMANDS ═══
Command — copy this
grep -n "127.0.0.1" "$HOME/cyberlium-lab/t11-m04-dmz-toy.py" grep -n "0.0.0.0" "$HOME/cyberlium-lab/t11-m04-dmz-toy.py" && echo "FAIL" grep "never_on_public" "$HOME/cyberlium-lab/t11-m04-never.txt" kill "$(cat "$HOME/cyberlium-lab/t11-m04-dmz-toy.pid")"
4. What you ship: two answering dests, a refuse-on-public-secret path, a bind audit
8783 public and 8793 app on 127.0.0.1. Distinct zone= bodies. /secret on public does not dump app secrets. DEMO GATE. Pid stopped. No WAN DMZ. No 0.0.0.0.
5. What you record before the next lesson
Date. DMZ lab dests. Bind audit. DEMO identified/STOP. NEVER nmap/hydra/0.0.0.0/WAN DMZ. File t11-m04-l04-dmz-lab.txt chmod 600.
6. Wrong vs right: stranger networks vs literacy on systems you own
Worked failure — same network word, opposite target. Right never needs a café or campus LAN.
Wrong
Port-forward 8783 on the home router. Bind app to 0.0.0.0. nmap WAN to “see the DMZ from outside.”
Right
Two loopback listeners, two curls, bind audit. Next: Quiz — DMZ.
Mission: run porch and kitchen on loopback only
1) / STOP if router. 2) Start public and app. 3) Curl both plus /secret on public. 4) Bind audit, stop YOUR pid. Never WAN DMZ. Never 0.0.0.0.
Stuck? Ask Cyberlium AI Mentor
Ask Mentor how to tell two HTTP toys apart by body — not how to hairpin NAT a home gateway.
Knowledge Check
APPLY: Classmates cannot hit your 8783 from their laptops. Lab status?
Multiple choice
Knowledge Check
APPLY: True or False: Both DMZ lab listeners bind 127.0.0.1 (8783 public, 8793 app).
True or False
Knowledge Check
APPLY: curl http://192.168.0.1/ is Router Admin in the DMZ lab. You:
Multiple choice