112 lines
2.9 KiB
Markdown
112 lines
2.9 KiB
Markdown
## Setup
|
||
### build docker image for linux:
|
||
```
|
||
cd ~/labs/sshworkshop
|
||
docker build -t workshop-debian:v1 .
|
||
```
|
||
|
||
### import arista cEOS image
|
||
`docker image import ~/cEOS64-lab-4.32.0.1F.tar.xz ceos-lab:4.32.0.1F`
|
||
|
||
### generate/ready the list of names:
|
||
`cp namepicker/names.yml ~/labs/sshworkshop/names-hashes.yml`
|
||
|
||
### bridges on clab host
|
||
`apt install bridge-utils`
|
||
|
||
```
|
||
auto br-ext
|
||
iface br-ext inet static
|
||
address 10.192.40.1/29
|
||
bridge-ports none
|
||
bridge-stp off
|
||
bridge-fd 0
|
||
|
||
auto br-clab-intonly
|
||
iface br-clab-intonly inet manual
|
||
bridge-ports none
|
||
bridge-stp off
|
||
bridge-fd 0
|
||
```
|
||
`ifup br-ext`
|
||
`ifup br-clab-intonly`
|
||
|
||
### DNAT & Co
|
||
edit & run `./setups/hypervisor.sh` (change UPLINK_INTERFACE accordingly)
|
||
```
|
||
#!/usr/bin/env bash
|
||
UPLINK_INTERFACE="enp0s31f6"
|
||
|
||
for port in {4010..4200}; do
|
||
ip_octet=$((port - 4000)) # 4011 → 11, … 4200 → 200
|
||
dst_ip="192.168.0.${ip_octet}"
|
||
|
||
iptables -t nat -A PREROUTING \
|
||
-i "$UPLINK_INTERFACE" -p tcp -m tcp --dport "$port" \
|
||
-j DNAT --to-destination "${dst_ip}:22"
|
||
done
|
||
iptables -t nat -A POSTROUTING -o br-ext -p tcp -d 192.168.0.0/24 --dport 22 -j MASQUERADE
|
||
```
|
||
|
||
## Deploy
|
||
containerlab (via vscode) & go.
|
||
it takes a good minute (with 50 workstations) for the setup to be ready (DHCP etc).
|
||
to create a csv of the online-users, run
|
||
`echo "IP,host,username,pwd"; cat online-users.txt | awk -F' +' 'BEGIN{OFS=","} {$1=$1; print}'`
|
||
on linux-gateway.
|
||
|
||
## prep workshop
|
||
once the lab is deployed and the online-users.txt is built, generate the cards to print out:
|
||
|
||
### generate CSV
|
||
`(echo "IP,host,username,pwd"; cat online-users.txt | awk -F' +' 'BEGIN{OFS=","} {$1=$1; print}') > credentials.csv`
|
||
|
||
### csv2cards script
|
||
```
|
||
#!/usr/bin/env bash
|
||
# csv2cards.sh → html
|
||
CSV=${1:-credentials.csv}
|
||
OUT=${2:-cards.html}
|
||
|
||
# start the document
|
||
cat >"$OUT" <<'EOF'
|
||
<!DOCTYPE html>
|
||
<html lang="en">
|
||
<head>
|
||
<meta charset="UTF-8">
|
||
<title>Credentials cards</title>
|
||
<style>
|
||
@page { size: A4 portrait; margin: 1cm; }
|
||
body { font-family: monospace; display: flex; flex-wrap: wrap; gap: 0.5cm; }
|
||
.card {
|
||
width: 9cm; /* fits 2‑3 cards across A4 */
|
||
border: 1px solid #333;
|
||
padding: 0.3cm;
|
||
box-sizing: border-box;
|
||
page-break-inside: avoid;
|
||
}
|
||
.field { margin: 0.1cm 0; }
|
||
.label { font-weight: bold; }
|
||
</style>
|
||
</head>
|
||
<body>
|
||
EOF
|
||
|
||
# read CSV, skip header, emit a <div class="card"> per line
|
||
awk -F',' 'NR>1{
|
||
printf "<div class=\"card\">\n"
|
||
printf " <div class=\"field\"><span class=\"label\">IP:</span> %s</div>\n", $1
|
||
printf " <div class=\"field\"><span class=\"label\">Host:</span> %s</div>\n", $2
|
||
printf " <div class=\"field\"><span class=\"label\">User:</span> %s</div>\n", $3
|
||
printf " <div class=\"field\"><span class=\"label\">Pass:</span> %s</div>\n", $4
|
||
printf "</div>\n"
|
||
}' "$CSV" >>"$OUT"
|
||
|
||
# close the document
|
||
cat >>"$OUT" <<'EOF'
|
||
</body>
|
||
</html>
|
||
EOF
|
||
```
|
||
download html, print from browser. Should be automatically A4.
|