Add lab-01-trace-request
This commit is contained in:
1 parent
576d56d39b
commit
101095d35a
6 files changed
+285
No files matched your search
@@ -0,0 +1,23 @@
|
|||||||
|
# Lab 1: Trace the Request
|
||||||
|
|
||||||
|
## What I practiced
|
||||||
|
|
||||||
|
In this lab, I worked with a simple virtual Linux network and used networking tools to examine:
|
||||||
|
|
||||||
|
- name resolution,
|
||||||
|
- route selection,
|
||||||
|
- next-hop addressing,
|
||||||
|
- outgoing interface and source addressing,
|
||||||
|
- and neighbor information.
|
||||||
|
|
||||||
|
## Request trace
|
||||||
|
|
||||||
|
In one or two sentences, explain how the client moves from `web.minicorp.test` to its next-hop device.
|
||||||
|
|
||||||
|
> Replace this line with your explanation.
|
||||||
|
|
||||||
|
## Key takeaway
|
||||||
|
|
||||||
|
Explain why the client needs both an IP address and a link-layer address when sending traffic to the next hop.
|
||||||
|
|
||||||
|
> Replace this line with your explanation.
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
# Lab 1 Scenario
|
||||||
|
|
||||||
|
This directory contains the Lab 1-specific services and configuration for MiniCorp.
|
||||||
|
|
||||||
|
The reusable Linux network topology is provided by:
|
||||||
|
|
||||||
|
```text
|
||||||
|
shared/minicorp/
|
||||||
|
```
|
||||||
|
|
||||||
|
Lab 1 uses a three-system virtual network:
|
||||||
|
|
||||||
|
```text
|
||||||
|
client -------- router -------- server
|
||||||
|
```
|
||||||
|
|
||||||
|
The router provides DNS for the MiniCorp web service, and the server provides a simple HTTP service.
|
||||||
|
|
||||||
|
Lab 1 intentionally keeps the application simple. Students investigate name resolution, routing, and neighbor information from the client's point of view.
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
# Lab 1: Trace the Request
|
||||||
|
# Scenario-specific configuration.
|
||||||
|
#
|
||||||
|
# Reusable network topology and addressing are provided by shared/minicorp.
|
||||||
|
|
||||||
|
LAB_ID="lab-01-trace-request"
|
||||||
|
LAB_NAME="Trace the Request"
|
||||||
|
|
||||||
|
# MiniCorp topology used by this scenario.
|
||||||
|
LAB_TOPOLOGY="client-router-server"
|
||||||
|
|
||||||
|
# Web service.
|
||||||
|
LAB_WEB_HOSTNAME="web.minicorp.test"
|
||||||
|
LAB_WEB_PORT="8080"
|
||||||
|
LAB_WEB_STDOUT="/tmp/minicorp-lab1-web.stdout"
|
||||||
|
|
||||||
|
# DNS service.
|
||||||
|
LAB_DNS_STDOUT="/tmp/minicorp-lab1-dns.stdout"
|
||||||
|
|
||||||
|
# Namespace-specific resolver configuration.
|
||||||
|
LAB_CLIENT_RESOLV_DIR="/etc/netns/client"
|
||||||
|
LAB_CLIENT_RESOLV_CONF="/etc/netns/client/resolv.conf"
|
||||||
Executable
+29
@@ -0,0 +1,29 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
|
LAB_DIR="$(cd "$SCRIPT_DIR/.." && pwd)"
|
||||||
|
REPO_ROOT="$(cd "$LAB_DIR/../.." && pwd)"
|
||||||
|
|
||||||
|
source "$SCRIPT_DIR/config.sh"
|
||||||
|
source "$REPO_ROOT/shared/minicorp/lib/minicorp.sh"
|
||||||
|
source "$REPO_ROOT/shared/minicorp/topologies/client-router-server.sh"
|
||||||
|
|
||||||
|
printf '\n'
|
||||||
|
mc_log "Resetting $LAB_NAME"
|
||||||
|
|
||||||
|
# Stop services and remove the MiniCorp network namespaces.
|
||||||
|
mc_topology_client_router_server_down
|
||||||
|
|
||||||
|
# Remove the namespace-specific resolver configuration.
|
||||||
|
sudo rm -f "$LAB_CLIENT_RESOLV_CONF"
|
||||||
|
sudo rmdir "$LAB_CLIENT_RESOLV_DIR" 2>/dev/null || true
|
||||||
|
|
||||||
|
# Remove temporary service output.
|
||||||
|
sudo rm -f \
|
||||||
|
"$LAB_WEB_STDOUT" \
|
||||||
|
"$LAB_DNS_STDOUT"
|
||||||
|
|
||||||
|
printf '\n'
|
||||||
|
mc_log "$LAB_NAME has been reset."
|
||||||
Executable
+149
@@ -0,0 +1,149 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
|
LAB_DIR="$(cd "$SCRIPT_DIR/.." && pwd)"
|
||||||
|
REPO_ROOT="$(cd "$LAB_DIR/../.." && pwd)"
|
||||||
|
|
||||||
|
source "$SCRIPT_DIR/config.sh"
|
||||||
|
source "$REPO_ROOT/shared/minicorp/lib/minicorp.sh"
|
||||||
|
source "$REPO_ROOT/shared/minicorp/topologies/client-router-server.sh"
|
||||||
|
|
||||||
|
printf '\n'
|
||||||
|
mc_log "Setting up $LAB_NAME"
|
||||||
|
|
||||||
|
if [[ "$LAB_TOPOLOGY" != "client-router-server" ]]; then
|
||||||
|
mc_error "Unsupported topology: $LAB_TOPOLOGY"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Verify the tools required by this lab.
|
||||||
|
for command_name in python3 dnsmasq ss curl getent dig; do
|
||||||
|
mc_require_command "$command_name"
|
||||||
|
done
|
||||||
|
|
||||||
|
# Build the MiniCorp network from a known state.
|
||||||
|
# Suppress topology details so setup does not reveal investigation answers.
|
||||||
|
mc_log "Building MiniCorp virtual network"
|
||||||
|
mc_topology_client_router_server_up >/dev/null
|
||||||
|
|
||||||
|
# Verify the topology without exposing the investigation answers.
|
||||||
|
if ! mc_topology_client_router_server_check >/dev/null; then
|
||||||
|
mc_error "MiniCorp topology validation failed."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Remove stale service output from a previous run.
|
||||||
|
sudo rm -f \
|
||||||
|
"$LAB_WEB_STDOUT" \
|
||||||
|
"$LAB_DNS_STDOUT"
|
||||||
|
|
||||||
|
#
|
||||||
|
# Web service
|
||||||
|
#
|
||||||
|
|
||||||
|
mc_log "Starting MiniCorp web service"
|
||||||
|
|
||||||
|
sudo ip netns exec "$MC_SERVER_NS" env \
|
||||||
|
MINICORP_WEB_HOST="$MC_SERVER_ADDR" \
|
||||||
|
MINICORP_WEB_PORT="$LAB_WEB_PORT" \
|
||||||
|
python3 -u "$SCRIPT_DIR/web_server.py" \
|
||||||
|
>"$LAB_WEB_STDOUT" 2>&1 &
|
||||||
|
|
||||||
|
web_ready=0
|
||||||
|
|
||||||
|
for attempt in {1..20}; do
|
||||||
|
if mc_exec "$MC_SERVER_NS" ss -ltn |
|
||||||
|
grep -F "$MC_SERVER_ADDR:$LAB_WEB_PORT" >/dev/null
|
||||||
|
then
|
||||||
|
web_ready=1
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
|
||||||
|
sleep 0.1
|
||||||
|
done
|
||||||
|
|
||||||
|
if [[ "$web_ready" -ne 1 ]]; then
|
||||||
|
mc_error "Web service failed to start."
|
||||||
|
|
||||||
|
if [[ -f "$LAB_WEB_STDOUT" ]]; then
|
||||||
|
cat "$LAB_WEB_STDOUT" >&2
|
||||||
|
fi
|
||||||
|
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
#
|
||||||
|
# DNS service
|
||||||
|
#
|
||||||
|
|
||||||
|
mc_log "Starting MiniCorp DNS service"
|
||||||
|
|
||||||
|
sudo ip netns exec "$MC_ROUTER_NS" dnsmasq \
|
||||||
|
--no-daemon \
|
||||||
|
--interface="$MC_ROUTER_CLIENT_IF" \
|
||||||
|
--listen-address="$MC_ROUTER_CLIENT_ADDR" \
|
||||||
|
--bind-interfaces \
|
||||||
|
--no-resolv \
|
||||||
|
--no-hosts \
|
||||||
|
--local=/minicorp.test/ \
|
||||||
|
--host-record="$LAB_WEB_HOSTNAME,$MC_SERVER_ADDR" \
|
||||||
|
--log-facility=- \
|
||||||
|
>"$LAB_DNS_STDOUT" 2>&1 &
|
||||||
|
|
||||||
|
dns_ready=0
|
||||||
|
|
||||||
|
for attempt in {1..20}; do
|
||||||
|
if mc_exec "$MC_ROUTER_NS" ss -lun |
|
||||||
|
grep -F "$MC_ROUTER_CLIENT_ADDR:53" >/dev/null
|
||||||
|
then
|
||||||
|
dns_ready=1
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
|
||||||
|
sleep 0.1
|
||||||
|
done
|
||||||
|
|
||||||
|
if [[ "$dns_ready" -ne 1 ]]; then
|
||||||
|
mc_error "DNS service failed to start."
|
||||||
|
|
||||||
|
if [[ -f "$LAB_DNS_STDOUT" ]]; then
|
||||||
|
cat "$LAB_DNS_STDOUT" >&2
|
||||||
|
fi
|
||||||
|
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
#
|
||||||
|
# Client resolver
|
||||||
|
#
|
||||||
|
|
||||||
|
mc_log "Configuring client DNS resolver"
|
||||||
|
|
||||||
|
sudo mkdir -p "$LAB_CLIENT_RESOLV_DIR"
|
||||||
|
|
||||||
|
printf 'nameserver %s\n' "$MC_ROUTER_CLIENT_ADDR" |
|
||||||
|
sudo tee "$LAB_CLIENT_RESOLV_CONF" >/dev/null
|
||||||
|
|
||||||
|
#
|
||||||
|
# Final health check
|
||||||
|
#
|
||||||
|
|
||||||
|
if ! mc_exec "$MC_CLIENT_NS" \
|
||||||
|
getent ahostsv4 "$LAB_WEB_HOSTNAME" >/dev/null
|
||||||
|
then
|
||||||
|
mc_error "Client name resolution check failed."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if ! mc_exec "$MC_CLIENT_NS" \
|
||||||
|
curl --noproxy '*' -fsS \
|
||||||
|
"http://$LAB_WEB_HOSTNAME:$LAB_WEB_PORT/" >/dev/null
|
||||||
|
then
|
||||||
|
mc_error "Client web request check failed."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
printf '\n'
|
||||||
|
mc_log "$LAB_NAME is ready."
|
||||||
Executable
+41
@@ -0,0 +1,41 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
import os
|
||||||
|
from http.server import BaseHTTPRequestHandler, ThreadingHTTPServer
|
||||||
|
|
||||||
|
HOST = os.environ.get("MINICORP_WEB_HOST", "10.53.2.20")
|
||||||
|
PORT = int(os.environ.get("MINICORP_WEB_PORT", "8080"))
|
||||||
|
|
||||||
|
|
||||||
|
class MiniCorpHandler(BaseHTTPRequestHandler):
|
||||||
|
def do_GET(self):
|
||||||
|
if self.path == "/":
|
||||||
|
body = (
|
||||||
|
"MiniCorp web service\n"
|
||||||
|
"Service: web.minicorp.test\n"
|
||||||
|
"Status: healthy\n"
|
||||||
|
).encode("utf-8")
|
||||||
|
|
||||||
|
self.send_response(200)
|
||||||
|
self.send_header("Content-Type", "text/plain; charset=utf-8")
|
||||||
|
self.send_header("Content-Length", str(len(body)))
|
||||||
|
self.end_headers()
|
||||||
|
self.wfile.write(body)
|
||||||
|
return
|
||||||
|
|
||||||
|
self.send_error(404)
|
||||||
|
|
||||||
|
def log_message(self, format, *args):
|
||||||
|
# Keep the student terminal focused on lab evidence.
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
server = ThreadingHTTPServer((HOST, PORT), MiniCorpHandler)
|
||||||
|
|
||||||
|
print(f"MiniCorp web service listening on {HOST}:{PORT}")
|
||||||
|
server.serve_forever()
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
Reference in new issue
Block a user