Cyberlium

Network › Module 8 › Lesson 4

BeginnerModule 8Lesson 4/5

Lab — Rate-Limit YOUR Loopback Server

Lab: Python limiter on and a few curls — never hping3, never flood others or the LAN.

25 min+40 XP3 quiz
Module progress4 of 5

Visual · loopback_ratelimit_lab

Hands-on 429 on YOUR loopback. A few curls of YOUR server only. Original Cyberlium.

Opening

Start YOUR limiter. Ask it politely a handful of times. Stop when you have seen 200 and 429.

You will run a tiny Python HTTP server bound to with a 4-hits-per-5-seconds style limiter. You will curl it a few times. If you see 429, the lab worked. You will not install hping3, not flood the LAN, not aim at 192.168.0.1, not bind 0.0.0.0, not recruit friends to “make it distributed.” Original Cyberlium.

1. Write a limiter that refuses any non-loopback bind

Copy the teaching helper into cyberlium-lab as a file you own. The first if-statement should kill the process if HOST is not 127.0.0.1. That is part of the grade culturally, even if no autograder exists.

Window and max hits should match yesterday's budget file unless you documented a change.

Command guide

Write a limiter that refuses any non-loopback bind

═══ 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

python3 - << 'PY'
from pathlib import Path
p = Path.home() / "cyberlium-lab" / "t11_m08_limiter.py"
p.write_text(r'''
from http.server import BaseHTTPRequestHandler, ThreadingHTTPServer
import threading, time
HOST, PORT, WINDOW, MAX_HITS = "127.0.0.1", 8787, 5.0, 4
lock = threading.Lock(); hits = []
class H(BaseHTTPRequestHandler):
  def do_GET(self):
      now = time.time()
      with lock:
          hits[:] = [t for t in hits if now - t < WINDOW]
          if len(hits) >= MAX_HITS:
              body = b"429 from YOUR loopback limiter
"
              self.send_response(429); self.send_header("Content-Length", str(len(body))); self.end_headers(); self.wfile.write(body); return
          hits.append(now)
      body = b"200 ok from 127.0.0.1:8787
"
      self.send_response(200); self.send_header("Content-Length", str(len(body))); self.end_headers(); self.wfile.write(body)
  def log_message(self, *a):
      pass
if HOST != "127.0.0.1":
  raise SystemExit("refusing non-loopback bind")
print("serving", HOST, PORT)
ThreadingHTTPServer((HOST, PORT), H).serve_forever()
''', encoding="utf-8")
print("wrote", p)
print("run in another terminal: python3", p)
PY

2. A few curls, then stop

After the helper is listening, send a handful of curl requests to http:///. Record status lines. You are done when you have seen the limiter say no. You are not done when the fan spins.

Do not wrap curl in an infinite while-true. Do not add -w in a 10,000-iteration script. Do not point the same script at any other IP.

Command guide

A few curls, then stop

═══ 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 -o /dev/null -w "1 %{http_code}
" "$SAFE/"
curl -sS -m 2 -o /dev/null -w "2 %{http_code}
" "$SAFE/"
curl -sS -m 2 -o /dev/null -w "3 %{http_code}
" "$SAFE/"
curl -sS -m 2 -o /dev/null -w "4 %{http_code}
" "$SAFE/"
curl -sS -m 2 -o /dev/null -w "5 %{http_code}
" "$SAFE/"

3. Evidence file, then power down the toy

Write which status codes you saw. chmod 600. Stop the Python process. Leaving a limiter running is fine only on loopback; still do not advertise it.

If you never saw 429, check you actually hit the helper, not a different app on 8787. Do not “debug” by flooding other hosts.

Command guide

Evidence file, then power down the toy

═══ 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

python3 -c "import socket;s=socket.socket();s.settimeout(0.3);print('8787',s.connect_ex(('127.0.0.1',8787)));s.close()"

4. What you ship: limiter file, a few status codes, a stopped flood temptation

t11_m08_limiter.py binds A few curls. 429 observed or an honest miss. No hping3. No LAN. No 0.0.0.0. DEMO GATE holds.

5. What you record before the next lesson

Lab note with codes. Limiter path. SAFE NEVER flood others. Next: Quiz — Availability Attacks.

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

    hping3 -S --flood 127.0.0.1 anyway “for science” then rotate to the LAN. while true; curl a classmate. python --bind 0.0.0.0.

  • Right

    Few curls to YOUR limiter. Record 200/429. Stop. Next: Quiz — Availability Attacks.

Mission: 429 YOUR loopback, then stop

1) / STOP if router. 2) Run the limiter on only. 3) A few curls; record statuses. Never hping3. Never flood others or the LAN. Never bind 0.0.0.0.

Stuck? Ask Cyberlium AI Mentor

If every curl is 000, ask Mentor whether the helper is actually bound to — not whether hping3 would “be more reliable.”

Knowledge Check

1

APPLY: After four 200s, curl five to YOUR limiter returns 429. You:

Multiple choice

Knowledge Check

2

APPLY: True or False: hping3 flood against a classmate is allowed if you also ran the loopback lab.

True or False

Knowledge Check

3

APPLY: The limiter must bind:

Multiple choice

← Previous

Answer all 3 knowledge checks to continue. (0/3 answered)